GetModuleHandle无法正常工作

时间:2013-10-11 07:50:03

标签: c++ winapi

经过调试并尝试解决这个问题几个小时之后,我就是在放弃这个项目之前尝试再次解决这个问题。

鉴于以下代码,我尝试将DLL注入Solitaire,目的是操纵分数但不起作用,应用程序在最终操作时崩溃。

void SetGameTime(int time)
{
MessageBox(NULL, "Func just begins here - ", "Func start", MB_OK | MB_ICONHAND);
DWORD baseAddress = (DWORD) GetModuleHandle(0);
baseAddress = *(DWORD *) (baseAddress + BASE_OFS_DEF);

DWORD temp  = *(DWORD *)(baseAddress + SCORE_OFS1_DEF);
DWORD temp2 = *(DWORD *)(temp + SCORE_OFS2_DEF);
*(DWORD*) temp2 = 500; // solitaire crashes right here
}

那么我做错了什么?我试图在使用调试器时得到错误的逻辑,由于整个函数,'eax'为0。

调试器的输出:

    SetGameTime(500);
703E1284  push        10h  
703E1286  push        703E3170h  
703E128B  push        703E317Ch  
703E1290  push        0  
703E1292  call        dword ptr ds:[703E30ACh]  // GetModuleHandle operation (?)
703E1298  push        0  
703E129A  call        dword ptr ds:[703E3000h]  // base Address operation (?)
703E12A0  mov         eax,dword ptr [eax+97074h]  // eax keeps zero so the wrong function has to be GetModuleHandle?
703E12A6  mov         eax,dword ptr [eax+2Ch]  // first offset of score
703E12A9  mov         eax,dword ptr [eax+10h]  // and the second one...
703E12AC  mov         dword ptr [eax],1F4h  // unhandled exception, no access to write at pos 0x00000000
    return 0;

1 个答案:

答案 0 :(得分:2)

您应该检查返回值。这是来自GetModuleHandle docs:

If the function fails, the return value is NULL. 
To get extended error information, call GetLastError.

显示的程序集解释不正确。这是它的作用:

SetGameTime(500);
703E1284  push        10h         // four arguments of MessageBox call
703E1286  push        703E3170h  
703E128B  push        703E317Ch  
703E1290  push        0  
703E1292  call        dword ptr ds:[703E30ACh]  // MessageBox call
703E1298  push        0                         // argument for GetModuleHandle()
703E129A  call        dword ptr ds:[703E3000h]  // GetModuleHandle call

我认为您的评论// eax keeps zero...具有误导性。

GetModuleHandle的调用(此为703E129A call ptr ds:[703E3000h])不返回0,返回0x400000。请在调试器中检查并在需要时调用GetLastError()来查看原因,但我确信它没问题。

如果您使用Visual Studio,这也是一个很好的提示。将以下内容添加到调试器的监视窗口:@err, hr。这将确保您始终可以看到最后一个错误的值,以及相应的消息(如果有)。

您的常量(BASE_OFS_DEF& co)似乎无效。你从哪里得到它们?您阅读baseAddress + BASE_OFS_DEF的内容并将其视为有效地址,但我相信不是。稍后您将使用SCORE_OFS2_DEF进行类似的操作。

似乎在地址temp + SCORE_OFS2_DEF处写入的值为0,您将其分配给temp2,从而获得访问冲突。在调试器中监控baseAddresstemptemp2,您会看到。