转换“应用程序”的内存地址

时间:2014-11-06 14:53:21

标签: c++ winapi pointers memory reverse-engineering

所以我正在为微软的Spider Solitaire编写我的第一个培训师。首先,我需要向后设计所有内存地址,直到找到静态地址。我使用偏移量,所以我可以很容易地将它们还原。

我发现了这个:

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

2 个答案:

答案 0 :(得分:1)

我认为您可以使用GetModuleInformation查询加载地址,并为模块句柄参数传递NULL。如果这不起作用,您可以通过EnumProcessModulesGetModuleBaseName采用更长的路线。

答案 1 :(得分:1)

经过长时间的研究,我找到了自己的答案! 这段代码获取模块基地址(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),然后浏览模块并检查它们是否相同,然后返回基地址。

现在,我用Spider Solitaire进行了测试。它给了我一个错误。 那是因为我的编译代码是32位,而SpiderSolitaire.exe是64位,这是因为我的Windows 7是64位。

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

相关问题