繁体   English   中英

c/c++ 如何获取 .exe 运行进程的基地址?

[英]c/c++ how can i get base address of .exe running process?

我正在寻找一种方法/函数,我可以用它来获取"program.exe"+03262C08 -> B4895A0基地址。 这个地址来自作弊引擎,并且已经用指针扫描器找到了基地址。 在指针扫描仪中,我可以按show module list并且program.exe的地址从地址00400000 program.exe 指针扫描器被扫描到地址09c3000 (我想在基地址+许多偏移后到达的地址[最终地址])。 此地址是某些对象的基础,但我无法到达该地址。 我只能在00400000处获得 exe 文件的基地址。 我正在尝试从指针03262C08 (和其他指针)添加偏移量,但我仍然无法到达该地址。 我不能使用函数FindWindow() 因为程序的名称会改变,坚持下去是多余的。 我正在使用OpenProcess(), EnumProcessModulesEx(), GetModuleFileNameEx()函数。 我也尝试过其他人,比如GetModuleInformation(),...得到了相同的结果。 GetModuleHandle()以结果0x126 [ERROR_MOD_NOT_FOUND]结束。 我正在使用 64 位操作系统,我正在尝试获取另一个进程的基地址。 我可以看到本地机器上的所有进程和“程序”进程的模块。

if (!K32EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) {
    return 1;
}

cProcesses = cbNeeded / sizeof(DWORD);

cout << setw(15) << left << "Process ID" << setw(10) << left << "Modules";
cout << setw(30) << left << "Process Name" << endl;
for (i = 0; i < cProcesses; i++) {
    if (aProcesses[i] != 0) {
        ProcessView::GetProccesses(aProcesses[i], modules, sizeModules, &cModules, &hCurrProcess);
        if (hCurrProcess != NULL) {
            cout << endl << setw(15) << left << aProcesses[i] << setw(10) << left << cModules;
            ProcessView::PrintModuleName(hCurrProcess, modules);
            CloseHandle(hCurrProcess);
        }

    }
}
ProcessView::GetProccesses(cProcesses, modules, sizeModules, &cModules, &hCurrProcess);

system("cls");
ProcessView::PrintModuleNameAll(hCurrProcess, modules, cModules);

我在我创建的 ProcessView.h 文件的示例中添加了函数的定义。

static void GetProccesses(_In_ DWORD processID, _Inout_ HMODULE ahModules[], _In_ int sizeModules, _Out_ DWORD* cModules, _Out_ HANDLE* hProcess);
static void PrintModuleName(_In_ HANDLE processID, _In_ HMODULE* modules);
static void PrintModuleNameAll(_In_ HANDLE hProcess, _In_ HMODULE * modules, _In_ DWORD cModules);

Windows 已经使用地址空间布局随机化大约十年了,但 EXE 中的模块基础远比这更古老。 简单地忽略它,它现在毫无意义。

并且不要忘记:每个进程都有自己的地址空间。 一个进程中的指针在另一个进程中毫无意义。

要在通过进程上的指针链找到的地址上使用ReadProcessMemoryWriteProcessMemory并在运行时动态获取模块基地址,您需要完成以下步骤:

  • 使用ToolHelp32Snapshot查找进程
  • 使用 ToolHelp32Snapsho 查找模块
  • 获取具有正确权限的进程句柄
  • 遍历指针链,取消引用并添加偏移量
  • 然后你可以调用 ReadProcessMemory 或 WriteProcessMemory
  • 您必须以管理员身份运行

对于这个例子,我将使用我制作的一个简单的攻击立方体作弊

#include <iostream>
#include <vector>
#include <Windows.h>
#include "proc.h"

int main()
{
    //Get ProcId of the target process
    DWORD procId = GetProcId(L"ac_client.exe");

    //Getmodulebaseaddress
    uintptr_t moduleBase = GetModuleBaseAddress(procId, L"ac_client.exe");

    //Get Handle to Process
    HANDLE hProcess = 0;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, NULL, procId);

    //Resolve base address of the pointer chain
    uintptr_t dynamicPtrBaseAddr = moduleBase + 0x10f4f4;

    std::cout << "DynamicPtrBaseAddr = " << "0x" << std::hex << dynamicPtrBaseAddr << std::endl;

    //Resolve our ammo pointer chain
    std::vector<unsigned int> ammoOffsets = { 0x374, 0x14, 0x0 };
    uintptr_t ammoAddr = FindDMAAddy(hProcess, dynamicPtrBaseAddr, ammoOffsets);

    std::cout << "ammoAddr = " << "0x" << std::hex << ammoAddr << std::endl;

    //Read Ammo value
    int ammoValue = 0;

    ReadProcessMemory(hProcess, (BYTE*)ammoAddr, &ammoValue, sizeof(ammoValue), nullptr);
    std::cout << "Curent ammo = " << std::dec << ammoValue << std::endl;

    //Write to it
    int newAmmo = 1337;
    WriteProcessMemory(hProcess, (BYTE*)ammoAddr, &newAmmo, sizeof(newAmmo), nullptr);

    //Read out again
    ReadProcessMemory(hProcess, (BYTE*)ammoAddr, &ammoValue, sizeof(ammoValue), nullptr);

    std::cout << "New ammo = " << std::dec << ammoValue << std::endl;

    getchar();
    return 0;
}

头文件proc.cpp:

DWORD GetProcId(const wchar_t* procName)
{
    DWORD procId = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        PROCESSENTRY32 procEntry;
        procEntry.dwSize = sizeof(procEntry);

        if (Process32First(hSnap, &procEntry))
        {
            do
            {
                if (!_wcsicmp(procEntry.szExeFile, procName))
                {
                    procId = procEntry.th32ProcessID;
                    break;
                }
            } while (Process32Next(hSnap, &procEntry));

        }
    }
    CloseHandle(hSnap);
    return procId;
}

uintptr_t GetModuleBaseAddress(DWORD procId, const wchar_t* modName)
{
    uintptr_t modBaseAddr = 0;
    HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, procId);
    if (hSnap != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 modEntry;
        modEntry.dwSize = sizeof(modEntry);
        if (Module32First(hSnap, &modEntry))
        {
            do
            {
                if (!_wcsicmp(modEntry.szModule, modName))
                {
                    modBaseAddr = (uintptr_t)modEntry.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnap, &modEntry));
        }
    }
    CloseHandle(hSnap);
    return modBaseAddr;
}

uintptr_t FindDMAAddy(HANDLE hProc, uintptr_t ptr, std::vector<unsigned int> offsets)
{
    uintptr_t addr = ptr;
    for (unsigned int i = 0; i < offsets.size(); ++i)
    {
        ReadProcessMemory(hProc, (BYTE*)addr, &addr, sizeof(addr), 0);
        addr += offsets[i];
    }
    return addr;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM