使用 EnumProcessModules 的 Windows 程序入口点返回意外值

Posted

技术标签:

【中文标题】使用 EnumProcessModules 的 Windows 程序入口点返回意外值【英文标题】:Windows program entry point using EnumProcessModules returns unexpected value 【发布时间】:2016-10-07 08:33:57 【问题描述】:

我正在运行一个简单的应用程序并尝试使用 Window 的 PSAPI 读取其内存中的特定偏移量。 当我运行我的调试器时,我得到了内存地址的真实值,以及我的“.exe”入口点的相对值。 然而,当我运行以下代码时,作为入口点的基本模块与我的偏移量一起产生不同的地址(这是错误的,并且偏离了几个(十六进制)点)。 可能是什么问题?

ReadMemory 是 ReadProcessMemory 的模板

    HWND   WINDOW_HANDLE;
HANDLE PROC_HANDLE;
DWORD PROC_ID;
DWORD address;
SIZE_T bytesRead; 

int InitReadMemory(const char* windowClass,const char* caption, DWORD addressOffset)


    DWORD cbNeeded;
    DWORD dwdResult;
    HMODULE mainModule;
    BOOL enumResult;

    //Get the window handle
    WINDOW_HANDLE = FindWindow(windowClass, NULL);
    if(WINDOW_HANDLE == NULL)
    
        //Window was not foud
        return 10;
    

    //Get the process ID
    dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID);
    if(dwdResult==0)
    
        //Getting Process ID failed
        return 20;
    

    //Open the process
    PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID);

    if(PROC_HANDLE==NULL)
    
        //Process failed to open
        return 30;
    

    /*
     *Get the Main Module-
     *first entry in the returned HMODULE array from
     *EnumProcessModules
     */
    enumResult = EnumProcessModules(PROC_HANDLE, &mainModule, sizeof(HMODULE), &cbNeeded);

    if(enumResult != 0)
    
        //Failed enumerating process modules
        return 40;
    

    //offset the requested memory address from the application's base address
    address = (DWORD)((UINT_PTR)mainModule + addressOffset);  

#ifdef DEBUG        
    using namespace std;
    char filenameBuffer[64]="";


    string number;
    stringstream stristream;


    stristream << address;
    stristream >> number;
    cout << number << "\r\n" << endl;

    GetModuleFileNameEx(PROC_HANDLE, mainModule , filenameBuffer, 256);
    cout << (byte)ReadMemory<byte>() << "\r\n" << number << "\r\n" << filenameBuffer << endl;
system("PAUSE");
#endif

return 1;

提前谢谢你:)

附:我主要是在寻找指针... 呸呸呸

更新: 显然,检查 GetLastError 值,EnumProcessModules 完成后提示 299 错误代码。并且调试表明 mainModule 什么都没有......但是 EnumProcessModules 返回 0 ,就像“没有错误”一样。

昨天,我设法得到它并让 GetModuleFileName 正常工作(相同的代码,只添加了 GetLastError)。

【问题讨论】:

【参考方案1】:

显然,我的问题是我使用 sn-p 运行测试

enumResult = EnumProcessModules(PROC_HANDLE, &mainModule, sizeof(HMODULE), &cbNeeded)
if(enumResult != 0)

    //Failed enumerating process modules
    return 40;

并且成功运行 EnumProcessModules 会产生非零结果! (这让我有些困惑,并让我的整个调试过程出错)

在弄清楚这个细节后,我再次运行了一些旧测试,发现我的目标进程是 64 位,而我正在运行一个 32 位应用程序。 更改为 64 位,现在它就像一个魅力

【讨论】:

以上是关于使用 EnumProcessModules 的 Windows 程序入口点返回意外值的主要内容,如果未能解决你的问题,请参考以下文章

如何在 VC++ 中使用 _W64 和 __w64?

w命令

如何使用 xslt 2.0 根据我的特定标准计算所有 <w:p> 节点?

使用连续 \d 和 \w 时了解正则表达式的行为 [重复]

使用w查看系统负载

g++ 标志的含义 -Wall -W -Werror