关于Hook的一些理解

我们平时所说的IDT Hook,Dispatch Hook,SSDT Hook...等,是指钩住IDT中断服务例程,Dispatch 例程和SSDT系统服务,这是Hook应用上的分类,也就是拦截它们的调用,要解决的是钩什么的问题

Inline Hook是用来实现Hook的一种方式,它和上面所说的Hook完全不是一个概念,它解决的是怎么钩的问题,一个是应用方式,一个是实现机制,IDT,Dispatch和SSDT都是可以用inline Hook来实现的。

比如我把IDT Handler的前5个字节换成长跳转跳到我的函数中运行,再用跳板函数把前5字节的指定运行后再跳回Handler+5偏移处,这样可以实现IDT Hook。

同样的Dispatch的例程我也可以这样处理,把Dispatch例程的前5字节换成跳转,跳到我的函数中,同样用一个跳板函数运行前5字节的指令,再跳回原函数的起使地址+5的位置,SSDT的也可以这样,也就是说inline Hook是实现这三种Hook的一种机制,而不是inline Hook和IDT Hook,Dispatch Hook,SSDT Hook都是一相同概念的Hook技术。

只不过有些用不着inline Hook,有些调用是用一个函数指针表,像KeServiceDescriptTable,不要总说它是什么系统服务描述表,C语言和机器语言里没有这个概念,这是操作系统一级的概念,从编译后的程序代码上来讲没有这个概念的,只从程序的角度来讲,只不过是一个结构里面一个成员(Base是一个函数指针数组),我们根据一个下标把这个指针数组中的某个条目改了(改条目在这里也是解决怎么钩的问题),就是所谓的SSDT Hook,它和下面的代码没有任何本质上的区别,确切的说下面的代码和Dispatch例程替换Hook也没有本质上的区别,不同的地方在于索引从哪里找 (ZwXXX函数地址+1的位置?IRP_MJ_XXX??),你理解了这个代码,你就理解了SSDT Hook最本质的东西,只差一些细节需要注意,比如页写保护:

#include <stdio.h>

typedef enum
{
SSDT_SHOW1,
SSDT_SHOW2,
SSDT_MAX
}SSDT_INDEX;

void Show1(void)
{
printf("show1");
}

void Show2(void)
{
printf("show2");
}

typedef void (*SSDT[SSDT_MAX])(void);

SSDT SystemTable[SSDT_MAX]={Show1,Show2};

struct
{
SSDT *Base;
int Count;
//...其它成员
}KeServiceDescriptTable;

void HookShow2(void)
{
Show2();
}

int main(void)
{
KeServiceDescriptTable.Base=SystemTable;
KeServiceDescriptTable.Count=SSDT_MAX;
//我们替换函数表项
*KeServiceDescriptTable.Base[SSDT_SHOW2]=HookShow2;

//当系统调用SHOW2时会先进Hookshow
(*KeServiceDescriptTable.Base[SSDT_SHOW2])();

return 0;
}

Inline Hook最怕的是函数前5字节指令里有jmp,因为jmp指令里带的是相对偏移量,你把指令移了位置它一跳到相对的位置就错了,这是个很简单的算术问题,100+5=105,200+5就是205了,本来指令在100它跳到105,但现在它移了位置到了200,它往后相对跳5就到了205,肯定是错的。

IDT,SSDT,DISPATCH Hook都是Hook,但是用什么机制来实现Hook的转移控制流程才是最本质的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值