2026-04-06 00:20:51 -05:00

146 lines
4.9 KiB
C++

#include "ProcLoader.h"
#include "ApiLoader.h"
#include "utils.h"
#include "ntdll.h"
ULONG Djb2A(PUCHAR str)
{
if (str == NULL)
return 0;
ULONG hash = 1572;
int c;
while (c = *str++) {
if (c >= 'A' && c <= 'Z')
c += 0x20;
hash = ((hash << 5) + hash) + c;
}
return hash;
}
ULONG Djb2W(PWCHAR str)
{
if (str == NULL)
return 0;
ULONG hash = 1572;
int c;
while (c = *str++) {
if (c >= L'A' && c <= L'Z')
c += 0x20;
hash = ((hash << 5) + hash) + c;
}
return hash;
}
HMODULE GetModuleAddress(ULONG modHash)
{
#ifdef _M_IX86
PEB* ProcEnvBlk = (PEB*)__readfsdword(0x30);
#else
PEB* ProcEnvBlk = (PEB*)__readgsqword(0x60);
#endif
PEB_LDR_DATA* Ldr = ProcEnvBlk->Ldr;
LIST_ENTRY* ModuleList = NULL;
ModuleList = &Ldr->InMemoryOrderModuleList;
LIST_ENTRY* pStartListEntry = ModuleList->Flink;
for (LIST_ENTRY* pListEntry = pStartListEntry; pListEntry != ModuleList; pListEntry = pListEntry->Flink) {
LDR_DATA_TABLE_ENTRY* pEntry = (LDR_DATA_TABLE_ENTRY*)((BYTE*)pListEntry - sizeof(LIST_ENTRY));
if ( Djb2W((PWCHAR)pEntry->BaseDllName.Buffer) == modHash )
return (HMODULE)pEntry->DllBase;
}
return NULL;
}
LPVOID GetSymbolAddress(HANDLE hModule, ULONG symbHash)
{
static int recursionDepth = 0;
if (recursionDepth > 6)
return NULL;
if (hModule == NULL)
return 0;
recursionDepth++;
uintptr_t dllAddress = (uintptr_t) hModule;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(dllAddress + ((PIMAGE_DOS_HEADER)dllAddress)->e_lfanew);
PIMAGE_DATA_DIRECTORY dataDirectory = (PIMAGE_DATA_DIRECTORY)&ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
PIMAGE_EXPORT_DIRECTORY exportDirectory = (PIMAGE_EXPORT_DIRECTORY)(dllAddress + dataDirectory->VirtualAddress);
uintptr_t exportedAddressTable = dllAddress + exportDirectory->AddressOfFunctions;
uintptr_t namePointerTable = dllAddress + exportDirectory->AddressOfNames;
uintptr_t ordinalTable = dllAddress + exportDirectory->AddressOfNameOrdinals;
uintptr_t symbolAddress = 0;
DWORD procAddress = 0;
DWORD dwCounter = exportDirectory->NumberOfNames;
while (dwCounter--) {
PUCHAR cpExportedFunctionName = (PUCHAR)(dllAddress + *(DWORD*)namePointerTable);
if ( Djb2A(cpExportedFunctionName) == symbHash ) {
exportedAddressTable += (*(WORD*)ordinalTable * sizeof(DWORD));
procAddress = *(DWORD*)exportedAddressTable;
symbolAddress = dllAddress + procAddress;
if ( dataDirectory->VirtualAddress < procAddress && procAddress < dataDirectory->VirtualAddress + dataDirectory->Size ) {
char* symbol = (char*)(symbolAddress);
char moduleName[64] = { 0 };
char funcName[64] = { 0 };
int index = StrIndexA(symbol, '.');
if (index >= 0) {
memcpy(moduleName, symbol, ++index);
moduleName[index ] = 'd';
moduleName[index + 1] = 'l';
moduleName[index + 2] = 'l';
moduleName[index + 3] = 0;
memcpy(funcName, symbol + index, StrLenA(symbol) - index + 1);
BOOL isApiSetDll = FALSE;
if (StrLenA(moduleName) > 11 && StrNCmpA(moduleName, (char*)"api-ms-win-", 11) == 0)
isApiSetDll = TRUE;
else if (StrLenA(moduleName) > 7 && StrNCmpA(moduleName, (char*)"ext-ms-", 7) == 0)
isApiSetDll = TRUE;
HMODULE hForwardModule = ApiWin->LoadLibraryA(moduleName);
if (hForwardModule) {
LPVOID result = NULL;
if (isApiSetDll) {
result = (LPVOID)ApiWin->GetProcAddress(hForwardModule, funcName);
}
else {
ULONG hashFunc = Djb2A((PUCHAR)funcName);
result = GetSymbolAddress(hForwardModule, hashFunc);
}
memset(moduleName, 0, StrLenA(moduleName));
memset(funcName, 0, StrLenA(funcName));
recursionDepth--;
return result;
}
memset(moduleName, 0, StrLenA(moduleName));
memset(funcName, 0, StrLenA(funcName));
}
break;
}
else {
recursionDepth--;
return (LPVOID) symbolAddress;
}
}
namePointerTable += sizeof(DWORD);
ordinalTable += sizeof(WORD);
}
recursionDepth--;
return NULL;
}