
《Windows 内核安全编程技术实践》
文章平均质量分 73
Windows 内核安全编程技术实践,是一本Windows10内核安全开发系列丛书,揭秘 AntiRootKit 反内核工具核心原理与技术实现细节,揭开ARK反内核工具的神秘面纱,本书以实战角度出发摒弃了大量无用的专业术语,欢迎阅读并提出建议。
微软技术分享
王瑞,LYSHARK(信息安全电子刊物出版品牌)创始人,微软全球最有价值专家,华为云开发者专家,金山办公最有价值专家,科创中国人才库专家,中国知网CNKI论文评审专家库专家,中国知网星云专家库专家,美国计算机协会会员,美国心理学会研究员,IEEE 电气电子工程师学会会员,中国高等教育学会会员,深耕信息安全领域,专注 Microsoft 技术在信息安全的实践与创新,撰写并发表《灰帽黑客:攻守道》、《Windows 内核安全编程技术实践》等专业著作,系统剖析攻防技术与内核安全编程,并持有 8 项信息安全领域原创软件著作权,推动技术成果转化,为信息安全防护提供有力支撑。
展开
-
驱动开发:驱动与应用的通信
驱动程序与应用程序的通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。先来简单介绍一下。原创 2019-09-23 09:05:00 · 7196 阅读 · 0 评论 -
驱动开发:DKOM 实现进程隐藏
DKOM 就是直接内核对象操作技术,我们所有的操作都会被系统记录在内存中,而驱动进程隐藏的做旧就是操作进程的EPROCESS结构与线程的ETHREAD结构、链表,要实现进程的隐藏我们只需要将某个进程中的信息,在系统EPROCESS链表中摘除即可实现进程隐藏。DKOM 隐藏进程的本质是操作EPROCESS结构体,EPROCESS结构体中包含了系统中的所有进程相关信息,还有很多指向其他结构的指针,首先我们可以通过WinDBG在内核调试模式下输入。函数就无法遍历出被摘链的进程了,从而实现了进程的隐藏。原创 2019-10-11 14:38:00 · 6590 阅读 · 0 评论 -
驱动开发:内核操作进线程与模块
进程就是活动起来的程序,每一个进程在内核里,都有一个名为EPROCESS的结构记录它的详细信息,其中就包括进程名,PID,PPID,进程路径等,通常在应用层枚举进程只列出所有进程的编号即可,不过在内核层需要把它的 EPROCESS 地址给列举出来。原创 2019-10-21 07:50:00 · 6673 阅读 · 0 评论 -
驱动开发:内核中的文件回调
无论在用户层还是内核层,操作文件的流程基本一致,除了在API函数上的区别(用户层调用用户层API,内核层调用内核API)以外其他基本一致,先讲解一下文件系统执行的流程。原创 2019-11-01 14:53:00 · 18404 阅读 · 0 评论 -
驱动开发:应用DeviceIoContro模板精讲
在笔者上一篇文章`《驱动开发:应用DeviceIoContro开发模板》`简单为大家介绍了如何使用`DeviceIoContro`模板快速创建一个驱动开发通信案例,但是该案例过于简单也无法独立加载运行,本章将继续延申这个知识点,通过封装一套标准通用模板来实现驱动通信中的常用传递方式,这其中包括了如何传递字符串,传递整数,传递数组,传递结构体等方法。可以说如果你能掌握本章模板精讲的内容基本上市面上的功能都可以使用本方法进行通信。原创 2023-06-29 09:49:21 · 5944 阅读 · 0 评论 -
驱动开发:取进程模块的函数地址
在笔者上一篇文章`《驱动开发:内核取应用层模块基地址》`中简单为大家介绍了如何通过遍历`PLIST_ENTRY32`链表的方式获取到`32位`应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数,本章将继续延申这个话题,并依次实现通用版`GetUserModuleBaseAddress()`取远程进程中指定模块的基址和`GetModuleExportAddress()`取远程进程中特定模块中的函数地址,此类功能也是各类安全工具中常用的代码片段。原创 2023-06-28 09:21:02 · 18697 阅读 · 2 评论 -
驱动开发:内核读写内存多级偏移
让我们继续在`《内核读写内存浮点数》`的基础之上做一个简单的延申,如何实现多级偏移读写,其实很简单,读写函数无需改变,只是在读写之前提前做好计算工作,以此来得到一个内存偏移值,并通过调用内存写入原函数实现写出数据的目的。以读取偏移内存为例,如下代码同样来源于本人的`LyMemory`读写驱动项目,其中核心函数为`WIN10_ReadDeviationIntMemory()`该函数的主要作用是通过用户传入的基地址与偏移值,动态计算出当前的动态地址。原创 2023-06-27 09:23:35 · 6106 阅读 · 0 评论 -
驱动开发:内核物理内存寻址读写
在某些时候我们需要读写的进程可能存在虚拟内存保护机制,在该机制下用户的`CR3`以及`MDL`读写将直接失效,从而导致无法读取到正确的数据,本章我们将继续研究如何实现物理级别的寻址读写。首先,驱动中的物理页读写是指在驱动中直接读写物理内存页(而不是虚拟内存页)。这种方式的优点是它能够更快地访问内存,因为它避免了虚拟内存管理的开销,通过直接读写物理内存,驱动程序可以绕过虚拟内存的保护机制,获得对系统中内存的更高级别的访问权限。原创 2023-06-26 09:01:46 · 20215 阅读 · 2 评论 -
驱动开发:摘除InlineHook内核钩子
在笔者上一篇文章`《驱动开发:内核层InlineHook挂钩函数》`中介绍了通过替换`函数`头部代码的方式实现`Hook`挂钩,对于ARK工具来说实现扫描与摘除`InlineHook`钩子也是最基本的功能,此类功能的实现一般可在应用层进行,而驱动层只需要保留一个`读写字节`的函数即可,将复杂的流程放在应用层实现是一个非常明智的选择,与`《驱动开发:内核实现进程反汇编》`中所使用的读写驱动基本一致,本篇文章中的驱动只保留两个功能,控制信号`IOCTL_GET_CUR_CODE`用于读取函数的前16个字节的内存原创 2023-06-24 13:14:59 · 6037 阅读 · 0 评论 -
驱动开发:内核中进程与句柄互转
在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的P原创 2023-06-23 10:16:00 · 18724 阅读 · 0 评论 -
驱动开发:内核远程线程实现DLL注入
在笔者上一篇文章`《驱动开发:内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。原创 2023-06-22 13:49:30 · 7603 阅读 · 0 评论 -
驱动开发:内核注册表增删改查
注册表是Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息,注册表是一个巨大的树形结构,无论在应用层还是内核层操作注册表都有独立的API函数可以使用,而在内核中读写注册表则需要使用内核装用API函数,如下将依次介绍并封装一些案例,实现对注册表的创建,删除,更新,查询等操作。原创 2023-06-21 09:20:14 · 19230 阅读 · 1 评论 -
驱动开发:基于事件同步的反向通信
在之前的文章中`LyShark`一直都在教大家如何让驱动程序与应用层进行`正向通信`,而在某些时候我们不仅仅只需要正向通信,也需要反向通信,例如杀毒软件如果驱动程序拦截到恶意操作则必须将这个请求动态的转发到应用层以此来通知用户,而这种通信方式的实现有多种,通常可以使用创建Socket套接字的方式实现,亦或者使用本章所介绍的通过`事件同步`的方法实现反向通信。原创 2023-06-20 08:52:36 · 9604 阅读 · 5 评论 -
驱动开发:文件微过滤驱动入门
MiniFilter 微过滤驱动是相对于`SFilter`传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数`IRP`操作都由过滤管理器`(FilterManager或Fltmgr)`所接管,因为有了兼容层,所以在开发中不需要考虑底层`IRP`如何派发,更无需要考虑兼容性问题,用户只需要编写对应的回调函数处理请求即可,这极大的提高了文件过滤驱动的开发效率。原创 2023-06-19 08:59:29 · 19907 阅读 · 0 评论 -
驱动开发:内核RIP劫持实现DLL注入
本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用`CreateRemoteThread`直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过劫持EIP的方式实现,其实现原理可总结为,挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,并把相关的指令机器码和数据拷贝到里面去,然后直接修改目标进程EIP使其强行跳转到我们拷贝进去的相关机器码位置,执行相关代码后,然后再次跳转回来执行原始指令集。原创 2023-06-16 09:05:58 · 8944 阅读 · 2 评论 -
驱动开发:内核解锁与强删文件
在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用`ObSetHandleAttributes`函数将特定句柄设置为可关闭状态,然后在调用`ZwClose`将其文件关闭,强制删除则是通过`ObReferenceObjectByHandle`在对象上提供相应的权限后直接调用`ZwDeleteFile`将其删除,虽此类代码较为普遍,但作为揭秘ARK工具来说也必须要将其分析并原创 2023-06-15 09:09:52 · 20974 阅读 · 2 评论 -
驱动开发:内核ShellCode线程注入
还记得`《驱动开发:内核LoadLibrary实现DLL注入》`中所使用的注入技术吗,我们通过`RtlCreateUserThread`函数调用实现了注入DLL到应用层并执行,本章将继续探索一个简单的问题,如何注入`ShellCode`代码实现反弹Shell,这里需要注意一般情况下`RtlCreateUserThread`需要传入两个最重要的参数,一个是`StartAddress`开始执行的内存块,另一个是`StartParameter`传入内存块的变量列表,而如果将`StartParameter`地址填充原创 2023-06-14 09:04:00 · 8927 阅读 · 4 评论 -
驱动开发:内核LoadLibrary实现DLL注入
远程线程注入是最常用的一种注入技术,在应用层注入是通过`CreateRemoteThread`这个函数实现的,该函数通过创建线程并调用 `LoadLibrary` 动态载入指定的DLL来实现注入,而在内核层同样存在一个类似的内核函数`RtlCreateUserThread`,但需要注意的是此函数未被公开,`RtlCreateUserThread`其实是对`NtCreateThreadEx`的包装,但最终会调用`ZwCreateThread`来实现注入,`RtlCreateUserThread`是`Creat原创 2023-06-13 09:25:15 · 23933 阅读 · 2 评论 -
驱动开发:内核遍历文件或目录
在笔者前一篇文章`《驱动开发:内核文件读写系列函数》`简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于`ZwQueryDirectoryFile`这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在`PFILE_BOTH_DIR_INFORMATION`结构下,通过遍历该目录即可获取到文件的详细参数,如下将具体分析并实现遍历目录功能。原创 2023-06-12 09:12:38 · 10151 阅读 · 0 评论 -
驱动开发:内核文件读写系列函数
在应用层下的文件操作只需要调用微软应用层下的`API`函数及`C库`标准函数即可,而如果在内核中读写文件则应用层的API显然是无法被使用的,内核层需要使用内核专有API,某些应用层下的API只需要增加Zw开头即可在内核中使用,例如本章要讲解的文件与目录操作相关函数,多数ARK反内核工具都具有对文件的管理功能,实现对文件或目录的基本操作功能也是非常有必要的。首先无论在内核态还是在用户态,我们调用的文件操作函数其最终都会转换为一个IRP请求,并发送到文件系统驱动上的`IRP_MJ_READ`派遣函数里面,这原创 2023-06-09 09:34:06 · 21196 阅读 · 3 评论 -
驱动开发:内核封装WFP防火墙入门
注册了一个过滤点,此处我们必须要注意三个回调函数,classifyFn, notifyFn, flowDeleteFn 他们分别的功能时,事前回调,事后回调,事后回调,而WFP框架中我们最需要注意的也就是对这三个函数进行重定义,也就是需要重写函数来实现我们特定的功能。事前更重要一些,如果需要监控网络流量则需要在事前函数中做处理,而如果是监视则可以在事后做处理,既然要在事前进行处理,那么我们就来看看事前是如何处理的流量。当有新的网络数据包路由到事前函数时,程序中会通过如下案例直接得到我们所需要的数据包头,原创 2023-06-08 09:04:27 · 10619 阅读 · 0 评论 -
驱动开发:PE导出函数与RVA转换
中简单介绍了如何扫描被挂钩的SSDT函数,并简单介绍了如何解析导出表,本章将继续延申PE导出表的解析,实现一系列灵活的解析如通过传入函数名解析出函数的RVA偏移,ID索引,Index下标等参数,并将其封装为可直接使用的函数,以在后期需要时可以被直接引用,同样为了节约篇幅本章中的。则实现传入RVA或者函数Index序号,解析出函数名,具体实现方法与如上函数基本一致,仅仅只是在过滤时做了调整。函数,当用户传入参数后自动将函数名解析为对应的RVA偏移或Index下标索引值,该函数接收三个参数传递,分别是。原创 2023-06-07 10:18:22 · 20251 阅读 · 0 评论 -
驱动开发:内核扫描SSDT挂钩状态
在笔者上一篇文章《驱动开发:内核实现SSDT挂钩与摘钩》中介绍了如何对SSDT函数进行Hook挂钩与摘钩的,本章将继续实现一个新功能,如何检测SSDT函数是否挂钩,要实现检测挂钩状态有两种方式,第一种方式则是类似于《驱动开发:摘除InlineHook内核钩子》文章中所演示的通过读取函数的前16个字节与原始字节做对比来判断挂钩状态,另一种方式则是通过对比函数的当前地址与起源地址进行判断,为了提高检测准确性本章将采用两种方式混合检测。原创 2023-06-06 08:32:24 · 9006 阅读 · 3 评论 -
驱动开发:内核实现SSDT挂钩与摘钩
接着就是如何挂钩并让其中转到我们自己的代码流程中的问题,由于挂钩与恢复代码是一样的此处就以挂钩为例,首先调用。Hook核心代码如下所示,为了节约篇幅,如果您找不到程序中的核心功能,请看前面的几篇文章,这里就不在赘述了。的目的只是为函数增加或处理新功能,则在执行完自定义函数后一定要跳回到原始函数上,此时定义一个。挂钩的目的就是要为特定函数增加功能,挂钩的实现方式无非就是替换原函数地址,我们以内核函数。将新函数地址写出到内存中实现替换,最后释放MDL句柄即可,这段代码如下所示,看过。函数可用来读取内核文件,原创 2023-06-05 08:49:47 · 20664 阅读 · 0 评论 -
驱动开发:内核PE结构VA与FOA转换
本章将继续探索内核中解析PE文件的相关内容,PE文件中FOA与VA,RVA之间的转换也是很重要的,所谓的FOA是文件中的地址,VA则是内存装入后的虚拟地址,RVA是内存基址与当前地址的相对偏移,本章还是需要用到。上图中出现的这种情况就是关于随机基址的问题,在新版的VS编译器上存在一个选项是否要启用随机基址(默认启用),至于这个随机基址的作用,猜测可能是为了防止缓冲区溢出之类的烂七八糟的东西。FOA(文件偏移) = RVA + .text节对应到文件中的偏移 => 58B + 400 = 98B。原创 2023-06-02 17:08:44 · 9441 阅读 · 0 评论 -
驱动开发:内核解析PE结构节表
上面PE结构图中可知PE文件的开头部分包括了一个标准的DOS可执行文件结构,这看上去有些奇怪,但是这对于可执行程序的向下兼容性来说却是不可缺少的,当然现在已经基本不会出现纯DOS程序了,现在来说这个。介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中。上方的结构就是PE文件的重要结构,接下来将通过编程读取出PE文件的开头相关数据,读取这些结构也非常简单代码如下所示。,节表数据在PE文件中被放在所有节数据的前面.原创 2023-06-01 19:00:25 · 20286 阅读 · 0 评论 -
驱动开发:内核解析PE结构导出表
参数,本章将继续延申这个话题,实现对PE文件导出表的解析任务,导出表无法动态获取,解析导出表则必须读入内核模块到内存才可继续解析,所以我们需要分两步走,首先读入内核磁盘文件到内存,然后再通过。取出函数的入口RVA,然后通过RVA加上模块基址便是第一个导出函数的地址,向后每次相加导出函数偏移即可依次遍历出所有的导出函数地址。导出函数存储在PE文件的导出表里,导出表的位置存放在PE文件头中的数据目录表中,与导出表对应的项目是数据目录中的首个。得到导出表的地址,依次循环读取即可得到完整的导出表。原创 2023-05-31 09:09:51 · 9244 阅读 · 0 评论 -
驱动开发:内核读写内存浮点数
将其转换为浮点数,通过此方法即可实现字节集到浮点数的转换,而决定是单精度还是双精度则只是一个字节集长度问题,这段读写代码实现原理如下所示;此处只用于演示核心原理,如果想要实现不报错,该代码中的传值操作应在应用层进行,而传入参数也应改为字节类型即可。读写,本章将在如前所述的读写函数进一步封装,并以此来实现驱动读写内存浮点数的目的。浮点数的目的,实现原理是通过读取BYTE类型的前4或者8字节的数据,并通过。的实现,因为浮点数本质上也可以看作是一个字节集,对于。函数依次循环字节集列表即可实现写出字节集的目的;原创 2023-05-30 09:08:04 · 23116 阅读 · 0 评论 -
驱动开发:内核解析内存四级页表
当今操作系统普遍采用64位架构,CPU最大寻址能力虽然达到了64位,但其实仅仅只是用到了48位进行寻址,其内存管理采用了。这段代码完整版如下所示,代码可动态定位到PTE的内存地址,然后将其取出;运行如上代码可动态获取到当前系统的PTE地址,然后将PTE填入到。中,即可实现解析系统内的四个标志位,完整解析代码如下所示;字节,PTE结构的解析非常容易,打开WinDBG输入。即可解析,如下所示,当前地址0位置处的PTE基址是。由于PTE是动态变化的,找到该地址的关键就在于通过。,由于PTE的一个页大小是。原创 2023-05-29 08:58:47 · 11673 阅读 · 0 评论 -
驱动开发:内核实现进程汇编与反汇编
简单介绍了如何通过MDL映射的方式实现进程读写操作,本章将通过如上案例实现远程进程反汇编功能,此类功能也是ARK工具中最常见的功能之一,通常此类功能的实现分为两部分,内核部分只负责读写字节集,应用层部分则配合反汇编引擎对字节集进行解码,此处我们将运用。Capstone旨在成为安全社区中二进制分析和反汇编的终极反汇编引擎,该引擎支持多种平台的反汇编,非常推荐使用。首先是实现驱动部分,驱动程序的实现是一成不变的,仅仅只是做一个读写功能即可,完整的代码如下所示;反汇编函数,该函数的解释如下所示;原创 2023-05-23 14:56:42 · 21199 阅读 · 3 评论 -
驱动开发:通过应用堆实现多次通信
的方式灵活的实现了内核态多次输出结构体的效果,但是此种方法并不推荐大家使用原因很简单首先内核空间比较宝贵,其次内核里面不能分配太大且每次传出的结构体最大不能超过。与MDL映射相反,MDL多数处理流程在内核代码中,而应用层开堆复杂代码则在应用层,但内核层中同样还是需要使用指针,只是这里的指针仅仅只是保留基本要素即可,通过。个,而最终这些内存由于无法得到更好的释放从而导致坏堆的产生,这样的程序显然是无法在生产环境中使用的,如下。回传给应用层,至此内核中仅仅回传了一个长度,其他的都写入到了应用层中。原创 2023-05-19 10:55:28 · 10526 阅读 · 0 评论 -
驱动开发:内核远程堆分配与销毁
在开始学习内核内存读写篇之前,我们先来实现一个简单的内存分配销毁堆的功能,在内核空间内用户依然可以动态的申请与销毁一段可控的堆空间,一般而言内核中提供了。则用于指定需要分配的内存空间大小,此参数的初始值指定区域的大小(以字节为单位)并向上舍入到下一个主机页大小边界。此函数则用于销毁堆内存,当我们需要分配内核空间时往往需要切换到对端进程栈上再进行操作,接下来。则用于接收分配堆地址的首地址,此处指向将接收已分配页面区域基址的变量的指针。在对特定进程分配堆时第一步就是要切入到该进程的进程栈中,此时可通过。原创 2023-05-15 09:20:45 · 10502 阅读 · 3 评论 -
驱动开发:通过MDL映射实现多次通信
在前几篇文章中`LyShark`通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用`SystemBuf`缓冲区通信,运用`ReadFile`读写通信,运用`PIPE`管道通信,以及运用`ASYNC`反向通信,这些通信方式在应对`一收一发`模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当我们枚举内核模块时,往往应用层例程中可以返回几条甚至是几十条结果,如下案例所示,这对于开发一款ARK反内核工具是必须要有的功能。原创 2023-04-29 15:12:35 · 10248 阅读 · 11 评论 -
驱动开发:内核使用IO/DPC定时器
本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,一般来说IO定时器是DDK中提供的一种,该定时器可以为间隔为N秒做定时,但如果要实现毫秒级别间隔,微秒级别间隔,就需要用到DPC定时器,如果是秒级定时其两者基本上无任何差异,本章将简单介绍。编译并运行这段程序,会发现其运行后的定时效果与IO定时器并无太大区别,但是DPC可以控制更精细,通过。函数对定时器进行初始化,但需要注意的是此函数每个设备对象只能调用一次,当初始化完成后用户可调用。原创 2023-04-04 11:19:16 · 12084 阅读 · 5 评论 -
驱动开发:探索DRIVER_OBJECT驱动对象
本章将探索驱动程序开发的基础部分,了解驱动对象`DRIVER_OBJECT`结构体的定义,一般来说驱动程序`DriverEntry`入口处都会存在这样一个驱动对象,该对象内所包含的就是当前所加载驱动自身的一些详细参数,例如驱动大小,驱动标志,驱动名,驱动节等等,每一个驱动程序都会存在这样的一个结构。原创 2023-04-03 20:36:53 · 7985 阅读 · 4 评论 -
驱动开发:配置Visual Studio驱动开发环境
在正式开始驱动开发之前,需要自行搭建驱动开发的必要环境,首先我们需要安装这款功能强大的程序开发工具,在课件内请双击ISO文件并运行内部的安装包,的安装非常的简单,您只需要按照提示全部选择默认参数即可,根据机器配置不同可能需要等待一段时间;原创 2023-03-13 14:32:00 · 11686 阅读 · 11 评论 -
驱动开发:监控进程与线程对象操作
监控进程对象和线程对象操作,可以使用ObRegisterCallbacks这个内核回调函数,通过回调我们可以实现保护calc.exe进程不被关闭,具体操作从OperationInformation->Object获得进程或线程的对象,然后再回调中判断是否是计算器,如果是就直接去掉TERMINATE_PROCESS或TERMINATE_THREAD权限即可。监控进程对象附上进程监控回调的...原创 2020-06-14 19:59:00 · 21733 阅读 · 0 评论 -
驱动开发:内核封装TDI网络通信接口
已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接。更接近于应用层,在早期Win系统中常用于实现过滤防火墙,同样经过封装后也可实现通信功能,本章将运用TDI接口实现驱动与应用层之间传输字符串,结构体,多线程收发等技术。运行应用层服务端,并运行驱动程序,则会验证该驱动是否合法,如果合法则加载不合法则拒绝;再来是驱动层代码,如下所示;原创 2022-11-03 09:47:50 · 19948 阅读 · 8 评论 -
驱动开发:内核封装WSK网络通信接口
本章`LyShark`将带大家学习如何在内核中使用标准的`Socket`套接字通信接口,我们都知道`Windows`应用层下可直接调用`WinSocket`来实现网络通信,但在内核模式下应用层API接口无法使用,内核模式下有一套专有的`WSK`通信接口,我们对WSK进行封装,让其与应用层调用规范保持一致,并实现内核与内核直接通过`Socket`通信的案例。原创 2022-11-03 09:37:50 · 11107 阅读 · 0 评论 -
驱动开发:内核层InlineHook挂钩函数
在上一章中,LyShark教大家如何通过LDE64引擎实现计算反汇编指令长度,本章将在此基础之上实现内联函数挂钩,内核中的InlineHook函数挂钩其实与应用层一致,都是使用劫持执行流并跳转到我们自己的函数上来做处理,唯一的不同的是内核Hook只针对内核API函数,但由于其身处在最底层所以一旦被挂钩其整个应用层都将会受到影响,这就直接决定了在内核层挂钩的效果是应用层无法比拟的,对于安全从业者来说学会使用内核挂钩也是很重要。挂钩的原理可以总结为,通过得到原函数地址,然后保存该函数的前15。原创 2022-10-31 17:11:55 · 10594 阅读 · 0 评论