initial commit
This commit is contained in:
Executable
+127
@@ -0,0 +1,127 @@
|
||||
#include <windows.h>
|
||||
#include <winternl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _S_LDR_DATA_TABLE_ENTRY {
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
LIST_ENTRY InInitializationOrderModuleList;
|
||||
LPVOID DllBase;
|
||||
LPVOID EntryPoint;
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
} S_LDR_DATA_TABLE_ENTRY;
|
||||
|
||||
typedef struct _S_PEB_LDR_DATA {
|
||||
DWORD Length;
|
||||
DWORD Initialized;
|
||||
LPVOID SsHandle;
|
||||
LIST_ENTRY InLoadOrderModuleList;
|
||||
LIST_ENTRY InMemoryOrderModuleList;
|
||||
} S_PEB_LDR_DATA;
|
||||
|
||||
typedef struct _S_PEB {
|
||||
BYTE Reserved1[2];
|
||||
BYTE BeingDebugged;
|
||||
BYTE Reserved2;
|
||||
#ifdef _WIN64
|
||||
BYTE Reserved3[4];
|
||||
#endif
|
||||
LPVOID Reserved4[1];
|
||||
LPVOID ImageBaseAddress;
|
||||
S_PEB_LDR_DATA *Ldr;
|
||||
} S_PEB;
|
||||
|
||||
static inline S_PEB *GetPeb(void) {
|
||||
#ifdef _WIN64
|
||||
return (S_PEB *)__readgsqword(0x60);
|
||||
#else
|
||||
return (S_PEB *)__readfsdword(0x30);
|
||||
#endif
|
||||
}
|
||||
|
||||
static DWORD StubHash(const char *str) {
|
||||
DWORD h = 0x4E67C6A7;
|
||||
while (*str) {
|
||||
h = ((h << 5) + h) ^ (unsigned char)*str++;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
static DWORD StubHashW(const WCHAR *str, USHORT lenBytes) {
|
||||
DWORD h = 0x4E67C6A7;
|
||||
const char *raw = (const char *)str;
|
||||
for (USHORT i = 0; i < lenBytes; i++) {
|
||||
char c = raw[i];
|
||||
if (c >= 'a' && c <= 'z') c -= 0x20;
|
||||
h = ((h << 5) + h) ^ (unsigned char)c;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
printf("=== PEB Module Walk ===\n");
|
||||
S_PEB_LDR_DATA *ldr = GetPeb()->Ldr;
|
||||
S_LDR_DATA_TABLE_ENTRY *first = (S_LDR_DATA_TABLE_ENTRY *)ldr->InMemoryOrderModuleList.Flink;
|
||||
S_LDR_DATA_TABLE_ENTRY *entry = first;
|
||||
do {
|
||||
if (entry->BaseDllName.Buffer) {
|
||||
DWORD h = StubHashW(entry->BaseDllName.Buffer, entry->BaseDllName.Length);
|
||||
printf(" Module: %.*S hash=0x%08X base=%p\n",
|
||||
entry->BaseDllName.Length / 2, entry->BaseDllName.Buffer,
|
||||
h, entry->DllBase);
|
||||
}
|
||||
entry = (S_LDR_DATA_TABLE_ENTRY *)entry->InMemoryOrderModuleList.Flink;
|
||||
} while (entry != first);
|
||||
|
||||
printf("\n=== Expected Hashes ===\n");
|
||||
printf(" FH_KERNEL32 = 0x52B1CB57\n");
|
||||
printf(" FH_NTDLL = 0x1EBCC013\n");
|
||||
|
||||
/* Try to resolve a function */
|
||||
LPVOID k32 = NULL;
|
||||
LPVOID ntdll = NULL;
|
||||
entry = first;
|
||||
do {
|
||||
if (entry->BaseDllName.Buffer) {
|
||||
DWORD h = StubHashW(entry->BaseDllName.Buffer, entry->BaseDllName.Length);
|
||||
if (h == 0x52B1CB57) k32 = entry->DllBase;
|
||||
if (h == 0x1EBCC013) ntdll = entry->DllBase;
|
||||
}
|
||||
entry = (S_LDR_DATA_TABLE_ENTRY *)entry->InMemoryOrderModuleList.Flink;
|
||||
} while (entry != first);
|
||||
|
||||
printf("\n=== Resolution ===\n");
|
||||
printf(" kernel32 base: %p %s\n", k32, k32 ? "FOUND" : "NOT FOUND!");
|
||||
printf(" ntdll base: %p %s\n", ntdll, ntdll ? "FOUND" : "NOT FOUND!");
|
||||
|
||||
if (k32) {
|
||||
/* Try resolving LoadLibraryA by hash */
|
||||
LPBYTE base = (LPBYTE)k32;
|
||||
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
|
||||
PIMAGE_NT_HEADERS nt = (PIMAGE_NT_HEADERS)(base + dos->e_lfanew);
|
||||
PIMAGE_EXPORT_DIRECTORY exp = (PIMAGE_EXPORT_DIRECTORY)(
|
||||
base + nt->OptionalHeader.DataDirectory[0].VirtualAddress);
|
||||
LPDWORD names = (LPDWORD)(base + exp->AddressOfNames);
|
||||
int found = 0;
|
||||
for (DWORD i = 0; i < exp->NumberOfNames && i < 5; i++) {
|
||||
const char *name = (const char *)(base + names[i]);
|
||||
DWORD h = StubHash(name);
|
||||
if (i < 3) printf(" Export[%d]: %-30s hash=0x%08X\n", i, name, h);
|
||||
}
|
||||
/* Find LoadLibraryA specifically */
|
||||
for (DWORD i = 0; i < exp->NumberOfNames; i++) {
|
||||
const char *name = (const char *)(base + names[i]);
|
||||
DWORD h = StubHash(name);
|
||||
if (h == 0x32B72ABF) {
|
||||
printf(" LoadLibraryA: FOUND (hash 0x32B72ABF matched \"%s\")\n", name);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) printf(" LoadLibraryA: NOT FOUND!\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user