这实际上是反汇编 Windows 7 D3D9.dll 的 DrawIndexedPrimitive 方法。
CPU Disasm
Address Hex dump Command Comments
58EBB6B1 . 8BFF MOV EDI,EDI
58EBB6B3 /. 55 PUSH EBP
58EBB6B4 |. 8BEC MOV EBP,ESP
58EBB6B6 |. 6A FF PUSH -1
58EBB6B8 |. 68 28BE0259 PUSH 5902BE28 ; Entry point
58EBB6BD |. 64:A1 0000000 MOV EAX,DWORD PTR FS:[0]
58EBB6C3 |. 50 PUSH EAX
58EBB6C4 |. 83EC 20 SUB ESP,20
58EBB6C7 |. 53 PUSH EBX
58EBB6C8 |. 56 PUSH ESI
58EBB6C9 |. 57 PUSH EDI
58EBB6CA |. A1 50920359 MOV EAX,DWORD PTR DS:[59039250]
58EBB6CF |. 33C5 XOR EAX,EBP
58EBB6D1 |. 50 PUSH EAX
58EBB6D2 |. 8D45 F4 LEA EAX,[EBP-0C]
58EBB6D5 |. 64:A3 0000000 MOV DWORD PTR FS:[0],EAX
58EBB6DB |. 8965 F0 MOV DWORD PTR SS:[EBP-10],ESP
58EBB6DE |. 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
58EBB6E1 |. 33DB XOR EBX,EBX
58EBB6E3 |. 3BFB CMP EDI,EBX
58EBB6E5 |.- 0F84 BA030000 JE 58EBBAA5
58EBB6EB |. 8D77 04 LEA ESI,[EDI+4]
58EBB6EE |. 8975 EC MOV DWORD PTR SS:[EBP-14],ESI
58EBB6F1 |> 8975 D4 MOV DWORD PTR SS:[EBP-2C],ESI
58EBB6F4 |. 895D D8 MOV DWORD PTR SS:[EBP-28],EBX
58EBB6F7 |. 395E 18 CMP DWORD PTR DS:[ESI+18],EBX
58EBB6FA |.- 0F85 66DE0500 JNE 58F19566
58EBB700 |> F647 2C 02 TEST BYTE PTR DS:[EDI+2C],02
58EBB704 |. 895D FC MOV DWORD PTR SS:[EBP-4],EBX
58EBB707 |.- 0F85 65DE0500 JNE 58F19572
58EBB70D |. 818F 0C2A0000 OR DWORD PTR DS:[EDI+2A0C],40000000
58EBB717 |. F647 2C 08 TEST BYTE PTR DS:[EDI+2C],08
58EBB71B |. C645 FC 01 MOV BYTE PTR SS:[EBP-4],1
58EBB71F |.- 0F85 54030000 JNE 58EBBA79
58EBB725 |> 8B8F F02C0000 MOV ECX,DWORD PTR DS:[EDI+2CF0]
58EBB72B |. 8B55 10 MOV EDX,DWORD PTR SS:[EBP+10]
58EBB72E |. 8DB7 3C2B0000 LEA ESI,[EDI+2B3C]
58EBB734 |. 8951 14 MOV DWORD PTR DS:[ECX+14],EDX
58EBB737 |. 399E 70010000 CMP DWORD PTR DS:[ESI+170],EBX
58EBB73D |.- 0F85 54DE0500 JNE 58F19597
58EBB743 |> F787 0C2A0000 TEST DWORD PTR DS:[EDI+2A0C],00000200
58EBB74D |.- 0F85 AE020000 JNE 58EBBA01
58EBB753 |> 8B4D 20 MOV ECX,DWORD PTR SS:[EBP+20]
58EBB756 |. 8B55 1C MOV EDX,DWORD PTR SS:[EBP+1C]
58EBB759 |. 8B45 18 MOV EAX,DWORD PTR SS:[EBP+18]
58EBB75C |. 51 PUSH ECX
58EBB75D |. 8B4D 14 MOV ECX,DWORD PTR SS:[EBP+14]
58EBB760 |. 52 PUSH EDX
58EBB761 |. 8B55 10 MOV EDX,DWORD PTR SS:[EBP+10]
58EBB764 |. 50 PUSH EAX
58EBB765 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+0C]
58EBB768 |. 51 PUSH ECX
58EBB769 |. 8B8F 0C2D0000 MOV ECX,DWORD PTR DS:[EDI+2D0C]
58EBB76F |. 52 PUSH EDX
58EBB770 |. 50 PUSH EAX
58EBB771 |. 57 PUSH EDI
58EBB772 |. FFD1 CALL ECX
58EBB774 |. 8B45 EC MOV EAX,DWORD PTR SS:[EBP-14]
58EBB777 |. 81A7 0C2A0000 AND DWORD PTR DS:[EDI+2A0C],BFFFFFFF
58EBB781 |. 83C4 1C ADD ESP,1C
58EBB784 |. 3958 18 CMP DWORD PTR DS:[EAX+18],EBX
58EBB787 |.- 0F85 6ADF0500 JNE 58F196F7
58EBB78D |> 33C0 XOR EAX,EAX
58EBB78F |. 8B4D F4 MOV ECX,DWORD PTR SS:[EBP-0C]
58EBB792 |. 64:890D 00000 MOV DWORD PTR FS:[0],ECX
58EBB799 |. 59 POP ECX
58EBB79A |. 5F POP EDI
58EBB79B |. 5E POP ESI
58EBB79C |. 5B POP EBX
58EBB79D |. 8BE5 MOV ESP,EBP
58EBB79F |. 5D POP EBP
58EBB7A0 \. C2 1C00 RETN 1C
比如说,我用我的跳转代码洞穴替换了 58EBB6DB(3 个字节)和 58EBB6DE(3 个字节)。这将替换 6 个字节的代码(跳转到我的代码洞穴函数地址 5 个字节,并跳过第 6 个字节)。
然后,我将替换后的原始 6 字节代码放回我的代码洞穴函数中。“MOV DWORD PTR SS:[EBP-10],ESP”和“MOV EDI,DWORD PTR SS:[EBP+8]”。然后我的代码洞穴开始做我的工作......
我的代码洞穴中有一个 If-Then-Else。
假设
1) 当结果为真时,我的代码洞穴返回 58EBB6E1 地址。
2)当结果为假时,这个DrawIndexedPrimitive方法将在我的代码洞穴编码处终止。
当我的代码洞穴返回到 58EBB6E1 地址的下一条指令行时,我对第一个没有问题。但是当我终止它时,游戏崩溃了。
这就是我终止该方法的方式。
TERMINATE:
POPAD // clear the previous PUSHAD
POPFD // clear the previous PUSHFD
// restore what DrawIndexedPrimitive method called...
POP EDI
POP ESI
POP EBX
MOV ESP,EBP
POP EBP
RETN 1C //CD3DBase::DrawIndexedPrimitive(enum _D3DPRIMITIVETYPE, int, unsigned int, unsigned int, unsigned int, unsigned int)