c++ - 如何获取进程中使用的 .DLL 的(物理)基地址?

标签 c++ memory-address cheat-engine

我最近开始了一个新的 c++ win32 控制台项目。 它基本上重写了内存中给定地址的值。

重点是,我希望它使用带偏移量的指针映射来重新计算它应该使用的地址。 Here是 Cheat Engine 中指针映射的图像。

正如我所说,如果我只输入地址,我设法手动重写值(在本例中为 1147),但我希望它是自动的! 希望你能理解我的问题

祝你有美好的一天。

最佳答案

要获取内存中模块(DLL 或 EXE)的基地址,您可以使用 ToolHelp32Snapshot 枚举加载的模块。 Windows API 函数。 Microsoft 提供了文档化的源代码来查找模块。基本上您需要 2 个函数,一个用于获取 ProcessId,然后一个用于获取基址。

bool GetPid(const wchar_t* targetProcess, DWORD* procID)
{
    HANDLE snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (snap && snap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 pe;
        pe.dwSize = sizeof(pe);
        if (Process32First(snap, &pe))
        {
            do
            {
                if (!wcscmp(pe.szExeFile, targetProcess))
                {
                    CloseHandle(snap);
                    *procID = pe.th32ProcessID;
                    return true;
                }
            } while (Process32Next(snap, &pe));
        }
    }
    return false;
}

char* GetModuleBase(const wchar_t* ModuleName, DWORD procID)
{
    MODULEENTRY32 ModuleEntry = { 0 };
    HANDLE SnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procID);

    if (!SnapShot) return NULL;

    ModuleEntry.dwSize = sizeof(ModuleEntry);

    if (!Module32First(SnapShot, &ModuleEntry)) return NULL;

    do
    {
        if (!wcscmp(ModuleEntry.szModule, ModuleName))
        {
            CloseHandle(SnapShot);
            return (char*)ModuleEntry.modBaseAddr;
        }
    } while (Module32Next(SnapShot, &ModuleEntry));

    CloseHandle(SnapShot);
    return NULL;
}

然后你做:

DWORD ProcId;
GetPid(L"ac_client.exe", &ProcId);
char* ExeBaseAddress = GetModuleBase(L"ac_client.exe", ProcId);

如果您在内部黑客中注入(inject)了进程,您可以使用 GetModuleHandle因为在发布时返回的句柄只是模块的地址:

 DWORD BaseAddress = (DWORD)GetModuleHandle(L"ac_client.exe");

要计算多级指针指向的动态地址,您可以使用此函数,它基本上为您使用 ReadProcessMemory() 从外部取消引用指针:

uintptr_t FindDmaAddy(int PointerLevel, HANDLE hProcHandle, uintptr_t Offsets[], uintptr_t BaseAddress)
{
    uintptr_t pointer = BaseAddress;
    uintptr_t pTemp;

    uintptr_t pointerAddr;
    for(int i = 0; i < PointerLevel; i++)
    {
            if(i == 0)
            {
                ReadProcessMemory(hProcHandle, (LPCVOID)pointer, &pTemp, sizeof(pTemp), NULL);
            }
            pointerAddr = pTemp + Offsets[i];

            ReadProcessMemory(hProcHandle, (LPCVOID)pointerAddr, &pTemp, sizeof(pTemp), NULL);
    }
    return pointerAddr;
}

关于c++ - 如何获取进程中使用的 .DLL 的(物理)基地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41552466/

相关文章:

c# - 与 C++ 相比,C# 'ref' 关键字的使用

linux - 如何从 Linux 中的用户空间访问物理地址?

c - 指针变量的地址是如何分配的?他们遵循任何模式吗?

c - jmp 到内联 AVR C 中的地址

javascript - 这对 Cheat Engine 有用吗?

c++ - 操作 c 风格字符串时遇到 exc_bad_access 错误

c++ - crypto_box_easy 和 crypto_box_open_easy 的奇怪行为。不用私钥解密?

c++ - 在 C++ 中如何控制对对象的访问?

python - ReadWriteMemory 将内存读取为 int 而不是 float