-
-
Save RistBS/e91e63790dbe2ae54d77b74fee098be5 to your computer and use it in GitHub Desktop.
WOW64 Callbacks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// How to locate the WOW64 Callback Table in ntdll.dll | |
// | |
// @modexpblog | |
// | |
#define PHNT_VERSION PHNT_VISTA | |
#include <phnt_windows.h> | |
#include <phnt.h> | |
#include <cstdio> | |
#include <cstdint> | |
#include <cstdlib> | |
#include <cstring> | |
typedef union _W64_T { | |
LPVOID p; | |
BYTE b[8]; | |
DWORD w[2]; | |
DWORD64 q; | |
LPVOID *pp; | |
} W64_T; | |
typedef struct _WOW64_CALLBACK { | |
STRING Name; | |
W64_T Function; | |
} WOW64_CALLBACK, *PWOW64_CALLBACK; | |
// | |
// Structure based on 64-bit version of NTDLL | |
// | |
typedef struct _WOW64_CALLBACK_TABLE { | |
WOW64_CALLBACK Wow64LdrpInitialize; | |
WOW64_CALLBACK Wow64PrepareForException; | |
WOW64_CALLBACK Wow64ApcRoutine; | |
WOW64_CALLBACK Wow64PrepareForDebuggerAttach; | |
WOW64_CALLBACK Wow64SuspendLocalThread; | |
WOW64_CALLBACK Wow64SuspendLocalProcess; | |
} WOW64_CALLBACK_TABLE, *PWOW64_CALLBACK_TABLE; | |
BOOL | |
IsReadOnlyPtr(LPVOID ptr) { | |
MEMORY_BASIC_INFORMATION mbi; | |
if (!ptr) return FALSE; | |
// query the pointer | |
DWORD res = VirtualQuery(ptr, &mbi, sizeof(mbi)); | |
if (res != sizeof(mbi)) return FALSE; | |
return ((mbi.State == MEM_COMMIT ) && | |
(mbi.Type == MEM_IMAGE ) && | |
(mbi.Protect == PAGE_READONLY)); | |
} | |
// | |
// | |
// | |
BOOL | |
GetWow64FunctionPointer(PWOW64_CALLBACK Callback) { | |
auto m = (PBYTE)GetModuleHandleW(L"ntdll"); | |
auto nt = (PIMAGE_NT_HEADERS)(m + ((PIMAGE_DOS_HEADER)m)->e_lfanew); | |
auto sh = IMAGE_FIRST_SECTION(nt); | |
for (DWORD i=0; i<nt->FileHeader.NumberOfSections; i++) { | |
if (*(PDWORD)sh[i].Name == *(PDWORD)".rdata") { | |
auto rva = sh[i].VirtualAddress; | |
auto cnt = (sh[i].Misc.VirtualSize - sizeof(STRING)) / sizeof(ULONG_PTR); | |
auto ptr = (PULONG_PTR)(m + rva); | |
for (DWORD j=0; j<cnt; j++) { | |
if (!IsReadOnlyPtr((LPVOID)ptr[j])) continue; | |
auto api = (PSTRING)ptr[j]; | |
if (api->Length == Callback->Name.Length && api->MaximumLength == Callback->Name.MaximumLength) { | |
if (!strncmp(api->Buffer, Callback->Name.Buffer, Callback->Name.Length)) { | |
Callback->Function.p = (PVOID)ptr[j + 1]; | |
return TRUE; | |
} | |
} | |
} | |
break; | |
} | |
} | |
return FALSE; | |
} | |
void | |
GetWow64CallbackTable(PWOW64_CALLBACK_TABLE Table) { | |
GetWow64FunctionPointer(&Table->Wow64LdrpInitialize); | |
GetWow64FunctionPointer(&Table->Wow64PrepareForException); | |
GetWow64FunctionPointer(&Table->Wow64ApcRoutine); | |
GetWow64FunctionPointer(&Table->Wow64PrepareForDebuggerAttach); | |
GetWow64FunctionPointer(&Table->Wow64SuspendLocalThread); | |
GetWow64FunctionPointer(&Table->Wow64SuspendLocalProcess); | |
GetWow64FunctionPointer(&Table->Wow64LdrpInitialize); | |
} | |
WOW64_CALLBACK_TABLE Wow64Table = { | |
{RTL_CONSTANT_STRING("Wow64LdrpInitialize"), NULL}, | |
{RTL_CONSTANT_STRING("Wow64PrepareForException"), NULL}, | |
{RTL_CONSTANT_STRING("Wow64ApcRoutine"), NULL}, | |
{RTL_CONSTANT_STRING("Wow64PrepareForDebuggerAttach"), NULL}, | |
{RTL_CONSTANT_STRING("Wow64SuspendLocalThread"), NULL}, | |
{RTL_CONSTANT_STRING("Wow64SuspendLocalProcess"), NULL} | |
}; | |
int | |
main(void) { | |
GetWow64CallbackTable(&Wow64Table); | |
printf("Wow64LdrpInitialize : %p\n", Wow64Table.Wow64LdrpInitialize.Function.p); | |
printf("Wow64PrepareForException : %p\n", Wow64Table.Wow64PrepareForException.Function.p); | |
printf("Wow64ApcRoutine : %p\n", Wow64Table.Wow64ApcRoutine.Function.p); | |
printf("Wow64PrepareForDebuggerAttach : %p\n", Wow64Table.Wow64PrepareForDebuggerAttach.Function.p); | |
printf("Wow64SuspendLocalThread : %p\n", Wow64Table.Wow64SuspendLocalThread.Function.p); | |
printf("Wow64SuspendLocalProcess : %p\n", Wow64Table.Wow64SuspendLocalProcess.Function.p); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment