2014-09-05 87 views
2

我想在程序加载后立即挂钩api。为此,我使用具有适当标志设置的createprocess,以便该流程被创建为暂停状态。我挂钩,然后我恢复它。但是当我试图钩住一个不是来自ntdll.DLL的API时,我得到了一个ERROR_INVALID_ADDRESS(487)。如果我等到程序开始放置钩子,我可以毫无困难地做到这一点。等待程序加载DLL,然后挂起它

这导致我相信这个过程不会在启动时加载每个DLL(即使它们是静态链接的),并且在iat上对应于api的内存区域之前要做一些初始化我想挂钩,有效并准备好被访问。

我在这儿吗?如果是这样,我该怎么做才能知道何时挂钩?

谢谢!

PD:我正在为未来的论文做一个概念验证。纯粹是为了教育目的。 PD2:我迷上了入口点,它运行得很好,但现在我又遇到了另一个难题:我需要一种标准化的方式来了解加载过程的入口点。

+0

你必须编写一个调试器才能使用DLL加载通知。这是[比听起来容易](http://msdn.microsoft.com/en-us/library/windows/desktop/ms679288%28v=vs.85%29.aspx)。 – 2014-09-05 23:52:38

+0

我宁可不使用调试。我不希望进程知道它正在被调试。有另一种方法吗? – Alex 2014-09-06 00:11:50

+0

这非常荒谬。 – 2014-09-06 00:19:45

回答

2

明白了!

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; 
} 

可能会做一些调整,但这是它的基本问题。