2014-11-04 94 views
1

即时通讯工作在C + +和ASM的钩子,目前我刚刚做了一个简单的内联钩子,在目标函数的第一个指令中跳转,在这种情况下是OutputDebugString仅用于测试目的。如何传递组件中的参数?

事情是我的钩子经过大约3天的研究并找出事物的工作原理,并发现了一些问题,但我不知道如何改变参数,这些参数进入我的“虚拟“功能,然后跳到原始功能的其余部分。

为u可以在我的代码中看到我试图改变参数只是在C++中,但当然这并不作为即时通讯工作,坡平所有后来的寄存器:/

反正这里是我的虚拟函数是什么该挂钩函数跳转到:

static void __declspec(naked) MyDebugString(LPCTSTR lpOutputString) { 
    __asm { 
     PUSHAD 
    } 

    //Where i suppose i could run my code, but not be able to interfere with parameters :/ 
    lpOutputString = L"new message!"; 

    __asm { 
     POPAD 
     MOV EDI, EDI 
     PUSH EBP 
     MOV EBP, ESP 
     JMP Addr 
    } 

    original_DebugString(lpOutputString); 
} 

我明白为什么我说的代码不工作,我实在看不出这一个妥善的解决办法,任何帮助是极大的赞赏。

+0

您需要将您的参数传送到工作寄存器,执行ADD操作,并进行必要的更改,然后再次将MOV传送到您将用于参数的位置。 – ha9u63ar 2014-11-04 15:25:53

+0

在纯汇编语言中,您*通常*将参数传递到寄存器中。在将程序集与C(或其他)混合时,你需要处理那些语言认为合适的参数以通过它们。在这种情况下,它可能在堆栈上(正好在返回地址下面)。也就是说,你的代码似乎没有任何意义。 – 2014-11-04 15:29:21

+0

我建议你只是用一些参数和局部变量来创建一个c/C++函数,比如'__stdcall'约定,并在反汇编器中查看编译器生成的asm代码如何与参数和本地堆栈变量交互并从中学习。它使用一个简单的技巧,并不总是必须计算出有多少'push */pop *'。 – Slyps 2014-11-04 15:43:53

回答

0

每个编译器都有一个使用汇编语言调用函数的协议。该协议可能在其手册中有深入的说明。

查找函数协议的更快方法是让编译器为您的函数生成汇编语言列表。

用于写入联汇编的最好的方法是:

  1. 首先写函数在C++源码
  2. 下一页打印输出功能的组件列表。
  3. 查看并了解编译器如何生成装配体。
  4. 最后,修改内部装配以满足您的需求。

我的首选是尽可能高效编写C++代码(或帮助编译器使用最佳汇编语言)。然后我查看汇编列表。我只更改内联程序集以调用处理器特殊功能(例如块移动指令)。