-2

在调试并尝试解决这个问题几个小时之后,我正准备在放弃这个项目之前再次尝试解决这个问题。

鉴于以下代码,我尝试将 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;
4

1 回答 1

4

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

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对(this is )的调用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,从而导致访问冲突。Monitor baseAddresstemptemp2在调试器中,您会看到。

于 2013-10-11T07:56:48.620 回答