c ++在线调用asm

时间:2012-06-22 04:41:29

标签: c++ assembly

我不确定我是否正确地从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
  }
}

1 个答案:

答案 0 :(得分:1)

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

还有一些库可以让这类事情变得更容易,例如MS Detourshere是一个使用绕行来挂钩D3D9对象的精彩教程,完全相同的情况适用于D3D8(仅限可能会改变的是VFT抵消。

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

PUSHFD
PUSHAD
//code...
POPAD
POPFD

否则,您将随机垃圾回流到EFLAGS和其他寄存器