-
很久没写点什么了,最近在忙着做一些零碎的程序,过一段儿时间一定放新东西。
现在手头上的其中一件事情就是帮同学做一个文件保护的毕业设计,考虑再三还是使用SSDT HOOK,因为这个最简单,而且比较稳定,也容易理解。
提到文件保护,无非就是文件隐藏、文件打开、读写、删除保护等。
一、文件隐藏
&nb... -
在第二部分我们使用了一个前提:可以通过进程句柄得到PID等信息。
事实上这是可行的,这一部分我们就进行介绍。我这里使用的是炉子大虾的《API HOOK实现ring3的进程保护》一文中提到的方法。 -
在ring3的API HOOK中,怎样迫使目标进程调用我们的傀儡DLL是我们非常重视的一个问题。在多数情况下,我们都喜欢使用CreateRemoteThread在目标进程中创建一个远程线程来迫使它加载我们的DLL。
因为CreateRemoteThread的使用方法并不复杂,而且与其他方式相比,它可以称得上是一种相当“优雅”的做法。各种因素的汇集就导致了这种方法的泛滥,致使很多具备主动防御或行为监控的安全软件都加强了对这个函数的照顾。 -
在使用冰刃的时候我们可以发现它有一个“监视进线程创建”的功能,这个功能挺有用的,在用户模式下我们可以注册一个shell钩子来监视,或者通过挂钩一些进程创建的Win32 API来实现。
在内核模式下我们同样可以使用API HOOK来实现,但是还有一些简单的做法,比如我们今天要介绍的PsSetCreateProcessNotifyRoutine函数。 -
从文件句柄和注册表句柄中读取文件及注册表键完整路径的方法。
-
并不是所有的驱动都需要直接访问硬件的,事实上几乎所有的硬件设备都存在着驱动程序链,最底层的驱动程序可以直接访问硬件,并对上层提供透明服务,最上层的驱动程序只要对接收到的数据进行过滤、格式化等处理即可,这样大大减少了开发的难度。
-
我们知道,系统中一些重要的表项如SSDT是只读的,如果我们强行对其进行修改就会造成BSOD的严重后果。当然这种保护方式很容易被绕过,我们曾经介绍了通过修改cr0来禁用WP(Write Protect,写保护)位的方法,现在再介绍一种不需要使用汇编的方法,就是MDL。
-
cr0是系统内的控制寄存器之一。控制寄存器是一些特殊的寄存器,它们可以控制CPU的一些重要特性。
-
在炉子的《API HOOK实现ring3的进程保护》一文中给出了一种解决方法,即使用NTDLL导出的Zw(Nt)QueryInformationProcess函数。
-
在我昨日发布的《驱动学习笔记系列文章汇总(PDF)》第11.2节中,我没有给出使用DeviceIoControl通信的演示源码,附录中附带的程序是我尚未调试好的,因此没有达到通信的目的。
今天又认真阅读了下张帆的《Windows驱动开发技术详解》第7章的内容,并对它给出的示例程序多次调试,总算把这个通信过程给理解了,下面我们先来看看应用层程序的代码:
-
IRP是从未分页内存申请的大小可变的结构,它由两部分组成:
1,包含一般簿记信息的头区域,即IRP头。
2,若干个成为I/O堆栈位置的内存块,即I/O堆栈。 -
IRP的全名是I/O Request Package,即输入输出请求包,它是Windows内核中的一种非常重要的数据结构。上层应用程序与底层驱动程序通信时,应用程序会发出I/O请求,操作系统将相应的I/O请求转换成相应的IRP,不同的IRP会根据类型被分派到不同的派遣例程中进行处理。
-
此前我们曾经介绍过不少枚举进程的方法,现在我们来到了ring0这一层,肯定是想玩点与ring3不同的东西。 今天我们就介绍一种通过EPROCESS链表来枚举系统进程的方法。
-
此前在“【科普6】利用NTDLL导出函数枚举进程”一文中我们曾经介绍了在ring3通过动态导出ntdll.dll中的ZwQuerySystemInformation函数来枚举系统进程,那么在ring0能否调用该函数呢?
-
在ring3的编程中我们经常使用多线程来提高效率或满足一些特殊的要求,当然在内核中也是一样,我们经常需要使用几个线程来同步完成一些工作。
-
在编程中,我们经常需要获得系统时间或是从启动开始的毫秒数,启动毫秒数在ring3我们可以使用GetTickCount()函数来获得,在ring0中也有一个对应的函数KeQueryTickCount(),不过单靠这个函数还不够。
-
注册表是Windows的核心,日常的许多操作其实最终都是转化成了对注册表的操作,在ring3我们就经常利用注册表达到一些简单而特殊的效果,例如实现自启动等。到了ring0,有关注册表的操作更加频繁,在ring0我们主要使用Zw系列函数,与ZwCreateKey、ZwDeleteKey等。
-
对文件的读写操作一直是我们需要熟练掌握的内容,在ring3我们可以使用CreateFile、ReadFile、WriteFile等API,在ring0同样很相似,不过函数变成了ZwCreateFile、ZwReadFile、ZwWriteFile等函数。
-
在驱动程序的开发中经常需要用到链表,常见的链表有单向链表和双向链表,我们只介绍双向链表的使用方法,DDK为我们提供了标准的双向链表LIST_ENTRY,但这个链表里面没有数据,不能直接使用,我们需要自己定义一个结构体类型,然后将LIST_ENTRY作为结构体的一个子域,如下所示
-
驱动开发通常有两种环境,一种是使用任意文本编辑器来编写代码,然后通过编写makefile和sources文件在WinDDK的命令行环境下使用build命令编译;另一种方法是使用各种各样的方法以图可以利用IDE的环境来搭建驱动框架,比如使用驱动向导文件或一些小工具,我经常使用的是EasySys这个小工具。










