Jump to content
Nytro

GetProcAddress replacement

Recommended Posts

Posted

_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

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...