HOOK技术:SSDT HOOK(x86)

在进行SSDT Hook之前我们要先了解SSDT的概念和作用。
SSDT:
System Services Descriptor Table(系统服务描述符表),在内核中是KeServiceDescriptorTable。这个表就是一个把ring3的Win32 API和ring0的内核API联系起来。SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基地址、服务函数个数等。
(Ring3层的函数API在进入内核层后,而每个调用号对应一个内核函数,为此Windows设计了一张表通过调用号作为序号,就能找到函数的地址。Windows内核把这张函数地址表称为 : 系统服务描述表(System Service Descriptor Table ) 简称SSDT)

在这里插入图片描述
SSDT表结构如下:

typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;

0x00 实现原理

上面我们知道了SSDT表的作用,所以说要进行SSDT HOOK,只要根据索引找到函数实现的真实地址,然后将这个函数地址,更换成我们自己函数的地址,就可以完成HOOK。例如我们知道了ZwOpenProcess的索引号为0xbe,就可以通过0xbe找到函数地址,然后进行修改hook。

kd> u ZwOpenProcess
nt!ZwOpenProcess:
84857cd8 b8be000000      mov     eax,0BEh  //索引号
84857cdd 8d542404        lea     edx,[esp+4]
84857ce1 9c              pushfd
84857ce2 6a08            push    8
84857ce4 e8d5190000      call    nt!KiSystemService (848596be)
84857ce9 c21000          ret     10h
nt!ZwOpenProcessToken:
84857cec b8bf000000      mov     eax,0BFh
84857cf1 8d542404        lea     edx,[esp+4]

用一个西游记里的小故事来说明SSDT HOOK的功能:

“当年唐僧的父亲是朝廷钦派的一名官员,而再唐僧父亲赶去赴任的时候,一个强盗把唐僧的父亲杀了,并且取走了官员证明,自己去当官享受荣华富贵了。”

在这个故事中呢,唐僧的父亲就是本来的函数,官员证明就是SSDT表中函数的地址,强盗呢就是我们自己写的函数。

0x01 实现流程

1.根据索引找到函数地址
2.保存原函数地址(因为再卸载驱动的时候,我们要再恢复回去 )
3.替换地址为自己的函数地址

还有最重要的是在HOOK之前不能忘记修改内存保护。

首先我们使用找到ZwOpenProcess函数的索引0BEh。


#define SSDT_INDEX(ZwFunctionAddress)*(PULONG)((PUCHAR)ZwFunctionAddress+1)//+1是为了跳过b8
kd> u ZwOpenProcess
nt!ZwOpenProcess:
84857cd8 b8be000000      mov     eax,0BEh

然后再SSDT表中找到相应的函数地址

&__ServiceTableBase[SSDT_INDEX(ZwFunctionAddress)

然后将地址替换成自己实现的函数地址:

#define SSDT_HOOK(ZwFunctionAddress,FakeFunctionAddress,OriginalFunctionAddress)\
			OriginalFunctionAddress=(PVOID)InterlockedExchange((PLONG)&__ServiceTableBase[SSDT_INDEX(ZwFunctionAddress)],(LONG)FakeFunctionAddress)

修改内存写保护属性方法如下:

_asm
	{
		cli;                 //禁止任何中断发生
		push eax;
		mov  eax, cr0;
		mov  Attribute, eax;
		and  eax, 0xFFFEFFFF; // CR0 16 BIT = 0 
		mov  cr0, eax;
		pop  eax;
	};
发布了21 篇原创文章 · 获赞 24 · 访问量 1316

猜你喜欢

转载自blog.csdn.net/weixin_43742894/article/details/105275881