函数hook注意事项

函数hook,简单地说就是把目标函数替换我们的函数,用比较技术的语言描述就是:

(1) Target函数:要拦截的函数,通常为WindowsAPI

(2) Trampoline函数Target函数的复制品。因为Detours将会改写Target函数,所以先把Target函数复制保存好,一方面仍然保存Target函数的过程调用语义,另一方面便于以后的恢复。

(3) Detour函数:用来替代Target函数的函数(往往是我们自己写的函数)。

一般进行函数hook的原理是在Target函数的开头加入JMP Address_of_ Detour_Function指令(共5个字节)把对Target函数的调用引导到自己的Detour函数, Target函数的开头的5个字节加上JMP Address_of_Target _ Function + 5作为Trampoline函数地址。

         其实关于函数hook方法的资料已经汗牛充栋,而且微软也早就推出了官方的库来辅助这一过程,无需我再赘述,我在这里只想谈下面一个话题:如何写好Detour函数,这是我们总结了前人和自身实践经验得出的。

         进行过函数hook实践的同学是否有过这种经历,注入我们的代码或dll,对目标函数进行hook后,执行到我们的函数或者执行过我们的函数后,程序会出错或崩溃(甚至蓝屏)。这是正常的,编写detour函数和普通的编程很不一样,它就像深入敌后的间谍,要考虑很多细节,稍不注意会破坏Context,影响目标进程的正常运行。那么要注意什么呢?

1.       自己定义的detour函数和目标target函数的参数很返回值完全一致

因为没有代码,所以对于目标函数的参数和返回值的确定是需要逆向分析的,在有pdb的情况下很嗨,直接IDA等工具能帮你准确确定。没有pdb的情况下需要通过参数所占内存大小、特征甚至动态调试去确定,这里想强调一点是指针类型、数值类型、和引用类型的区分很关键且容易出错。另外有一种可怕的经验是返回值是一个结构,没经验无从讲起,但愿不要遇到这种情况。

2.       函数调用方式的确定与选择

我假设大家都知道了常见的cdeclstdcall还有fastcall三种调用方式的异同,通常情况下碰到的函数调用都是cdeclstdcall方式。他们最大的区别是前者是函数调用者负责栈平衡,后者是函数内负责栈平衡。我们编写detour函数时最好明确声明函数调用方式,原则是和target函数声明方式保持一致。Tips:就hook这种特殊情形,一般用stdcall更方便,因为我们的控制范围是函数内部,要向控制函数调用上下文要绕写弯路,而stdcall是在函数内部控制栈平衡的,sounder control

3.       现场保护

在编写detour函数时要时刻有一个观念就是这段代码的正确运行是以不破坏当前进程正常运行为前提的,但一个问题是我们往往不知道进程需要用到哪些现场,所以就是通过pushad-popad对寄存器进行完整保护。但应该在什么情况下使用pushadpopad呢?这个需要视具体情况而定,但有一个原则是:在开始执行自己的指令前pushad,在执行原生代码前popad,这个原则不是很准确,只是想表示:不要让自己的指令执行破坏原来的context

4.       This:“勿忘我!”

对于hook一般的系统函数,在detour函数中可以直接调用Trampoline函数,但在hook一些类成员函数后,不能直接调用Trampoline函数,因为进程确定对象成员函数需要以该对象this指针为入口进行索骥。所以hook了类成员函数,又要在detour函数中调用Trampoline函数,需要在调用前将对象的地址(this指针的内容)存入ecx中。

         就我目前的经验和水平只能总结这些,其实上述的123点背后都有一个共同的背后灵就是“栈平衡”,函数调用的最基本规则就是要在函数调用前和函数调用结束后保证sp指在同一个地方,所以你如果碰到hook崩溃的情况,第一步想到的调试方法就是对比查看函数执行前后的栈的情况然后就是比较寄存器的异同。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值