经过调试并尝试解决这个问题几个小时之后,我就是在放弃这个项目之前尝试再次解决这个问题。
鉴于以下代码,我尝试将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;
答案 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
,从而获得访问冲突。在调试器中监控baseAddress
,temp
和temp2
,您会看到。