Windows内核编程 文件监控(ssdt hook)

本文介绍了Windows内核编程中的SSDT Hook技术,用于文件监控。通过挂钩系统服务描述符表(SSDT)来拦截并修改文件相关函数的行为,实现对文件操作的监控。首先,讲解了MEP技术的基本原理,然后详细说明了环境搭建、编程语言选择、驱动入口函数(DriverEntry)和驱动派遣函数的使用。文中提到了禁用内存保护的三种方法,并以NtCreateFile为例展示了如何挂钩函数。最后,讨论了驱动卸载以移除自定义函数。
摘要由CSDN通过智能技术生成

        本文主要针为进行内核编程的一些初学者提供一些错误,如有错误,希望大家能够指出。

        这里先简单介绍一下概念。说到SSDT HOOK,可以从MEP技术说起,MEP(即执行路径修改)主旨就是拦截系统函数或相关处理例程,让它们转向我们自己的函数进行处理,这样就能实现过滤参数或者修改目标函数处理结果的目的。而SSDT(即 系统服务描述符表),主要是将位于Ring3的应用API函数和Ring0的内核函数联系起来,我们所要做的就是对文件监控所用的函数进行执行地址的修改,将它们转到我们自己编写的函数上来,实现挂钩。

       所有编程的开始当然是对环境的搭建,这里推荐《寒江独钓》等书籍,只要按照上面的步骤去做的话,基本上环境的搭建是没有问题的,注意的问题是当你在安装服务的时候,输入程序路径要将文件名(比如first.sys)一同写进去,此外,Makefile文件可以在下载的winddk当中找一份样例即可。

      关于编程语言,一般都是使用c或者c++,当然如果对于汇编语言比较熟悉也可以使用汇编。要注意的是c和c++的编译方式是不同的,意思是你不能用编译c++的方式去编译c的代码,在你所写的代码当中,如果出现了c语言和c++语言相混叠的情况,需要在代码中使用extern进行标注。

        啰嗦的了半天,可以进行正式的代码部分了,很多人在开始写内核编程的代码时候其实是毫无头绪的(包括本人),这里推荐去看看关于Windows驱动开发部分内容的书籍。我们可以这么想,一般编程,都需要一个主函数,所以呢驱动开发同样需要一个主函数,称为驱动入口函数(DriverEntry)

#pragma code_seg("INIT")  
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) //使用的是c++,出现的c语法部分添加 extern"C"
{
  
   //函数内容
}
要注意的是,这个入口函数需要我们为它添加一块内存空间。既然有驱动入口,我们就要考虑驱动的问题了,我们的程序驱动的对象是什么呢,驱动的当然是设备了,所以这里我们开始创建设备,
    //创建设备名称的字符串  
    UNICODE_STRING devName;  
    RtlInitUnicodeString(&devName, L"\\Device\\MySSDTHookDevice");   
    //创建设备  
    status = IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, TRUE, &pDevObj);  
    if (!NT_SUCCESS(status))//判断设备是否创建成功
        return status;  
    pDevObj->Flags |= DO_BUFFERED_IO;//将设备设置为缓冲设备  
    pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;//得到设备扩展  
    //创建符号链接  
    UNICODE_STRING symLinkName;  
    RtlInitUnicodeString(&symLinkName, L"\\??\\MySSDTHookDevice_link");  
    pDevExt->SymLinkName = symLinkName;  
    status = IoCreateSymbolicLink(&symLinkName, &devName);  
    if (!NT_SUCCESS(status)) //判断符号链接是否成功 失败则删除
    {  
        IoDeleteDevice(pDevObj);  
        return status;  
    }
这里我们稍微说一说设备扩展,为什么会有设备扩展呢,因为默认的设备结构实际上是固定的,我们所要使用的设备绝非只有这一种结构,设备扩展给了我们这样一个机会能够像设备的结构当中添加我们所需要的内容。

写到这时候,我们发现驱动和设备都做好了,那么触发条件又在哪里呢?这时候,我们就用到了驱动派遣函数。派遣函数是windows驱动程序当中非常重要的概念,主要负责处理I/O请求。我们可以这么理解,我们所处的环境是用户模式,如果此时我们使用我们的鼠标双击打开一个文件时候,我们的操作

