为了向游戏添加新内容,我正在反向设计一款非常古老的游戏(Mu 97d)。我正在做的是用 DLL 拦截游戏,并在 DLL 中进行计算,以便我可以添加新内容。
我有这段代码可以拦截一个“if”语句,我将它重定向到我自己的函数——根据输入——我的函数返回真或假。
代码:
/* Called on player load - 12 bytes */
*(BYTE*)(0x004798CD + 0) = 0x50; /* PUSH EAX */
*(BYTE*)(0x004798CD + 1) = 0xE8; /* CALL */
*(DWORD*)(0x004798CD + 2) = (DWORD)&Unk11 - (0x004798CD + 6); /* FUNCTION TO CALL */
*(BYTE*)(0x004798CD + 6) = 0x85; /* TEST */
*(BYTE*)(0x004798CD + 7) = 0xC0; /* EAX, EAX */
*(BYTE*)(0x004798CD + 8) = 0x58; /* POP EAX */
*(BYTE*)(0x004798CD + 9) = 0x74; /* JE */
*(BYTE*)(0x004798CD + 10) = 0x15; /* 15 */
*(BYTE*)(0x004798CD + 11) = 0x90; /* NOP */
我正在拦截的 ASM 部分
[...]
004798A1 |. 81E7 FF000000 AND EDI,000000FF
004798A7 |. 8D0440 LEA EAX,[EAX*2+EAX]
004798AA |. C1E0 02 SHL EAX,2
004798AD |. 99 CDQ
004798AE |. F7FF IDIV EDI
004798B0 |. 8BD8 MOV EBX,EAX
004798B2 |. B8 67666666 MOV EAX,66666667
004798B7 |. F7EF IMUL EDI
004798B9 |. D1FA SAR EDX,1
004798BB |. 8BC2 MOV EAX,EDX
004798BD 03D3 ADD EDX,EBX
004798BF C1E8 1F SHR EAX,1F
004798C2 8D5410 04 LEA EDX,[EDX+EAX+4]
004798C6 66:0156 12 ADD WORD PTR DS:[ESI+12],DX
004798CA 66:8B06 MOV AX,WORD PTR DS:[ESI]
004798CD 66:3D 8301 CMP AX,183 ]---------------------- FROM HERE
004798D1 7C 1A JL SHORT 004798ED
004798D3 66:3D 8601 CMP AX,186
004798D7 7F 14 JG SHORT 004798ED ]--------------- TO HERE
004798D9 83F9 09 CMP ECX,9
004798DC B8 09000000 MOV EAX,9
004798E1 7F 02 JG SHORT 004798E5
004798E3 8BC1 MOV EAX,ECX
004798E5 03C0 ADD EAX,EAX
004798E7 66:0146 12 ADD WORD PTR DS:[ESI+12],AX
004798EB EB 13 JMP SHORT 00479900
004798ED 83F9 09 CMP ECX,9
004798F0 |. B8 09000000 MOV EAX,9
004798F5 |. 7F 02 JG SHORT 004798F9
004798F7 |. 8BC1 MOV EAX,ECX
004798F9 |> 8D1440 LEA EDX,[EAX*2+EAX]
004798FC |. 66:0156 12 ADD WORD PTR DS:[ESI+12],DX
00479900 |> 8D51 F7 LEA EDX,[ECX-9]
00479903 |. 33C0 XOR EAX,EAX
00479905 |. 85D2 TEST EDX,EDX
00479907 |. 7E 1D JLE SHORT 00479926
00479909 |. BB 04000000 MOV EBX,4
0047990E |. BF 05000000 MOV EDI,5
00479913 |> 85C0 /TEST EAX,EAX
00479915 |. 75 06 |JNE SHORT 0047991D
00479917 |. 66:015E 12 |ADD WORD PTR DS:[ESI+12],BX
0047991B |. EB 04 |JMP SHORT 00479921
0047991D |> 66:017E 12 |ADD WORD PTR DS:[ESI+12],DI
00479921 |> 40 |INC EAX
[...]
这是来自我的 DLL 的代码,该函数现在的行为与游戏一样。
BOOL Unk11(short int a1)
{
if((a1 >= 387 && a1 <= 390))
return TRUE;
return FALSE;
}
但是,如果我向 IF 添加第二个条件:
BOOL Unk11(short int a1)
{
if((a1 >= 387 && a1 <= 390) || (a1 >= 404 && a1 <= 415))
return TRUE;
return FALSE;
}
游戏变得不稳定,即使使用写入日志文件的简单调试功能,游戏也会变得不稳定,例如:
BOOL Unk11(short int a1)
{
Debug("Hello");
if((a1 >= 387 && a1 <= 390))
return TRUE;
return FALSE;
}
我使用 Ollydbg 执行了游戏,并检查了我函数的 ASM 部分,这就是我得到的:
CPU Disasm
Address Hex dump Command Comments
7C721B30 55 PUSH EBP
7C721B31 8BEC MOV EBP,ESP
7C721B33 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
7C721B36 05 7DFEFFFF ADD EAX,-183
7C721B3B 66:B9 0300 MOV CX,3
7C721B3F 66:3BC8 CMP CX,AX
7C721B42 1BC0 SBB EAX,EAX
7C721B44 40 INC EAX
7C721B45 5D POP EBP
7C721B46 C3 RETN
为什么 ADD EAX 是 -183?不应该是183吗?这段代码中的“<= 390”在哪里?我尝试了不同的调用约定,但我得到了相同的行为 - 游戏不稳定。
为什么即使是最小游戏,游戏也不稳定?游戏很旧,2003 年左右 - 这可能是我的 DLL 的兼容性问题吗?我正在使用 Visual Studio 2010。
我希望这是足够的信息,如果没有,请说出来!谢谢!