鲲鹏 发表于 2024-12-2 22:31:02

WINAPI笔记:根据窗口类名查找镜像基址


流程如下。

1. 使用`FindWindow`查找窗口类名得到窗口句柄`hWnd`。
2. 使用`GetWindowThreadProcessId`获取窗口句柄对应的进程标识`dwProcessId`。
3. 使用`OpenProcess`打开进程标识得到进程句柄`hProcess`。
4. 使用`NtQueryInformationProcess`查询进程句柄对应的进程基本信息`PROCESS_BASIC_INFORMATION`,其中包含进程信息块`PebBaseAddress`。需要`PROCESS_QUERY_INFORMATION`权限。
5. 使用`ReadProcessMemory`读取进程信息块中的镜像基址。需要`PROCESS_VM_READ`权限。

#include <stdio.h>
#include <stdlib.h>

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

#pragma comment(lib, R"(C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x86\ntdll.lib)")

int main()
{
    HWND hWnd = FindWindowA("ClassName", NULL);
    if (!hWnd)
      abort();

    DWORD dwProcessId;
    if (!GetWindowThreadProcessId(hWnd, &dwProcessId))
      abort();

    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessId);
    if (!hProcess)
      abort();

    PROCESS_BASIC_INFORMATION pbi;
    if (!NT_SUCCESS(NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL)))
      abort();

    HMODULE hModuleFromPeb;
    if (!ReadProcessMemory(hProcess, &pbi.PebBaseAddress->Reserved3, &hModuleFromPeb, sizeof(hModuleFromPeb), NULL))
      abort();

    printf("hWnd = %p, hModuleFromPeb = %p\n", hWnd, hModuleFromPeb);

    return 0;
}

哥又回来了 发表于 2024-12-3 18:43:13

不错,回家研究下,搞成一份Delphi版的。{:handshake:}
楼主,我很喜欢。

哥又回来了 发表于 2024-12-3 18:46:25

大声朗读三遍,似乎和那个HOOK进程得到Delphi地址事件的如出一辙啊。
页: [1]
查看完整版本: WINAPI笔记:根据窗口类名查找镜像基址