#include #include // Replacement for GetProcAddress. FARPROC GetProcAddressReplacement(IN HMODULE hModule, IN LPCSTR lpApiName) { PBYTE pBase = (PBYTE)hModule; // Get DOS header and validate signature. PIMAGE_DOS_HEADER pImgDosHdr = (PIMAGE_DOS_HEADER)pBase; if (pImgDosHdr->e_magic != IMAGE_DOS_SIGNATURE) return NULL; // Get NT headers and validate signature. PIMAGE_NT_HEADERS pImgNtHdrs = (PIMAGE_NT_HEADERS)(pBase + pImgDosHdr->e_lfanew); if (pImgNtHdrs->Signature != IMAGE_NT_SIGNATURE) return NULL; // Get the optional header. IMAGE_OPTIONAL_HEADER ImgOptHdr = pImgNtHdrs->OptionalHeader; // Get the export directory. PIMAGE_EXPORT_DIRECTORY pImgExportDir = (PIMAGE_EXPORT_DIRECTORY)(pBase + ImgOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); // Get arrays for names, addresses, and ordinals. PDWORD FunctionNameArray = (PDWORD)(pBase + pImgExportDir->AddressOfNames); PDWORD FunctionAddressArray = (PDWORD)(pBase + pImgExportDir->AddressOfFunctions); PWORD FunctionOrdinalArray = (PWORD)(pBase + pImgExportDir->AddressOfNameOrdinals); // Loop through exported functions. for (DWORD i = 0; i < pImgExportDir->NumberOfFunctions; i++) { CHAR* pFunctionName = (CHAR*)(pBase + FunctionNameArray[i]); PVOID pFunctionAddress = (PVOID)(pBase + FunctionAddressArray[FunctionOrdinalArray[i]]); if (strcmp(lpApiName, pFunctionName) == 0) { return (FARPROC)pFunctionAddress; } } return NULL; } // Simple case-insensitive wide-string comparison. bool IsStringEqual(LPCWSTR a, LPCWSTR b) { return (wcscmp(a, b) == 0); } // Replacement for GetModuleHandle. HMODULE GetModuleHandleReplacement(IN LPCWSTR szModuleName) { #ifdef _WIN64 PPEB pPeb = (PPEB)(__readgsqword(0x60)); #elif _WIN32 PPEB pPeb = (PPEB)(__readfsdword(0x30)); #endif PPEB_LDR_DATA pLdr = (PPEB_LDR_DATA)(pPeb->Ldr); PLDR_DATA_TABLE_ENTRY pDte = (PLDR_DATA_TABLE_ENTRY)(pLdr->InMemoryOrderModuleList.Flink); while (pDte) { if (pDte->FullDllName.Length != 0) { if (IsStringEqual(pDte->FullDllName.Buffer, szModuleName)) { #ifdef STRUCTS return (HMODULE)(pDte->InInitializationOrderLinks.Flink); #else return (HMODULE)pDte->Reserved2[0]; #endif } } else { break; } pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte); } return NULL; }