Nytro Posted June 11, 2011 Report Posted June 11, 2011 _GetProcAddress replacementAuthor: 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 Quote