为 64 位进程查找 AddressOfEntryPoint

逆向工程 C++ 登录
2021-06-15 07:15:27

好的,所以在下面的代码片段中,我将启动一个notepad.exe处于挂起状态进程并尝试获取该进程的 AddressOfEntryPoint。问题是我似乎无法找到实际的codeEntry.

应用程序和notepad.exe进程都是 64 位的。

我究竟做错了什么?

这是注释的代码片段:

#include <iostream>
#include <windows.h>
#include <winternl.h>

#pragma comment(lib, "ntdll")

using namespace std;

int main() {    
    STARTUPINFOA si;
    si = {};
    PROCESS_INFORMATION pi = {};
    PROCESS_BASIC_INFORMATION pbi = {};
    DWORD returnLength = 0;
    CreateProcessA(0, (LPSTR)"c:\\windows\\system32\\notepad.exe", 0, 0, 0, CREATE_SUSPENDED, 0, 0, &si, &pi);

    // get target image PEB address and pointer to image base
    NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), &returnLength);
    DWORD_PTR pebOffset = (DWORD_PTR)pbi.PebBaseAddress + 10;

    // get target process image base address
    LPVOID imageBase = 0;
    ReadProcessMemory(pi.hProcess, (LPCVOID)pebOffset, &imageBase, 16, NULL);

    // read target process image headers
    BYTE headersBuffer[4096] = {};
    ReadProcessMemory(pi.hProcess, (LPCVOID)imageBase, headersBuffer, 4096, NULL);

    // get AddressOfEntryPoint
    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)headersBuffer;
    PIMAGE_NT_HEADERS64 ntHeader = (PIMAGE_NT_HEADERS64)((DWORD_PTR)headersBuffer + dosHeader->e_lfanew);
    LPVOID codeEntry = (LPVOID)(ntHeader->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)imageBase);

    // Do something with the AddressOfEntryPoint(print to console in this case)
    cout << codeEntry << endl;

    return 0;
}
1个回答

一般来说,你几乎都做对了,但是有两个简单的错误。

首先也是最重要的就是这里

DWORD_PTR pebOffset = (DWORD_PTR)pbi.PebBaseAddress + 10;

偏移量ImageBaseAddress不是10,它是0x10(16 在 DEC)。所以你需要这样做

DWORD_PTR pebOffset = (DWORD_PTR)pbi.PebBaseAddress + 0x10;

其次,你确定 sizeofLPVOID是 16 吗?至少在我的编译器上它是 8,而不是 16,所以你最喜欢覆盖堆栈上的数据。这就是为什么我提出这种方法

ReadProcessMemory(pi.hProcess, (LPCVOID)pebOffset, &imageBase, sizeof(LPVOID), NULL);

代替

ReadProcessMemory(pi.hProcess, (LPCVOID)pebOffset, &imageBase, 16, NULL);