分享
 
 
 

系统服务挂钩(HOOK) -1

王朝other·作者佚名  2006-12-01
窄屏简体版  字體: |||超大  

系统服务就是由操作系统提供的一组函数,类似上层开发的Win32 API。

不仅Win32 API可以挂钩,系统服务也可以挂钩。开发者为了捕获各种事件,可以挂钩文件创建函数CreateFile,注册表访问函数RegCreateKey。使用挂钩可以改变操作系统的行为,只要适当地改变挂钩的数据结构和上下文,足够引起新的行为。例如,通过挂钩NtCreateFile系统服务,可以保护敏感文件不被打开,尽管NTFS为文件提供了用户级的安全,但这些安全措施却不能用在FAT分区上。

Kernel-Level Hooking

系统级挂钩要用驱动程序实现,此方法的缺点就是,需要确定传递给内核函数的参数,但多数情况下这些服务都是未公开的。所以,这类挂钩更难实现,但可以产生更好的效果。

User-Level Hooking

用户级的挂钩的优点是这些函数通常都是公开的,可以知道所需的参数。这类挂钩只能局限于用户模式而不能扩展到内核模式。

下面主要要讨论Kernel-Level Hooking

这方面的知识可以阅读《Undocmented Windows 2000 Secrets》,在我的BLOG上可以下载由Kendiv大牛翻译的中文版,这是我看过关于挂钩系统服务最详细的书了。另外还有一本《Undocmented Windows NT》,其中第6章专门讲述这方面知识,后者可以作为补充教材,本书同样在我的BLOG上提供下载。除了这两本书以外,网上还有一些零星的文章介绍这个,比如《剖析Windows服务调用机制》等,很容易在网上搜索得到 。如果你要彻底掌握这些知识,建议把上面提到的书籍文章通通看一看。

我这里主要把重点提一下,以及自已学习过程中理解的东东,和理解后写出来的源码。不少文章有代码片段,但很多像我一样,刚刚接解内核开发,连DDK都没安装,看过那些代码片段总觉得太空洞。《Undocmented Windows 2000 Secrets》虽然提供代码(w2k_spy),但过于复杂,不利于初学者。

关于驱动程序如果编译安装,请参考有关资料。如果想要速学,建议看《Undocmented Windows 2000 Secrets》第三章。接下来,假设你已经懂得如何编译安装驱动,以及挂钩系统服务的基本知识了。

系统服务是如何被调用的?

系统服务的用户接口是以包装函数的形式提供的,这些包装函数都在NTDLL.dll中。这些包装函数使用INT 2E指令来切换到内核模式并执行所需的系统服务:每一种系统服务都用一个service ID的标识,包装函数将所需的系统服务的service ID送入EAX寄存器,将指向堆栈帧的指针送入EDX寄存器,然后发出INT 2E指令。INT 2E的处理程序将参数从用户模式的堆栈拷贝到内核模式的堆栈,这个由ntosknrl.exe提供的INT 2E处理程序内部被称为KiSystemService()。其中有一个系统服务分派表,表中的每一个表项都包含service ID和其对应的函数地址。每个函数的代码都位于内核之中。

挂钩系统服务最简单的方法就是修改系统服务分派表中的函数指针,使之指向由开发者插入的某个函数。要做到这点只能通过内核驱动,因为这个系统服务分派表是受操作系统保护的,这表所在的页属性被设置成只有内核程序才能读写,用户级的应用程序不能读写这些内存单元。

如何访问系统服务分派表?

在2000/XP中默认存在两个系统服务分派表(SDT),它们对应了两类不同的系统服务。这两个分别是:KeServiceDescriptorTable和KeServiceDescriptorTableShadow,NT下只有前面那个。KeServiceDescriptorTable定义了在ntoskrln.exe中实现的系统服务,通常在kernel32.dll和advapi32.dll中提供的函数接口均是使用KeServiceDescriptorTable。同时存在的还有win32k.sys中实现的winuser和GDI函数,它们是属于另一类系统服务调用,与之相对应的分派表是KeServiceDescriptorTableShadow,它提供了内核模式的USER和GDI的服务。由服务KeAddSystEmServiceTable添加的服务会被同时复制到上面两个分派表中。

