如何在C++中获取进程的起始/基地址?

8
我正在通过在Microsoft Spider Solitaire上使用整个base/static指针来测试它。因此,我获得了玩家已使用的“移动”数量的基础指针,作弊引擎告诉我它是“SpiderSolitaire.exe+B5F78”。现在我卡在了如何找出SpiderSolitaire.exe的起始地址(当然,每次程序启动时都会改变)。我该如何找到SpiderSolitaire.exe的起始地址,以便添加偏移量并获取“移动”值的真实地址(当然是在c++中)?

你可以从外部注入DLL吗? - Blood
从外部来看,我正在使用WriteMemoryProcess来写入进程内存。 - ZimZim
好的,那么我的答案应该适用于你。 - Blood
3个回答

8
这是另一种方法,使用Visual Studio 2015编写,但应向后兼容。
void GetBaseAddressByName(DWORD processId, const _TCHAR *processName)
{
    _TCHAR szProcessName[MAX_PATH] = _TEXT("<unknown>");

    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
        PROCESS_VM_READ,
        FALSE, processId);

    if (NULL != hProcess)
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if (EnumProcessModulesEx(hProcess, &hMod, sizeof(hMod),
            &cbNeeded, LIST_MODULES_32BIT | LIST_MODULES_64BIT))
        {
            GetModuleBaseName(hProcess, hMod, szProcessName,
                sizeof(szProcessName) / sizeof(_TCHAR));
            if (!_tcsicmp(processName, szProcessName)) {
                _tprintf(_TEXT("0x%p\n"), hMod);
            }
        }
    }

    CloseHandle(hProcess);
}

int notmain(void)
{
    DWORD aProcesses[1024];
    DWORD cbNeeded;
    DWORD cProcesses;

    // Get the list of process identifiers.
    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
        return 1;

    // Calculate how many process identifiers were returned.
    cProcesses = cbNeeded / sizeof(DWORD);

    // Check the names of all the processess (Case insensitive)
    for (int i = 0; i < cProcesses; i++) {
        GetBaseAddressByName(aProcesses[i], _TEXT("SpiderSolitaire.exe"));
    }

    return 0;
}

1
如果(NULL!= hProcess),比较顺序让我的一天变得美好。 - knoxgon
2
GetBaseAddressByName(aProcesses[i], TEXT("SpiderSolitaire.exe")); - argument of type "const char *" is incompatible with parameter of type "TCHAR *" - Ari Seyhun
@AriSeyhun: 将GetBaseAddressByName更改为void GetBaseAddressByName(DWORD processId, const TCHAR *processName)(在processName参数中添加const以表示您不打算修改其内容)应该可以解决这个问题。 - ShadowRanger
@ShadowRanger 我不确定那样会解决问题,我认为故障更多地与微软关于使用 _T 或 _TEXT 而不是 TEXT 的规定有关,如果我没记错的话。虽然 const 当然是一个好主意,但我恐怕并没有编写原始代码,我永远不会编写 NULL != hProcess。我将编辑更改为 _(everything)。 - Orwellophile

2

以下是用于查找给定进程的基地址的代码。

请注意,此代码使用多字节字符集;在 VS2012 中,可以通过属性 > 配置属性 > 项目默认值 > 字符集 > 使用多字节字符集来设置。

#define _CRT_SECURE_NO_WARNINGS
#define UNINITIALIZED 0xFFFFFFFF

#include <iostream>
#include <iomanip>
#include <Windows.h>
#include <TlHelp32.h> //PROCESSENTRY

/* The name of the process */
const char* processName_ = "REPLACETHIS.exe" ; 

void main(void)
{
DWORD  processID_     = NULL ;
DWORD  processBaseAddress_   = UNINITIALIZED;

/* Get the process ID  */
{
    PROCESSENTRY32 processEntry_ ; // Entry into process you wish to inject to
    HANDLE hProcSnapshot_ = NULL ; 
    /* Takes a snapshot of the system's processes */
    hProcSnapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) ; //?

    /* While process has not been found, keep looking for it */
    while(!processID_)
    {
        /* If a process on the system exists */
        if(Process32First(hProcSnapshot_, &processEntry_)) //?
        {
            /* Check all processes in the system's processes snapshot */
            do
            {
                /* Compare the name of the process to the one we want */
                if( !strcmp(processEntry_.szExeFile, processName_) ) //?
                {
                    /* Save the processID and break out */
                    processID_ = processEntry_.th32ProcessID ;
                    break ;
                }
            } 
            while(Process32Next(hProcSnapshot_, &processEntry_)) ;
        }

        /* Didnt find process, sleep for a bit */
        if( !processID_ )
        {
            system("CLS") ;
            std::cout << "Make sure " << processName_ << " is running." << std::endl ;
            Sleep(200) ;
        }
    }

    /* Process found */
    std::cout << "Found Process: " << processName_ << std::endl ;
}


/* Find Base Address of process */
{
    HANDLE moduleSnapshotHandle_ = INVALID_HANDLE_VALUE;
    MODULEENTRY32 moduleEntry_;

    /* Take snapshot of all the modules in the process */
    moduleSnapshotHandle_ = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, processID_ );

    /* Snapshot failed */
    if( moduleSnapshotHandle_ == INVALID_HANDLE_VALUE )
    {
        std::cout << "Module Snapshot error" << std::endl ;
        return ;
    }

    /* Size the structure before usage */
    moduleEntry_.dwSize = sizeof( MODULEENTRY32 );

    /* Retrieve information about the first module */
    if( !Module32First( moduleSnapshotHandle_, &moduleEntry_ ) )
    {
        std::cout << "First module not found" << std::endl ;  
        CloseHandle( moduleSnapshotHandle_ );    
        return ;
    }

    /* Find base address */
    while(processBaseAddress_ == UNINITIALIZED)
    {
        /* Find module of the executable */
        do
        {

            /* Compare the name of the process to the one we want */
            if( !strcmp(moduleEntry_.szModule, processName_) ) //?
            {
                /* Save the processID and break out */
                processBaseAddress_ = (unsigned int)moduleEntry_.modBaseAddr ;
                break ;
            }

        } while( Module32Next( moduleSnapshotHandle_, &moduleEntry_ ) );


        if( processBaseAddress_ == UNINITIALIZED )
        {
            system("CLS") ;
            std::cout << "Failed to find module" << processName_ << std::endl ;
            Sleep(200) ;
        }
    }

    /* Found module and base address successfully */
    std::cout << "Base Address: " << std::hex << processBaseAddress_ << std::dec << std::endl ;
    CloseHandle( moduleSnapshotHandle_ );
}

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接