SSDT HOOK禁止指定进程结束

本文分享了一位初学者如何在论坛的帮助下实现SSDT HOOK的过程。作者从编写第一个内核程序开始,逐步尝试HOOK API函数,并在遇到问题时求助于论坛。通过与经验丰富的开发者交流,解决了代码中存在的问题,最终实现了功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经过两个星期的折腾,SSDT HOOK终于成功了,在这里首先感谢论坛里的一位大神,真的是非常感谢,他的ID是什么记不得了,加了他的好友,记得他的名字下面写着列宁两个字,呵呵很有趣的名字啊,想加的人可以看一看我发的帖子。

这里闲扯淡两句,论坛里的大神级别的人物还是不少的,我们不能用等级来衡量一个人的知识水平,就像那天看到一个c++高级程序员的帖子,两星级以上的用户优先录取,我觉着吧,这是不明智的举动,我认识的那位内核大神就是五裤衩的裤衩级用户。有人说的对,裤衩级的大神多得是,星级的菜鸟也到处都是。

作为一位大神,其实你一个你认为很不经意的举动,你认为很简单的一个回答说不定就能帮助一个菜鸟少走一大段路程,所以当一个菜鸟劳烦你一些事情的时候如果你能够稍稍再多付出一点,收到的不仅仅是感谢,还会有一种帮助的快感。

闲话就不扯了,本菜鸟要发表言论了。

经过第一个内核程序的编写,我明显的觉得自己在一步一步的成熟,我第一次写的是HOOK分发函数截获键盘记录,如果有兴趣的朋友看我另一篇博客,现在我写的是挂钩SSDT表在R0HOOK API函数。

在我写驱动HOOK之前,我是由看黒防的杂志得到的想法,我也想自己动手试试SSDT HOOK,菜鸟么,重在动手练习。我查阅资料,翻看书籍,自己写或者是借鉴别人成功的代码,写了一些SSDT HOOK的代码,但是编译神马的都通过了,就是一旦运行不是蓝屏就是死机,于是反复查资料改代码,最终还是没能通过,于是我就去论坛发帖,一个帖子挂在论坛上一个星期没有人回帖,我也只好郁闷的结了,正好有些错误经过改动和源代码也不一样,就又重写了一下发了新帖,果然当天晚上就遇到那个“列宁”的大神,他仔细的看了,真仔细的看了,给我的代码提出了五点错误。我仔细看了一下,发现了一个严重的逻辑错误,难怪蓝屏,呵呵,还是不仔细啊,除此之外“列宁”作为一个经验丰富的内核程序设计者指出了一些由于经验不足导致的小错误,使我受益匪浅。在此再次感谢。

以下是我修改后的HOOK的代码,和上次一样,为了方便,我任然没有写卸载函数,我是用的是暴力修改CR0寄存器的方法,所以稳定性有待考证,经过我的测试还是会有蓝屏的情况出现,不过作为菜鸟写的代码,确实也实现了这段代码应该有的功能,在此,我就贴出来让大家瞧瞧,不要笑话啊,毕竟是菜鸟,呵呵。

#include <ntddk.h> typedef struct _ServiceDescriptorEnty //定义结构 { unsigned int *ServiceTableBase; unsigned int *ServiceCounterTableBase; unsigned int NumberOfServices; unsigned char *ParamTableBase; }ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry; typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,IN ACCESS_MASK AccessMask,IN POBJECT_ATTRIBUTES ObjectAttributes,IN PCLIENT_ID ClientId); //定义函数 NTOPENPROCESS RealNtOpenProcess; extern PServiceDescriptorTableEntry KeServiceDescriptorTable; NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId); VOID DriverUnload(PDRIVER_OBJECT DriverObject) //卸载函数 { DbgPrint("succeed!"); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { ULONG Address; ULONG_PTR RealOPServiceAddress; _asm //取消ssdt的保护 { cli mov eax,cr0 and eax,not 10000h mov cr0,eax } Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;//得到真实地址 *((ULONG*)Address)=(ULONG)MyNtOpenProcess;//替换为自己回调函数的地址 RealOPServiceAddress = *(ULONG*)Address; //保存真是地址 RealNtOpenProcess = (NTOPENPROCESS)RealOPServiceAddress;//根据论坛上一位大神的的说法,两次寄存器的操作之间的代码要尽量少,因为调用的函数也有可能使用寄存器,改变寄存器的值 _asm //关闭保护 { cli mov eax,cr0 or eax,10000h mov cr0,eax sti } DriverObject->DriverUnload=DriverUnload; return STATUS_SUCCESS; } NTSTATUS MyNtOpenProcess(PHANDLE ProcessHandle,ACCESS_MASK DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,PCLIENT_ID ClientId) { NTSTATUS rc=NULL; ULONG dwPID; //rc=(NTSTATUS)(REALZWOPENPROCESS)RealZwOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId); if(ClientId!=NULL) //判读是否是制定的PID { dwPID=(ULONG)ClientId->UniqueProcess; if(dwPID==1884) { DbgPrint("PID 1884 has been accessed,need forbidden"); ProcessHandle=0; rc=STATUS_ACCESS_DENIED; //返回失败句柄 } } else rc=(NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId );//如果不是则调用原来的NtOpenProcess地址 return rc; }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值