一:SSDT表的hook检测和恢复 ~!~~~ 二:IDT表的hook检测和恢复 ~~~~~~(idt多处理器的恢复没处理,自己机器是单核的,没得搞,不过多核的列举可以) 三:系统加载驱动模块的检测 通过使用一个全局hash表(以DRIVEROBJECT为对象)来使用以下的方法来存储得到的结果,最终显示出来 1.常规的ZwQuerySystemInformation来列举 2通过打开驱动对象目录来列举 3搜索内核空间匹配驱动的特征来列举(这个功能里面我自己的主机一运行就死机,别的机器都没事,手动设置热键来蓝屏都不行,没dump没法分析,哎,郁闷) 4从本驱动的Modulelist开始遍历来列举驱动 四:进程的列举和进程所加载的dll检测 采用以下方法来列举进程: 1ZwQuerySystemInformation参数SystemProcessesAndThreadsInformation来枚举 2进程EPROCESS 结构的Activelist遍历来枚举 3通过解析句柄表来枚举进程 4通过Handletablelisthead枚举进程 5进程创建时都会向csrss来注册,从这个进程里面句柄表来枚举进程 6通过自身进程的HANDLETABLE来枚举进程 7通过EPROCESS的SessionProcessLinks来枚举进程 8通过EPROCESS ---VM---WorkingSetExpansionLinks获取进程 9暴力搜索内存MmSystemRangeStart以上查找PROCESS对象 进程操作: 进程的唤醒和暂停通过获取PsSuspendProcess和PsResumeProcess来操作的 进程结束通过进程空间清0和插入apc。 采用以下方法查找DLL: 1遍历VAD来查找dll 2挂靠到对应的进程查找InLoadOrderLinks来枚举dll 3暴力搜索对应进程空间查找pe特征来枚举dll DLL的操作: Dll的卸载是通过MmUnmapViewOfSection和MmmapViewOfSection(从sdt表中相应函数搜索到的)来实现的(本来想直接清0 dll空间,有时行有时不行)(只要将这个进程的ntdll卸载了,进程就结束了,一个好的杀进程的办法撒,绿色环保无污染),注入dll使用的是插入apc实现的。(注入的dll必须是realse版的。Debug版会出现***错误,全局dll注入貌似也是)插入apc效果不是很好,要有线程有告警状态才执行。 五:线程信息的检测 遍历ThreadList来枚举线程 线程的暂停和唤醒都是通过反汇编获取PsResumeThread和PsSuspendThread直接从r3传来ETHREAD来操作的,通过插入APC来结束线程 六:shadow sdt表的hook检测与恢复 没有采用pdb来解决函数名问题,直接写入xp和03的shandow表函数名(主要是自己的网不稳定,连windbg有时都连不上微软) 七:系统所有的过滤驱动的检测 查看各device下是否挂接有驱动之类的,可直接卸载 八:系统常用回调历程的检测和清除 只检查了PsSetLoadImageNotifyRoutine PsSetCreateThreadNotifyRoutine PsSetCreateProcessNotifyRoutine CmRegisterCallback这几个,至于那个什么shutdown回调不知道是啥玩意,就没搞了,有知道的顺便告诉我下撒,谢谢 九:文件系统fat和ntfs的分发函数检测 直接反汇编fat和ntfs的DriverEntry得到对应的填充分发的偏移,然后和当前已经运行的文件系统的分发相比是否被hook,并附带恢复 十:文件查看功能 自己解析ntfs和fat的结构,来实现列举文件和直接写磁盘删除。附带有普通的删除和发生IRP来删除。不过这里面有点问题,ntfs删除有时把目录给搞坏了,大家凑合着吧, Ntfs网上删除这些操作的代码不多,就是sudami大大的利用ntfs-3g来实现的,看了下,太多了,充满了结构。然后自己对照着系统删除文件时目录的变化来自己实现的。只处理了$BITMAP对应的位清除,父目录的对应文件的索引项的覆盖,删除文件对应的filerecord清0. 另外偷懒时间都没处理,呵呵,y的,一个破时间都都搞好几个字节移来移去的。 十一:常用内核模块钩子的检测和恢复 这里只检测了主要的内核模块nkrnlpa**.exe的.win32k.sys,hal.dll,比对它们的原始文件从而查找eat inline hook,iat hook ,和inline hook。Inline是从TEXT段开始一段位置开始比较的。(有点慢貌似,等待显示扫描完成就好了) 十二:应用层进程所加载dll的钩子 应用层钩子检测和内核模块钩子检测原理一样,不过为了能读写别的进程的空间,并没有使用openprocess去打开进程,而是通过KiattachProcess挂靠到当前进程,然后通过在r0直接读写进程空间的。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值