Reputation: 103
I want to hook an api as soon as a program loads. For that I use createprocess with the appropriate flag set so that the process is created suspended. I place the hook and then I resume it. But when I try to hook an api that's not from ntdll.DLL i get an ERROR_INVALID_ADDRESS (487). If I wait until the program has started to place the hook, I can do it without trouble.
This leads me yo believe that the process doesn't load every DLL when it starts (even though they are linked statically), and there is some initialization to be done before the memory area on the iat that corresponds to the api I want to hook, is valid and ready to be accessed.
Am I right here? And if so, what can I do in order to know when to place the hook?
Thanks!
PD: I'm working on a proof of concept for my future thesis. It's purely for educational purposes.
PD2: I hooked the entry point and it worked great but now I have another conundrum: I need a standardized way of knowing the entry point of a loaded process.
Upvotes: 2
Views: 1247
Reputation: 103
Got it!!
int main()
{
STARTUPINFO sInfo;
PROCESS_INFORMATION pInfo;
ZeroMemory(&sInfo, sizeof(STARTUPINFO));
ZeroMemory(&pInfo, sizeof(PROCESS_INFORMATION));
CreateProcess("c:\\windows\\notepad.exe", nullptr, nullptr, nullptr, false, CREATE_SUSPENDED, nullptr, nullptr, &sInfo, &pInfo);
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pInfo.dwProcessId);
PROCESS_BASIC_INFORMATION pbaseInfo;
ZeroMemory(&pbaseInfo, sizeof(PROCESS_BASIC_INFORMATION));
DWORD dwRet = 0;
ZwQueryInformationProcess = (DWORD (__stdcall *)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(GetModuleHandleA("ntdll"),"ZwQueryInformationProcess");
ZwQueryInformationProcess(hProcess, 0, &pbaseInfo, sizeof(PROCESS_BASIC_INFORMATION), &dwRet);
SIZE_T imageBase = 0;
SIZE_T dwret1;
ReadProcessMemory(hProcess, (BYTE*) pbaseInfo.PebBaseAddress + 8, &imageBase, 4, &dwret1);
BYTE *buffer = new BYTE[sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS32)];
ZeroMemory(buffer, sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS32));
DWORD dwRead = 0;
ReadProcessMemory(hProcess, (void*) imageBase, buffer, sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS32), &dwRead);
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER) buffer;
PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS32) (buffer + dosHeader->e_lfanew);
cout << (hex) << ntHeader->OptionalHeader.AddressOfEntryPoint + imageBase << endl;
TerminateProcess(hProcess, 0);
return 0;
}
There might be some tweaks to do, but that's the basic jist of it.
Upvotes: 2