C++ 获取 64 位应用程序的模块基地址 [英] C++ Get Module Base Address for 64bit Application

查看:37
本文介绍了C++ 获取 64 位应用程序的模块基地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近一直在玩内存读取/编辑,遇到了一个我认为是 64 位应用程序引起的问题,我也尝试在 64 位下编译.我对这个脚本与 32 位应用程序一起使用没有问题,但是当我在 Solitaire 上尝试这个时,它无法获得基地址,然后无法计算正确的偏移量等.这是脚本:

I have been playing around with memory reading/editing recently and have run into a problem which I think is due to the 64bit application, I have also tried to compile under 64bit. I had no problem with this script using with 32bit apps, however when I try this on Solitaire it fails to get the base address, which then fails to workout the correct offsets ect. Here is the script:

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
using namespace std;

DWORD dwGetModuleBaseAddress(DWORD dwProcessID, TCHAR *lpszModuleName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID);
    DWORD dwModuleBaseAddress = 0;
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 ModuleEntry32 = { 0 };
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &ModuleEntry32))
        {
            do
            {
                if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
                {
                    dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }
    return dwModuleBaseAddress;
}

int main()
{
    DWORD address = 0xBAFA8;
    HWND hwnd = FindWindow(0, L"Solitaire");
    DWORD pid;
    int data = 0;
    int newData = 0;
    if (hwnd)
    {
        GetWindowThreadProcessId(hwnd, &pid);
        HANDLE phandle = OpenProcess(PROCESS_ALL_ACCESS, 0, pid);
        if (phandle)
        {
            DWORD base = dwGetModuleBaseAddress(pid, L"Solitaire.exe");
            cout << "Base: " << (void*)base << endl;

            ReadProcessMemory(phandle, (LPCVOID)(base + address), &data, sizeof(data), 0);
        }
        else {
            cout << "Couldnt get handle" << endl;
        }

    }
    else {
        cout << "Couldn't find window" << endl;
    }
    cin.get();
    return 0;
}

问题可能是我使用的函数使用了 MODULE32,但是我尝试了其他函数(使用 EnumModules)仍然无法返回地址.

The problem may be that the function I use uses MODULE32, however I have tried other functions (that uses EnumModules) which still fails to return address.

任何想法如何获取 64 位应用程序的基地址或让此脚本工作?

Any ideas how to get base address of 64bit application or to get this script working?

谢谢

推荐答案

好吧,您的代码永远不会成功运行,因为您谈论的是 64 位,但您使用的是 DWORD 作为基地址!Solitare 可能有一个 32 位地址,但你不能保证,你永远不应该假设它.

Well your code is never going to work successfully because you are talking about 64 bits but you are using DWORD for base address! Solitare might have a 32 bit address but you cannot guarantee that and you should never assume it.

此功能有效.它只需要相关进程的进程 ID,并且假定您需要该进程的基地址.即不是它的 DLL 之一.如果您不想要拥有进程,那么您需要使用类似 for (int i=0; i<moduleCount; i++ ) {//使用 moduleArray[ 做一些事情i] } 然后检查模块文件名.

This function works. It requires only the process ID of the process in question, and it assume you want the base address of that process. i.e. not one of its DLLs. If you don't want the owning process then you need to iterate through moduleArray using something like for (int i=0; i<moduleCount; i++ ) { // do something with moduleArray[i] } and then check the module file name.

如果您只想要启动进程(可执行文件),您可以假设它是数组中的第一个元素.

If you only want the starting process (the executable) you can just make an assumption that it's the first element in the array.

DWORD_PTR GetProcessBaseAddress( DWORD processID )
{
    DWORD_PTR   baseAddress = 0;
    HANDLE      processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    HMODULE     *moduleArray;
    LPBYTE      moduleArrayBytes;
    DWORD       bytesRequired;

    if ( processHandle )
    {
        if ( EnumProcessModules( processHandle, NULL, 0, &bytesRequired ) )
        {
            if ( bytesRequired )
            {
                moduleArrayBytes = (LPBYTE)LocalAlloc( LPTR, bytesRequired );

                if ( moduleArrayBytes )
                {
                    unsigned int moduleCount;

                    moduleCount = bytesRequired / sizeof( HMODULE );
                    moduleArray = (HMODULE *)moduleArrayBytes;

                    if ( EnumProcessModules( processHandle, moduleArray, bytesRequired, &bytesRequired ) )
                    {
                        baseAddress = (DWORD_PTR)moduleArray[0];
                    }

                    LocalFree( moduleArrayBytes );
                }
            }
        }

        CloseHandle( processHandle );
    }

    return baseAddress;
}

这篇关于C++ 获取 64 位应用程序的模块基地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