-1

我不确定从 asm 调用 c++ 方法的方法是否正确。

c++ hkDrawIndexdPrimitive 方法:

HRESULT WINAPI hkDrawIndexedPrimitive (LPDIRECT3DDEVICE8 pDevice,
D3DPRIMITIVETYPE PrimType, UINT minIndex, UNIT NumVertices, UNIT startIndex, UINT primCount)

调用 hkDrawIndexdPrimitive 方法的 asm 代码:

__declspec(naked) void DIP_Mid( ) {
 __asm {
     pushad
     pushfd

     PUSH DWORD PTR SS:[EBP+0x1C]            // primCount               [4 Bytes]
     PUSH DWORD PTR SS:[EBP+0x18]            // startIndex              [4 Bytes]
     PUSH DWORD PTR SS:[EBP+0x14]            // NumVertices             [4 Bytes]
     PUSH DWORD PTR SS:[EBP+0x10]            // minIndex                [4 Bytes]
     PUSH DWORD PTR SS:[EBP+0x0C]            // PrimType                [4 Bytes]
     PUSH DWORD PTR SS:[EBP+0x08]            // pDevice                 [4 Bytes]

     CALL hkDrawIndexedPrimitive

     popad
     popfd

     XOR ESI,ESI                              // Replace Code 0x6D9D73D1 [2 Bytes]
     CMP DWORD PTR DS:[ESI+18],EBX            // Replace Code 0x6D9D73D3 [3 Bytes]

     JMP dwDIPRet;                            // Return to 0x6D9D73D6
  }
}
4

1 回答 1

1

你为什么要这么辛苦?D3D 使用 COM,它具有用于所有对象方法的虚拟函数表,这意味着您无需深入研究汇编深度并依赖于系统/编译器相关的内联 ASM。它还有一个额外的好处是对象本地,而不是应用程序或系统本地。

还有一些库可以使这种事情变得更容易,例如MS Detours这里有一个很好的教程,关于使用 detours 挂钩 D3D9 对象,完全相同的内容适用于 D3D8(唯一可能会改变的是 VFT 偏移量。

就您的程序集是否正确而言,您似乎假设已经设置了一个堆栈框架,但是 AFAIK,COM 不使用堆栈框架,因此 EBP 可能不指向堆栈的顶部。此外,您需要配对推送和弹出指令,因为堆栈是 FILO,先进后出,例如:在您的情况下,您应该有

PUSHFD
PUSHAD
//code...
POPAD
POPFD

否则,您会将随机垃圾弹出回 EFLAGS 和其他寄存器

于 2012-06-23T14:48:57.980 回答