BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { DisableThreadLibraryCalls(hModule); InitializeCriticalSection(&cs_GetQueue); InitInstance(hModule); if(SUCCEEDED(PatchIat(GetModuleHandle(NULL),"kernel32.dll","GetProcAddress",(PVOID)GetProcAddress_Hooked,(PVOID *)&GetProcAddress_Original))) { DBB("GetPRocAddress hook injected"); } else { DBB("GetPRocAddress hook failed"); } if(SUCCEEDED(PatchIat(GetModuleHandle(NULL),"user32.dll","RegisterClassA",(PVOID)RegisterClass_Hooked,(PVOID *)&RegisterClass_Original))) { DBB("RegisterClass hook injected"); } else { DBB("RegisterClass hook failed"); } case DLL_PROCESS_DETACH: ExitInstance(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } } return TRUE; }
int main(int argc, char** argv) { BOOL is_wow64 = FALSE; if (IsWow64Process(GetCurrentProcess(), &is_wow64) && is_wow64) { printf("Error: This must be run on 32 bit Windows\n"); return 1; } // Hook the call to CsrClientCallServer from kernel32 to apply the anonymous token. PVOID hook; HRESULT hr = PatchIat(GetModuleHandle(L"kernel32.dll"), "ntdll.dll", "CsrClientCallServer", CsrClientCallServerHook, &hook); if (FAILED(hr)) { printf("Error patching IAT: %08X\n", hr); return 1; } g_pCsgClientCallServer = (fCsrClientCallServer)hook; printf("Patched client %p %p\n", hook, GetProcAddress(GetModuleHandle(L"ntdll.dll"), "CsrClientCallServer")); HANDLE hThread = CreateThread(nullptr, 0, CaptureAndSuspendProcess, nullptr, 0, nullptr); // Wait a little just to ensure capture loop is running. Sleep(1000); STARTUPINFO startInfo = {}; startInfo.cb = sizeof(startInfo); PROCESS_INFORMATION procInfo = {}; WCHAR cmdline[] = L"edit.com"; // Create a 16bit executable, this will call into CSRSS which we've hooked. CreateProcess(nullptr, cmdline, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &startInfo, &procInfo); return 0; }
void *InterceptDllCall(HMODULE hModule, char *szDllName, char *szFunctionName, DWORD pNewFunction) { /* For some setups this old code won't probably because GetProcAddress returns a different address from the one that the IAT uses. PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pNTHeader; PIMAGE_IMPORT_DESCRIPTOR pImportDesc; PIMAGE_THUNK_DATA pThunk; MdtMemBlockInfos mbis; void *pOldFunction; #ifdef MDT_DEBUG MessageBox(0, szFunctionName, "InterceptDllCall", MB_OK|MB_ICONINFORMATION); #endif if (!(pOldFunction = GetProcAddress(GetModuleHandle(szDllName), szFunctionName))) { #ifdef MDT_DEBUG MessageBox(0, "GetProcAddress failed.", "InterceptDllCall", MB_OK|MB_ICONERROR); #endif return NULL; } pDosHeader = (PIMAGE_DOS_HEADER) hModule; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) { #ifdef MDT_DEBUG MessageBox(0, "No IMAGE_DOS_SIGNATURE", "InterceptDllCall", MB_OK|MB_ICONERROR); #endif return NULL; } pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew); if (pNTHeader->Signature != IMAGE_NT_SIGNATURE || (pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader, pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)) == (PIMAGE_IMPORT_DESCRIPTOR) pNTHeader) { #ifdef MDT_DEBUG MessageBox(0, "No IMAGE_NT_SINGATURE or ImportDesc is NtHeader", "InterceptDllCall", MB_OK|MB_ICONERROR); #endif return NULL; } while (pImportDesc->Name) { char *szModuleName = MakePtr(char *, pDosHeader, pImportDesc->Name); if (!_stricmp(szModuleName, szDllName)) break; pImportDesc++; } if (pImportDesc->Name == NULL) { #ifdef MDT_DEBUG MessageBox(0, "DLLName does not match.", "InterceptDllCall", MB_OK|MB_ICONERROR); #endif return NULL; } pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk); while (pThunk->u1.Function) { if (pThunk->u1.Function == (DWORD)pOldFunction) { MdtMemAccessBegin((void *) &pThunk->u1.Function, sizeof(DWORD), &mbis); pThunk->u1.Function = (DWORD) pNewFunction; MdtMemAccessEnd(&mbis); return pOldFunction; } pThunk++; } #ifdef MDT_DEBUG MessageBox(0, "Function not found.", "InterceptDllCall", MB_OK|MB_ICONERROR); #endif */ void *pOldFunction; if(S_OK == PatchIat( hModule, szDllName, szFunctionName, (PVOID)pNewFunction, (PVOID *)&pOldFunction )) return pOldFunction; return NULL; }