系统服务分派表的数据结构(SDT)

typedef struct _SERVICE_DESCRIPTOR_TABLE // SDT

{

SYSTEM_SERVICE_TABLE ntoskrnl ; // ntoskrnl.exe (Nativate API)

SYSTEM_SERVICE_TABLE win32k ; // win32k.sys (gdi/user support)

SYSTEM_SERVICE_TABLE table3 ; // not used

SYSTEM_SERVICE_TABLE table4 ; // not used

} SERVICE_DESCRIPTOR_TABLE ;

typedef NTSTATUS (NTAPI *NTPROC)() ;

typedef NTPROC *PNTPROC ;

typedef struct _SYSTEM_SERVICE_TABLE // SSD

{

PNTPROC ServiceTable ; // array of entry points

PULONG CounterTable ; // array of usage counters . be NULL

ULONG ServiceLimit ; // number of table entries

UCHAR* ArgumentTable ; // array of bytes counts

} SYSTEM_SERVICE_TABLE

访问KeServiceDescriptorTable很简单,因为它由ntoskrnl.exe公开导出。

加上 extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; 这行就可以直接访问这个数据结构。但KeServiceDescriptorTableShadow没有导出(NT下没有此表),而且2000和XP下,它的位置不一样。以后我们要挂钩的都是ntoskrnl.exe导出的函数,所以不用访问KeServiceDescriptorTableShadow。

KeServiceDescriptorTabe只有第1个成员 ntoskrnl 有用到,其它3个成员全部为NULL 。KeServiceDescriptorTabeShadow前面2个成员都用到,它们的ntoskrnl成员都是相同的,差别在后者多了一个有效的win32k成员,也就是win32k.sys的系统服务分派表。在2000下 ,KeServiceDescriptorTableShadow=KeServiceDescriptorTable+0xE0;

在XP下,KeServiceDescriptorTableShadow=KeServiceDescriptorTable-0x40。

如何得到要挂钩服务的ID?

Ntosknrl.exe的服务都保存在SYSTEM_SERVICE_TABLE.ServiceTable中,该成员是个线性数组,每个项保存一个服务的地址指针,只要把这个地址换成我们提供的函数地址指针就OK了。我们怎么知道要挂钩那个服务在数组中的ID(索引)呢?

ULONG ServiceIdFromFn (PVOID pfnHandler)

{

PUCHAR pbHandler = (PUCHAR) pfnHandler ;

ULONG ulService = * ((PULONG)(pbHandler + 1));

return ulService;

}

由这个服务函数的地址可以直接转化成ID ,如 ServiceIdFromFn( ZwCreateFile )就是返回 ZwCreateFile 的ID。而且,从这个ID我们就可以判断这个服务是由ntosknrl.exe,还是win32k.sys提供的。看ID二进制的 13,14位,如果全为0表示由ntosknrl.exe提供,如果13位为1,14位为0表示由win32k.sys提供。

例子:

理论看得再多,还不如读一下代码!有的时候我更喜欢直接看代码。

我提供的代码再简洁不过,没有多余的代码,一切都只为了实现 ZwCreateFile 的挂钩。我的ZwCreateFile只是把文件名称打印出来,然后直接调用真正的ZwCreateFile 。如果你不熟悉驱动安装,又想检验一下实践的成果,可以:

1. 把hooksys.sys文件复制到 c:\windows\system32\drivers 下

2. 在命令提示符下,执行w2k_load c:\windows\system32\drivers\hooksys.sys安装

3. 运行dbgview.exe ,我的BLOG上有提供下载。

4. 在命令提示符下,执行net start hooksys 启动驱动

5. 通过dbgview.exe 观察文件的创建情况

6. 在命令提示符下,执行net stop hooksys 停止驱动

7. 删除 hooksys.sys

本代码在 XP sp2 下执行通过。例子下载

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有