ctf python大法好_[原创]必备绝技——hook大法( 中 )

本文详细介绍了Windows内核级别的Hook技术,包括SSDT Hook、IDT Hook和sysenter Hook。通过改变内存保护、使用特定宏等方式实现系统调用的拦截和替换,从而实现对系统服务的控制。文章还给出了具体的代码示例,展示了如何隐藏进程以及如何进行中断处理的Hook。适合有一定内核编程基础的读者深入理解。
摘要由CSDN通过智能技术生成

[原创]必备绝技——hook大法( 中 )

2007-4-9 23:37

190402

[原创]必备绝技——hook大法( 中 )

2007-4-9 23:37

190402

【文章标题】: 必备绝技——hook大法( 中 )

【文章作者】: LvG

【作者邮箱】: [email]LvG2008@gmail.com[/email]

【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!

--------------------------------------------------------------------------------

【详细过程】

这次主要说说核心层的hook。包括SSDT-hook,IDT-hook,sysenter-hook。欢迎讨论,指正!内核层需要驱动,有这方面的基础最好,如果不会,了解下其中的思路也可以的。

II. SSDT-hook,IDT-hook,sysenter-hook

一.SSDT-hook

(一)一般思路:

1.先来了解一下,什么是SSDT

SSDT既System Service Dispath  Table。在了解他之前,我们先了解一下NT的基本组建。在 Windows NT 下,NT 的 executive(NTOSKRNL.EXE 的一部分)提供了核心系统服务。各种 Win32、OS/2 和 POSIX 的 APIs 都是以 DLL 的形式提供的。这些dll中的 APIs 转过来调用了 NT executive 提供的服务。尽管调用了相同的系统服务,但由于子系统不同,API 函数的函数名也不同。例如,要用Win32 API 打开一个文件,应用程序会调用 CreateFile(),而要用 POSIX API,则应用程序调用 open() 函数。这两种应用程序最终都会调用 NT executive 中的 NtCreateFile() 系统服务。

系统组建.jpg

用户模式(User mode)的所有调用,如Kernel32,User32.dll, Advapi32.dll等提供的API,最终都封装在Ntdll.dll中,然后通过Int 2E或SYSENTER进入到内核模式,通过服务ID,在System Service Dispatcher Table中分派系统函数,举个具体的例子,再如下图

调用过程.jpg

从上可知,SSDT就是一个表,这个表中有内核调用的函数地址。从上图可见,当用户层调用FindNextFile函数时,最终会调用内核层的NtQueryDirectoryFile函数,而这个函数的地址就在SSDT表中,如果我们事先把这个地址改成我们特定函数的地址,那么,哈哈。。。。。。。下来详细了解一下,SSDT的结构,如下图:

SSDT.jpg

KeServiceDescriptorTable:是由内核(Ntoskrnl.exe)导出的一个表,这个表是访问SSDT的关键,具体结构是

typedef struct ServiceDescriptorTable {

PVOID ServiceTableBase;

PVOID ServiceCounterTable(0);

unsigned int NumberOfServices;

PVOID ParamTableBase;

}

其中,

ServiceTableBase System Service Dispatch Table 的基地址。

NumberOfServices 由 ServiceTableBase 描述的服务的数目。

ServiceCounterTable 此域用于操作系统的 checked builds,包含着 SSDT 中每个服务被调用次数的计数器。这个计数器由 INT 2Eh 处理程序 (KiSystemService)更新。

ParamTableBase 包含每个系统服务参数字节数表的基地址。

System Service Dispath Table(SSDT):系统服务分发表,给出了服务函数的地址,每个地址4子节长。

System Service Parameter Table(SSPT):系统服务参数表,定义了对应函数的参数字节,每个函数对应一个字节。如在0x804AB3BF处的函数需0x18字节的参数。

还有一种这样的表,叫KeServiceDescriptorTableShadow,它主要包含GDI服务,也就是我们常用的和窗口,桌面有关的,具体存在于Win32k.sys。在如图:

服务分发.jpg

右侧的服务分发就通过KeServiceDescriptorTableShadow。

那么下来该咋办呢?下来就是去改变SSDT所指向的函数,使之指向我们自己的函数。

2.Hook前的准备-改变SSDT内存的保护

系统对SSDT都是只读的,不能写。如果试图去写,等你的就是蓝脸。一般可以修改内存属性的方法有:通过cr0寄存器及Memory Descriptor List(MDL)。

(1)改变CR0寄存器的第1位

Windows对内存的分配,是采用的分页管理。其中有个CR0寄存器,如下图:

CR0.jpg

   

其中第1位叫做保护属性位,控制着页的读或写属性。如果为1,则可以读/写/执行;如果为0,则只可以读/执行。SSDT,IDT的页属性在默认下都是只读,可执行的,但不能写。所以现在要把这一位设置成1。

(2)通过Memory Descriptor List(MDL)

也就是把原来SSDT的区域映射到我们自己的MDL区域中,并把这个区域设置成可写。MDL的结构:

typedef struct _MDL {

struct _MDL *Next;

CSHORT Size;

CSHORT MdlFlags;  //关键在这里,将来设置成MDL_MAPPED_TO_SYSTEM_VA ,这样一来,这块区域就可写

struct _EPROCESS *Process;

PVOID MappedSystemVa;

PVOID StartVa;

ULONG ByteCount;

ULONG ByteOffset;

} MDL, *PMDL;

首先需要知道KeServiceDscriptorTable的基址和入口数,这样就可以用MmCreateMdl创建一个有起始地址和大小的内存区域。然后把这个MDL结构的flag改成

MDL_MAPPED_TO_SYSTEM_VA ,那么这个区域就可以写了。最后把这个内存区域调用MmMapLockedPages锁定在内存中。大体框架如下:

//先声明一个System Serv

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值