2010-03-23 135 views
6

我使用Detours挂钩到可执行文件的消息功能,但我需要运行我自己的代码,然后调用原始代码。根据我在Detours文档中看到的,它肯定听起来像是应该自动发生。原始功能会在屏幕上打印一条消息,但只要我附加绕道,它就会开始运行我的代码并停止打印。需要从绕道功能调用原始功能

原先的功能代码大致是:

void CGuiObject::AppendMsgToBuffer(classA, unsigned long, unsigned long, int, classB); 

我的功能是:

void CGuiObject_AppendMsgToBuffer([same params, with names]); 

我才知道,原来的功能驻留在内存中的位置,所以使用:

DWORD OrigPos = 0x0040592C; 
DetourAttach((void*)OrigPos, CGuiObject_AppendMsgToBuffer); 

让我进入功能。这段代码几乎完美地工作:我的函数被调用了正确的参数。但是,执行会离开我的函数,并且不会调用原始代码。我已经试过jmping了,但是这个程序崩溃了(我假设代码Detours移动到适合钩子负责崩溃)。

编辑:我设法解决第一个问题,没有返回到程序执行。通过将OrigPos值作为函数调用,我可以转到“蹦床”功能,并从那里到原始代码。但是,在某些地方,寄存器正在发生变化,并且一旦我回到原始代码中,就会导致程序崩溃并出现段错误。

EDIT2:最后的工作代码:

class CGuiObject 
{ 
public: 
    void MyFunc([params]); 
}; 

DWORD TrueAddr = 0x0040592C; 

CGuiObject::MyFunc([params]) 
{ 
    _asm { pushad } 
    // process 
    _asm { 
     popad 
     leave 
     jmp TrueAddr 
    } 
} 

,并使用TrueAddr在DetourAttach的第一个参数。

+0

你可以在反汇编中通过这个步骤吗? – 2010-03-23 02:43:28

+0

是的,我建立了调试,并在我的函数开始时设置了一个断点。代码命中,我pushad,做一些日志记录(使用<<运算符),popad和jmp将消息发送到fstream到Detours返回的地址。执行通过复制的东西,并回到原来的可执行文件。它运行了几行,但据我所知,ECX正被重置为0,并被用作指针,因此是段错误。如果这没有帮助,我可以用asm发布完整的代码。 – ssube 2010-03-23 18:55:08

回答

1

鉴于您试图拦截C++方法调用,因此调用原始函数时可能会遇到调用约定问题。

我还没有试图亲自去做这个弯路,但这篇文章指出的东西可能会帮助你。 C++ — Detours (Win32 API Hijacking) — Hijack Class Methods请参阅第二个答案中的链接。

+0

这工作,在一个圆的方式。最后,我创建了一个完美的框架类。它甚至可以调用自己将消息插入队列或跳过最后的部分以防止消息。感谢您的链接! :) – ssube 2010-03-24 01:47:27