转换"application's"内存地址

Converting "application's" memory address

本文关键字:内存 地址 application 转换      更新时间:2023-10-16

所以我正在为微软的蜘蛛纸牌编写我的第一个培训师。首先,我需要对所有的内存地址进行逆向工程,直到找到一个静态地址。我使用了偏移,这样我就可以很容易地将它们恢复。

我发现了这个:

1000157F78  <-- starting value(never changes)
+ E8        <-- offsets to pointers
+ 14
002DC3D4    <-- final adress(changes every time)

这就是我的教练如何获得他的最终记忆地址:

DWORD FindFinalAddr(HANDLE hProc, BYTE offsets[], DWORD baseAddress, unsigned char pointerLevel)
{
    DWORD pointer = baseAddress;
    DWORD pTemp = 0;
    DWORD pointerAddr = 0;
    // set base address
    ReadProcessMemory(hProc, (LPCVOID)pointer, &pTemp, (DWORD)sizeof(pTemp), NULL);
    for (int c = 0; c < pointerLevel; c++)
    {
        pointerAddr = pTemp + (DWORD)offsets[c];
        ReadProcessMemory(hProc, (LPCVOID)pointerAddr, &pTemp, (DWORD)sizeof(pTemp), NULL);
    }
    return pointerAddr;
}

在这种情况下,我(大致)这样做:FindFinalAddr(hProc, {0xE8, 0x14}, 0x1000157F78, 2);

当Spider Solitaire打开并且我刚刚找到静态值时,这很好。但当我关闭并重新打开它时,它就不再有效了。

我发现1000157F78实际上是SpiderSolitaire.exe+B5F78,它就像一个偏移。如果我在作弊引擎中输入这个,我会得到正确的内存地址,但我不能简单地在代码中输入。

现在我的问题是:如何将SpiderSolitaire.exe+B5F78转换为正确的内存地址?

注意:SpiderSolitaire.exe是64位的。

编辑:我试过以下几种:

void * entryPoint = (void*) hProc;
DWORD base_addr = ((DWORD)(entryPoint) + 0xB5F78);

但这不起作用,因为入口点是5C。它(在这个会话中)应该给出的地址是FF7A5F78,但实际发生的是5C + B5F78 = B5F4D

我认为您可以使用GetModuleInformation查询加载地址,为模块句柄参数传递NULL。如果这不起作用,您可以通过EnumProcessModules和GetModuleBaseName进行更长的路由。

经过长时间的研究,我找到了自己的答案!这段代码获取模块的基本地址(AKA入口点)(您需要包括TlHelp32.h和tchar.h):

DWORD getModuleBaseAddr(DWORD procId, TCHAR * lpszModuleName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
    DWORD moduleBaseAddr = 0;
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 mentry32 = { 0 };
        mentry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &mentry32))
        {
            do
            {
                if (_tcscmp(mentry32.szModule, lpszModuleName) == 0)
                {
                    moduleBaseAddr = (DWORD)mentry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &mentry32));
        }
    }
    else
    {
        std::cout << "Error on finding module base address: " << GetLastError() << "n";
    }
    return moduleBaseAddr;
}

你给它pid和模块的名称(比如game.exe),然后它浏览模块并检查它们是否相同,然后它返回基本地址。

现在,我用蜘蛛纸牌测试了这个。它给了我一个错误。那是因为我编译的代码是32位的,SpiderSolitaire.exe是64位的,这是因为我的Windows7是64位。

因此,请确保您的代码与您的目标代码具有相同的平台目标!