Skip to content

Instantly share code, notes, and snippets.

@mr-r3bot
Created May 25, 2024 09:35
Show Gist options
  • Save mr-r3bot/8c3f14302e8f8ba4ef8ccc6f40d2c459 to your computer and use it in GitHub Desktop.
Save mr-r3bot/8c3f14302e8f8ba4ef8ccc6f40d2c459 to your computer and use it in GitHub Desktop.
Customized GetProcAddress and GetModuleHandle and handle redirected function with API hashing
UINT32 HashStringJenkinsOneAtATime32BitA(_In_ PCHAR String)
{
SIZE_T Index = 0;
UINT32 Hash = 0;
SIZE_T Length = lstrlenA(String);
while (Index != Length)
{
Hash += String[Index++];
Hash += Hash << INITIAL_SEED;
Hash ^= Hash >> 6;
}
Hash += Hash << 3;
Hash ^= Hash >> 11;
Hash += Hash << 15;
return Hash;
}
UINT32 HashStringJenkinsOneAtATime32BitW(_In_ PWCHAR String)
{
SIZE_T Index = 0;
UINT32 Hash = 0;
SIZE_T Length = lstrlenW(String);
while (Index != Length)
{
Hash += String[Index++];
Hash += Hash << INITIAL_SEED;
Hash ^= Hash >> 6;
}
Hash += Hash << 3;
Hash ^= Hash >> 11;
Hash += Hash << 15;
return Hash;
}
FARPROC GetProcAddressH(HMODULE hModule, DWORD dwApiNameHash) {
if (hModule == NULL || dwApiNameHash == NULL)
return NULL;
PBYTE pBase = (PBYTE)hModule;
PIMAGE_DOS_HEADER pImgDosHdr = (PIMAGE_DOS_HEADER)pBase;
if (pImgDosHdr->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
PIMAGE_NT_HEADERS pImgNtHdr = (PIMAGE_NT_HEADERS)(pBase + pImgDosHdr->e_lfanew);
if (pImgNtHdr->Signature != IMAGE_NT_SIGNATURE)
return NULL;
IMAGE_OPTIONAL_HEADER ImgOptHdr = pImgNtHdr->OptionalHeader;
PIMAGE_EXPORT_DIRECTORY pImgExportDir = (PIMAGE_EXPORT_DIRECTORY)(pBase + ImgOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD FunctionNameArray = (PDWORD)(pBase + pImgExportDir->AddressOfNames);
PDWORD FunctionAddressArray = (PDWORD)(pBase + pImgExportDir->AddressOfFunctions);
PWORD FunctionOrdinalArray = (PWORD)(pBase + pImgExportDir->AddressOfNameOrdinals);
DWORD dwImgExportDirSize = ImgOptHdr.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
for (DWORD i = 0; i < pImgExportDir->NumberOfFunctions; i++) {
CHAR* pFunctionName = (CHAR*)(pBase + FunctionNameArray[i]);
PVOID pFunctionAddress = (PVOID)(pBase + FunctionAddressArray[FunctionOrdinalArray[i]]);
DWORD DotOffSet = 0;
CHAR ForwardedName[MAX_PATH * 2] = { 0 };
PCHAR FunctionMod = NULL;
PCHAR FunctionName = NULL;
//Hashing function
if (dwApiNameHash == HashStringJenkinsOneAtATime32BitA(pFunctionName)) {
// Check if it's a redirected function
if ((ULONG_PTR)pFunctionAddress >= (ULONG_PTR)(pImgExportDir) &&
(ULONG_PTR)pFunctionAddress < (ULONG_PTR)(pImgExportDir) + dwImgExportDirSize) {
memcpy(ForwardedName, pFunctionAddress, strlen((PCHAR)pFunctionAddress));
for (int i = 0; i < strlen((PCHAR)ForwardedName); i++) {
if ((PCHAR)ForwardedName[i] == '.') {
ForwardedName[i] = NULL;
DotOffSet = i;
break;
}
}
FunctionName = ForwardedName + DotOffSet + 1;
FunctionMod = ForwardedName;
// Calling GetProcCustom with Forwarded function
return GetProcAddressH(LoadLibraryA(FunctionMod), HashStringJenkinsOneAtATime32BitA(FunctionName));
}
return (FARPROC)pFunctionAddress;
}
}
return NULL;
}
HMODULE GetModuleHandleH(DWORD dwModuleNameHash) {
if (dwModuleNameHash == NULL)
return NULL;
#ifdef _WIN64
PPEB pPeb = (PEB*)(__readgsqword(0x60));
#elif _WIN32
PPEB pPeb = (PEB*)(__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 != NULL && pDte->FullDllName.Length < MAX_PATH) {
//Converting `FullDllName.Buffer to uppercase
CHAR UpperCaseDllName[MAX_PATH];
DWORD i = 0;
while (pDte->FullDllName.Buffer[i]) {
UpperCaseDllName[i] = (CHAR)toupper(pDte->FullDllName.Buffer[i]);
i++;
}
UpperCaseDllName[i] = '\0';
//Hash module name then compare
if (HashStringJenkinsOneAtATime32BitA(UpperCaseDllName) == dwModuleNameHash)
return (HMODULE)(pDte->InInitializationOrderLinks.Flink);
}
else {
break;
}
// Move to next element
pDte = *(PLDR_DATA_TABLE_ENTRY*)(pDte);
}
return NULL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment