Jump to content
Nytro

GetProcAddress replacement

Recommended Posts

_GetProcAddress replacement

Author: vernad (cred)

This _GetProcAddress function supports api lookup in EAT by either name or hash. It also can look up exports in either loaded or non-loaded modules.

There are two known issues:

when looking up exports in unmapped module - it assumes that exports are in very first section. It could be fixed, but at the moment i have no need for that kind of functionality so i leave it to you for now.

when exported func rva actually points string (example: in kernel32.dll x86 (on windows7 x64) EnterCriticalSection points to string 'NTDLL.RtlEnterCriticalSection') is not handled either. Once again had no need for supporting that.

Also i do not include Hash::String() function, it returns 32bit integer. I leave implementing this to your imagination. It is not tested on x64, but probably would work. Now the good part:

#define GET_PHYSICAL(RVA) ((size_t)hModule + RVA - pSectionHdrs[i].VirtualAddress + pSectionHdrs[i].PointerToRawData)
#define GET_VIRTUAL(RVA) ((size_t)hModule + RVA)

enum GET_PROC_TYPE
{
BY_HASH,
BY_NAME
};

void* _GetProcAddress( HANDLE hModule, size_t val, GET_PROC_TYPE type /*= BY_HASH*/, bool mapped /*= true*/ )
{
if(!hModule)
return 0;

PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hModule;
PIMAGE_NT_HEADERS pNT = (PIMAGE_NT_HEADERS)((size_t)hModule + pDos->e_lfanew);
char* bModule = (char*)hModule;

PIMAGE_DATA_DIRECTORY pDataExpDir = &pNT->OptionalHeader.DataDirectory[0];
PIMAGE_SECTION_HEADER pSectionHdrs = (PIMAGE_SECTION_HEADER)&pNT[1];

for (int i = 0; i < pNT->FileHeader.NumberOfSections; i++)
{
if(pDataExpDir->VirtualAddress >= pSectionHdrs[i].VirtualAddress && pDataExpDir->VirtualAddress < pSectionHdrs[i].VirtualAddress + pSectionHdrs[i].Misc.VirtualSize)
{
PIMAGE_EXPORT_DIRECTORY pExpDir = mapped ? (PIMAGE_EXPORT_DIRECTORY)GET_VIRTUAL(pDataExpDir->VirtualAddress) : (PIMAGE_EXPORT_DIRECTORY)GET_PHYSICAL(pDataExpDir->VirtualAddress);

DWORD* procs = mapped ? (PDWORD)GET_VIRTUAL(pExpDir->AddressOfFunctions) : (PDWORD)GET_PHYSICAL(pExpDir->AddressOfFunctions);
DWORD* names = mapped ? (PDWORD)GET_VIRTUAL(pExpDir->AddressOfNames) : (PDWORD)GET_PHYSICAL(pExpDir->AddressOfNames);
WORD* ordinals = mapped ? (PWORD)GET_VIRTUAL(pExpDir->AddressOfNameOrdinals) : (PWORD)GET_PHYSICAL(pExpDir->AddressOfNameOrdinals);

for(DWORD j = 0; j < pExpDir->NumberOfNames; j++)
{
c8* pName = mapped ? (c8*)GET_VIRTUAL(names[j]) : (c8*)GET_PHYSICAL(names[j]);

if( (type == BY_HASH && val == Hash::String(pName)) ||
(type == BY_NAME && !__strcmp(pName, (c8*)val)))
{
if(mapped)
return (void*)GET_VIRTUAL(procs[ordinals[j]]);
else
{
i = 0; // set i to code section in order for macros to work. not good, if export is not in the 1st section!!!
size_t oft = procs[ordinals[j]] + pSectionHdrs[i].PointerToRawData - pSectionHdrs[i].VirtualAddress;
return (void*)((size_t)hModule + oft);
}
}
}
}
}

return 0;
}

Sursa: _GetProcAddress

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...