合集-Windows 内核安全编程技术实践

摘要:在进程的`_EPROCESS`中有一个`_RTL_AVL_TREE`类型的`VadRoot`成员,它是一个存放进程内存块的二叉树结构,如果我们找到了这个二叉树中我们想要隐藏的内存,直接将这个内存在二叉树中`抹去`,其实是让上一个节点的`EndingVpn`指向下个节点的`EndingVpn`,类似于摘链隐藏进程,就可以达到隐藏的效果。 阅读全文
posted @ 2021-07-16 10:40 lyshark 阅读(1522) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:应用DeviceIoContro开发模板》`简单为大家介绍了如何使用`DeviceIoContro`模板快速创建一个驱动开发通信案例,但是该案例过于简单也无法独立加载运行,本章将继续延申这个知识点,通过封装一套标准通用模板来实现驱动通信中的常用传递方式,这其中包括了如何传递字符串,传递整数,传递数组,传递结构体等方法。可以说如果你能掌握本章模板精讲的内容基本上市面上的功能都可以使用本方法进行通信。 阅读全文
posted @ 2023-06-29 09:48 lyshark 阅读(1091) 评论(0) 推荐(1)
摘要:在笔者上一篇文章`《驱动开发:内核取应用层模块基地址》`中简单为大家介绍了如何通过遍历`PLIST_ENTRY32`链表的方式获取到`32位`应用程序中特定模块的基地址,由于是入门系列所以并没有封装实现太过于通用的获取函数,本章将继续延申这个话题,并依次实现通用版`GetUserModuleBaseAddress()`取远程进程中指定模块的基址和`GetModuleExportAddress()`取远程进程中特定模块中的函数地址,此类功能也是各类安全工具中常用的代码片段。 阅读全文
posted @ 2023-06-28 09:19 lyshark 阅读(1379) 评论(0) 推荐(0)
摘要:让我们继续在`《内核读写内存浮点数》`的基础之上做一个简单的延申,如何实现多级偏移读写,其实很简单,读写函数无需改变,只是在读写之前提前做好计算工作,以此来得到一个内存偏移值,并通过调用内存写入原函数实现写出数据的目的。以读取偏移内存为例,如下代码同样来源于本人的`LyMemory`读写驱动项目,其中核心函数为`WIN10_ReadDeviationIntMemory()`该函数的主要作用是通过用户传入的基地址与偏移值,动态计算出当前的动态地址。 阅读全文
posted @ 2023-06-27 09:23 lyshark 阅读(1029) 评论(2) 推荐(0)
摘要:在某些时候我们需要读写的进程可能存在虚拟内存保护机制,在该机制下用户的`CR3`以及`MDL`读写将直接失效,从而导致无法读取到正确的数据,本章我们将继续研究如何实现物理级别的寻址读写。首先,驱动中的物理页读写是指在驱动中直接读写物理内存页(而不是虚拟内存页)。这种方式的优点是它能够更快地访问内存,因为它避免了虚拟内存管理的开销,通过直接读写物理内存,驱动程序可以绕过虚拟内存的保护机制,获得对系统中内存的更高级别的访问权限。 阅读全文
posted @ 2023-06-26 08:59 lyshark 阅读(3249) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。 阅读全文
posted @ 2023-06-25 09:15 lyshark 阅读(1479) 评论(1) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核层InlineHook挂钩函数》`中介绍了通过替换`函数`头部代码的方式实现`Hook`挂钩,对于ARK工具来说实现扫描与摘除`InlineHook`钩子也是最基本的功能,此类功能的实现一般可在应用层进行,而驱动层只需要保留一个`读写字节`的函数即可,将复杂的流程放在应用层实现是一个非常明智的选择,与`《驱动开发:内核实现进程反汇编》`中所使用的读写驱动基本一致,本篇文章中的驱动只保留两个功能,控制信号`IOCTL_GET_CUR_CODE`用于读取函数的前16个字节的内存,信号`IOCTL_SET_ORI_CODE`则用于设置前16个字节的内存。 阅读全文
posted @ 2023-06-24 13:13 lyshark 阅读(805) 评论(0) 推荐(2)
摘要:在内核开发中,经常需要进行进程和句柄之间的互相转换。进程通常由一个唯一的进程标识符(PID)来标识,而句柄是指对内核对象的引用。在Windows内核中,`EProcess`结构表示一个进程,而HANDLE是一个句柄。为了实现进程与句柄之间的转换,我们需要使用一些内核函数。对于进程PID和句柄的互相转换,可以使用函数如`OpenProcess`和`GetProcessId`。OpenProcess函数接受一个PID作为参数,并返回一个句柄。GetProcessId函数接受一个句柄作为参数,并返回该进程的PID。 阅读全文
posted @ 2023-06-23 10:13 lyshark 阅读(812) 评论(0) 推荐(2)
摘要:注册表是Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息,注册表是一个巨大的树形结构,无论在应用层还是内核层操作注册表都有独立的API函数可以使用,而在内核中读写注册表则需要使用内核装用API函数,如下将依次介绍并封装一些案例,实现对注册表的创建,删除,更新,查询等操作。 阅读全文
posted @ 2023-06-21 09:18 lyshark 阅读(816) 评论(0) 推荐(0)
摘要:在之前的文章中`LyShark`一直都在教大家如何让驱动程序与应用层进行`正向通信`,而在某些时候我们不仅仅只需要正向通信,也需要反向通信,例如杀毒软件如果驱动程序拦截到恶意操作则必须将这个请求动态的转发到应用层以此来通知用户,而这种通信方式的实现有多种,通常可以使用创建Socket套接字的方式实现,亦或者使用本章所介绍的通过`事件同步`的方法实现反向通信。 阅读全文
posted @ 2023-06-20 08:49 lyshark 阅读(879) 评论(0) 推荐(2)
摘要:MiniFilter 微过滤驱动是相对于`SFilter`传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数`IRP`操作都由过滤管理器`(FilterManager或Fltmgr)`所接管,因为有了兼容层,所以在开发中不需要考虑底层`IRP`如何派发,更无需要考虑兼容性问题,用户只需要编写对应的回调函数处理请求即可,这极大的提高了文件过滤驱动的开发效率。 阅读全文
posted @ 2023-06-19 08:59 lyshark 阅读(2180) 评论(2) 推荐(0)
摘要:本章将探索内核级DLL模块注入实现原理,DLL模块注入在应用层中通常会使用`CreateRemoteThread`直接开启远程线程执行即可,驱动级别的注入有多种实现原理,而其中最简单的一种实现方式则是通过劫持EIP的方式实现,其实现原理可总结为,挂起目标进程,停止目标进程EIP的变换,在目标进程开启空间,并把相关的指令机器码和数据拷贝到里面去,然后直接修改目标进程EIP使其强行跳转到我们拷贝进去的相关机器码位置,执行相关代码后,然后再次跳转回来执行原始指令集。 阅读全文
posted @ 2023-06-16 09:04 lyshark 阅读(2735) 评论(1) 推荐(2)
摘要:在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用`ObSetHandleAttributes`函数将特定句柄设置为可关闭状态,然后在调用`ZwClose`将其文件关闭,强制删除则是通过`ObReferenceObjectByHandle`在对象上提供相应的权限后直接调用`ZwDeleteFile`将其删除,虽此类代码较为普遍,但作为揭秘ARK工具来说也必须要将其分析并讲解一下。 阅读全文
posted @ 2023-06-15 09:07 lyshark 阅读(1412) 评论(0) 推荐(0)
摘要:还记得`《驱动开发:内核LoadLibrary实现DLL注入》`中所使用的注入技术吗,我们通过`RtlCreateUserThread`函数调用实现了注入DLL到应用层并执行,本章将继续探索一个简单的问题,如何注入`ShellCode`代码实现反弹Shell,这里需要注意一般情况下`RtlCreateUserThread`需要传入两个最重要的参数,一个是`StartAddress`开始执行的内存块,另一个是`StartParameter`传入内存块的变量列表,而如果将`StartParameter`地址填充为`NULL`则表明不传递任何参数,也就是只在线程中执行`ShellCode`代码,利用这个特点我们就可以在上一篇文章的基础之上简单改进代码即可实现驱动级后门注入的功能。 阅读全文
posted @ 2023-06-14 09:04 lyshark 阅读(1206) 评论(0) 推荐(0)
摘要:远程线程注入是最常用的一种注入技术,在应用层注入是通过`CreateRemoteThread`这个函数实现的,通过该函数通过创建线程并调用 `LoadLibrary` 动态载入指定的DLL来实现注入,而在内核层同样存在一个类似的内核函数`RtlCreateUserThread`,但需要注意的是此函数未被公开,`RtlCreateUserThread`其实是对`NtCreateThreadEx`的包装,但最终会调用`ZwCreateThread`来实现注入,`RtlCreateUserThread`是`CreateRemoteThread`的底层实现。 阅读全文
posted @ 2023-06-13 09:22 lyshark 阅读(1688) 评论(0) 推荐(2)
摘要:在笔者前一篇文章`《驱动开发:内核文件读写系列函数》`简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于`ZwQueryDirectoryFile`这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在`PFILE_BOTH_DIR_INFORMATION`结构下,通过遍历该目录即可获取到文件的详细参数,如下将具体分析并实现遍历目录功能。 阅读全文
posted @ 2023-06-12 09:11 lyshark 阅读(901) 评论(1) 推荐(0)
摘要:在应用层下的文件操作只需要调用微软应用层下的`API`函数及`C库`标准函数即可,而如果在内核中读写文件则应用层的API显然是无法被使用的,内核层需要使用内核专有API,某些应用层下的API只需要增加Zw开头即可在内核中使用,例如本章要讲解的文件与目录操作相关函数,多数ARK反内核工具都具有对文件的管理功能,实现对文件或目录的基本操作功能也是非常有必要的。 阅读全文
posted @ 2023-06-09 09:32 lyshark 阅读(810) 评论(0) 推荐(0)
摘要:WFP框架是微软推出来替代TDIHOOK传输层驱动接口网络通信的方案,其默认被设计为分层结构,该框架分别提供了用户态与内核态相同的AIP函数,在两种模式下均可以开发防火墙产品,以下代码我实现了一个简单的驱动过滤防火墙。WFP 框架分为两大层次模块,用户态基础过滤引擎`BFE (BaseFilteringEngine)` ,以及内核态过滤引擎 `KMFE (KMFilteringEngine)`,基础过滤引擎对上提供C语言调用方式的API以及RPC接口,这些接口都被封装在`FWPUCLNT.dll`模块中,开发时可以调用该模块中的导出函数. 阅读全文
posted @ 2023-06-08 09:04 lyshark 阅读(1941) 评论(1) 推荐(0)
摘要:在笔者上篇文章`《驱动开发:内核扫描SSDT挂钩状态》`中简单介绍了如何扫描被挂钩的SSDT函数,并简单介绍了如何解析导出表,本章将继续延申PE导出表的解析,实现一系列灵活的解析如通过传入函数名解析出函数的RVA偏移,ID索引,Index下标等参数,并将其封装为可直接使用的函数,以在后期需要时可以被直接引用,同样为了节约篇幅本章中的`LoadKernelFile()`内存映射函数如需要使用请去前一篇文章中自行摘取。 阅读全文
posted @ 2023-06-07 10:16 lyshark 阅读(560) 评论(4) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核实现SSDT挂钩与摘钩》`中介绍了如何对`SSDT`函数进行`Hook`挂钩与摘钩的,本章将继续实现一个新功能,如何`检测SSDT`函数是否挂钩,要实现检测`挂钩状态`有两种方式,第一种方式则是类似于`《驱动开发:摘除InlineHook内核钩子》`文章中所演示的通过读取函数的前16个字节与`原始字节`做对比来判断挂钩状态,另一种方式则是通过对比函数的`当前地址`与`起源地址`进行判断,为了提高检测准确性本章将采用两种方式混合检测。 阅读全文
posted @ 2023-06-06 08:32 lyshark 阅读(612) 评论(0) 推荐(2)
摘要:在前面的文章`《驱动开发:内核解析PE结构导出表》`中我们封装了两个函数`KernelMapFile()`函数可用来读取内核文件,`GetAddressFromFunction()`函数可用来在导出表中寻找指定函数的导出地址,本章将以此为基础实现对特定`SSDT`函数的`Hook`挂钩操作,与`《驱动开发:内核层InlineHook挂钩函数》`所使用的挂钩技术基本一致,不同点是前者使用了`CR3`的方式改写内存,而今天所讲的是通过`MDL映射`实现,此外前者挂钩中所取到的地址是通过`GetProcessAddress()`取到的动态地址,而今天所使用的方式是通过读取导出表寻找。 阅读全文
posted @ 2023-06-05 08:49 lyshark 阅读(804) 评论(2) 推荐(1)
摘要:本章将继续探索内核中解析PE文件的相关内容,PE文件中FOA与VA,RVA之间的转换也是很重要的,所谓的FOA是文件中的地址,VA则是内存装入后的虚拟地址,RVA是内存基址与当前地址的相对偏移,本章还是需要用到`《驱动开发:内核解析PE结构导出表》`中所封装的`KernelMapFile()`映射函数,在映射后对其PE格式进行相应的解析,并实现转换函数。 阅读全文
posted @ 2023-06-02 17:07 lyshark 阅读(549) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核解析PE结构导出表》`介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中`LyShark`封装实现了`KernelMapFile()`内存映射函数,在之后的章节中这个函数会被多次用到,为了减少代码冗余,后期文章只列出重要部分,读者可以自行去前面的文章中寻找特定的片段。 阅读全文
posted @ 2023-06-01 18:58 lyshark 阅读(603) 评论(0) 推荐(0)
摘要:在笔者的上一篇文章`《驱动开发:内核特征码扫描PE代码段》`中`LyShark`带大家通过封装好的`LySharkToolsUtilKernelBase`函数实现了动态获取内核模块基址,并通过`ntimage.h`头文件中提供的系列函数解析了指定内核模块的`PE节表`参数,本章将继续延申这个话题,实现对PE文件导出表的解析任务,导出表无法动态获取,解析导出表则必须读入内核模块到内存才可继续解析,所以我们需要分两步走,首先读入内核磁盘文件到内存,然后再通过`ntimage.h`中的系列函数解析即可。 阅读全文
posted @ 2023-05-31 09:10 lyshark 阅读(701) 评论(0) 推荐(0)
摘要:如前所述,在前几章内容中笔者简单介绍了`内存读写`的基本实现方式,这其中包括了`CR3切换`读写,`MDL映射`读写,`内存拷贝`读写,本章将在如前所述的读写函数进一步封装,并以此来实现驱动读写内存浮点数的目的。内存`浮点数`的读写依赖于`读写内存字节`的实现,因为浮点数本质上也可以看作是一个字节集,对于`单精度浮点数`来说这个字节集列表是4字节,而对于`双精度浮点数`,此列表长度则为8字节。 阅读全文
posted @ 2023-05-30 09:06 lyshark 阅读(1087) 评论(0) 推荐(1)
摘要:关于内存管理和分页模式,不同的操作系统和体系结构可能会有略微不同的实现方式。9-9-9-9-12的分页模式是一种常见的分页方案,其中物理地址被分成四级页表:PXE(Page Directory Pointer Table Entry)、PPE(Page Directory Entry)、PDE(Page Table Entry)和PTE(Page Table Entry)。这种分页模式可以支持大量的物理内存地址映射到虚拟内存地址空间中。每个级别的页表都负责将虚拟地址映射到更具体的物理地址。通过这种层次化的页表结构,操作系统可以更有效地管理和分配内存。 阅读全文
posted @ 2023-05-29 08:58 lyshark 阅读(1089) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核MDL读写进程内存》`简单介绍了如何通过MDL映射的方式实现进程读写操作,本章将通过如上案例实现远程进程反汇编功能,此类功能也是ARK工具中最常见的功能之一,通常此类功能的实现分为两部分,内核部分只负责读写字节集,应用层部分则配合反汇编引擎对字节集进行解码,此处我们将运用`capstone`引擎实现这个功能。 阅读全文
posted @ 2023-05-23 14:56 lyshark 阅读(804) 评论(0) 推荐(2)
摘要:在前面的文章`《驱动开发:运用MDL映射实现多次通信》`LyShark教大家使用`MDL`的方式灵活的实现了内核态多次输出结构体的效果,但是此种方法并不推荐大家使用原因很简单首先内核空间比较宝贵,其次内核里面不能分配太大且每次传出的结构体最大不能超过`1024`个,而最终这些内存由于无法得到更好的释放从而导致坏堆的产生,这样的程序显然是无法在生产环境中使用的,如下`LyShark`将教大家通过在应用层申请空间来实现同等效果,此类传递方式也是多数ARK反内核工具中最常采用的一种。 阅读全文
posted @ 2023-05-19 10:54 lyshark 阅读(682) 评论(0) 推荐(0)
摘要:在开始学习内核内存读写篇之前,我们先来实现一个简单的内存分配销毁堆的功能,在内核空间内用户依然可以动态的申请与销毁一段可控的堆空间,一般而言内核中提供了`ZwAllocateVirtualMemory`这个函数用于专门分配虚拟空间,而与之相对应的则是`ZwFreeVirtualMemory`此函数则用于销毁堆内存,当我们需要分配内核空间时往往需要切换到对端进程栈上再进行操作,接下来`LyShark`将从API开始介绍如何运用这两个函数实现内存分配与使用,并以此来作为驱动读写篇的入门知识。 阅读全文
posted @ 2023-05-15 09:21 lyshark 阅读(845) 评论(0) 推荐(1)
摘要:在前几篇文章中`LyShark`通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用`SystemBuf`缓冲区通信,运用`ReadFile`读写通信,运用`PIPE`管道通信,以及运用`ASYNC`反向通信,这些通信方式在应对`一收一发`模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当我们枚举内核模块时,往往应用层例程中可以返回几条甚至是几十条结果,如下案例所示,这对于开发一款ARK反内核工具是必须要有的功能。 阅读全文
posted @ 2023-04-29 15:13 lyshark 阅读(1150) 评论(0) 推荐(1)
摘要:本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,一般来说IO定时器是DDK中提供的一种,该定时器可以为间隔为N秒做定时,但如果要实现毫秒级别间隔,微秒级别间隔,就需要用到DPC定时器,如果是秒级定时其两者基本上无任何差异,本章将简单介绍`IO/DPC`这两种定时器的使用技巧。 阅读全文
posted @ 2023-04-04 11:19 lyshark 阅读(861) 评论(0) 推荐(0)
摘要:本章将探索驱动程序开发的基础部分,了解驱动对象`DRIVER_OBJECT`结构体的定义,一般来说驱动程序`DriverEntry`入口处都会存在这样一个驱动对象,该对象内所包含的就是当前所加载驱动自身的一些详细参数,例如驱动大小,驱动标志,驱动名,驱动节等等,每一个驱动程序都会存在这样的一个结构,首先来看一下微软对其的定义,此处我已将重要字段进行了备注。 阅读全文
posted @ 2023-04-03 20:37 lyshark 阅读(1065) 评论(5) 推荐(0)
摘要:在正式开始驱动开发之前,需要自行搭建驱动开发的必要环境,首先我们需要安装`Visual Studio 2013`这款功能强大的程序开发工具,在课件内请双击`ISO`文件并运行内部的`vs_ultimate.exe`安装包,`Visual Studio`的安装非常的简单,您只需要按照提示全部选择默认参数即可,根据机器配置不同可能需要等待一段时间; 阅读全文
posted @ 2023-03-13 14:30 lyshark 阅读(2010) 评论(2) 推荐(0)
摘要:在上一篇文章`《驱动开发:内核封装WSK网络通信接口》`中,`LyShark`已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接`Socket`和协议驱动,用于实现访问传输层的功能,该接口比`NDIS`更接近于应用层,在早期Win系统中常用于实现过滤防火墙,同样经过封装后也可实现通信功能,本章将运用TDI接口实现驱动与应用层之间传输字符串,结构体,多线程收发等技术。 阅读全文
posted @ 2022-11-03 09:47 lyshark 阅读(1055) 评论(0) 推荐(0)
摘要:本章`LyShark`将带大家学习如何在内核中使用标准的`Socket`套接字通信接口,我们都知道`Windows`应用层下可直接调用`WinSocket`来实现网络通信,但在内核模式下应用层API接口无法使用,内核模式下有一套专有的`WSK`通信接口,我们对WSK进行封装,让其与应用层调用规范保持一致,并实现内核与内核直接通过`Socket`通信的案例。 阅读全文
posted @ 2022-11-03 09:37 lyshark 阅读(1282) 评论(0) 推荐(0)
摘要:内核中的`InlineHook`函数挂钩技术其实与应用层完全一致,都是使用劫持执行流并跳转到我们自己的函数上来做处理,唯一的不同只有一个内核`Hook`只针对内核API函数,虽然只针对内核API函数实现挂钩但由于其身处在最底层所以一旦被挂钩其整个应用层都将会受到影响,这就直接决定了在内核层挂钩的效果是应用层无法比拟的,对于安全从业者来说学会使用内核挂钩也是很重要的。 阅读全文
posted @ 2022-10-31 17:11 lyshark 阅读(1311) 评论(1) 推荐(0)
摘要:本章开始`LyShark`将介绍如何在内核中实现`InlineHook`挂钩这门技术,内核挂钩的第一步需要实现一个动态计算汇编指令长度的功能,该功能可以使用`LDE64`这个反汇编引擎,该引擎小巧简单可以直接在驱动中使用,LDE引擎是`BeaEngine`引擎的一部分,后来让`BeatriX`打包成了一个`ShellCode`代码,并可以通过`typedef`动态指针的方式直接调用功能,本章内容作为后期`Hook`挂钩的铺垫部分,独立出来也是因为代码太多太占空间一篇文章写下来或很长影响阅读。 阅读全文
posted @ 2022-10-31 11:01 lyshark 阅读(1102) 评论(0) 推荐(0)
摘要:通常使用`Windows`系统自带的`任务管理器`可以正常地`结束`掉一般`进程`,而某些`特殊的`进程在应用层很难被结束掉,例如某些`系统核心进程`其权限是在`0环`内核态,但有时我们不得不想办法结束掉这些特殊的进程,当然某些正常进程在特殊状态下也会无法被正常结束,此时使用驱动前行在内核态将其结束掉就变得很有用了,驱动结束进程有多种方法。 阅读全文
posted @ 2022-10-29 10:18 lyshark 阅读(2501) 评论(0) 推荐(0)
摘要:本篇文章与上一篇文章`《驱动开发:内核注册并监控对象回调》`所使用的方式是一样的都是使用`ObRegisterCallbacks`注册回调事件,只不过上一篇博文中`LyShark`将回调结构体`OB_OPERATION_REGISTRATION`中的`ObjectType`填充为了`PsProcessType`和`PsThreadType`格式从而实现监控进程与线程,本章我们需要将该结构填充为`IoFileObjectType`以此来实现对文件的监控,文件过滤驱动不仅仅可以用来监控文件的打开,还可以用它实现对文件的保护,一旦驱动加载则文件是不可被删除和改动的。 阅读全文
posted @ 2022-10-28 09:08 lyshark 阅读(1164) 评论(0) 推荐(0)
摘要:在笔者前一篇文章`《驱动开发:内核枚举Registry注册表回调》`中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监控函数,通过这两个函数可以在不劫持内核API的前提下实现对注册表增加,删除,创建等事件的有效监控,注册表监视通常会通过`CmRegisterCallback`创建监控事件并传入自己的回调函数,与该创建对应的是`CmUnRegisterCallback`当注册表监控结束后可用于注销回调。 阅读全文
posted @ 2022-10-27 10:56 lyshark 阅读(1609) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核监视LoadImage映像回调》`中`LyShark`简单介绍了如何通过`PsSetLoadImageNotifyRoutine`函数注册回调来`监视驱动`模块的加载,注意我这里用的是`监视`而不是`监控`之所以是监视而不是监控那是因为`PsSetLoadImageNotifyRoutine`无法实现参数控制,而如果我们想要控制特定驱动的加载则需要自己做一些事情来实现,如下`LyShark`将解密如何实现屏蔽特定驱动的加载。 阅读全文
posted @ 2022-10-26 14:24 lyshark 阅读(1317) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核注册并监控对象回调》`介绍了如何运用`ObRegisterCallbacks`注册`进程与线程`回调,并通过该回调实现了`拦截`指定进行运行的效果,本章`LyShark`将带大家继续探索一个新的回调注册函数,`PsSetLoadImageNotifyRoutine`常用于注册`LoadImage`映像监视,当有模块被系统加载时则可以第一时间获取到加载模块信息,需要注意的是该回调函数内无法进行拦截,如需要拦截则需写入返回指令这部分内容将在下一章进行讲解,本章将主要实现对模块的监视功能。 阅读全文
posted @ 2022-10-25 08:00 lyshark 阅读(960) 评论(6) 推荐(0)
摘要:在笔者前面有一篇文章`《驱动开发:断链隐藏驱动程序自身》`通过摘除驱动的链表实现了断链隐藏自身的目的,但此方法恢复时会触发PG会蓝屏,偶然间在网上找到了一个作者介绍的一种方法,觉得有必要详细分析一下他是如何实现的驱动隐藏的,总体来说作者的思路是最终寻找到`MiProcessLoaderEntry`的入口地址,该函数的作用是将驱动信息加入链表和移除链表,运用这个函数即可动态处理驱动的添加和移除问题。 阅读全文
posted @ 2022-10-24 19:55 lyshark 阅读(2118) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核枚举进程与线程ObCall回调》`简单介绍了如何枚举系统中已经存在的`进程与线程`回调,本章`LyShark`将通过对象回调实现对进程线程的`句柄`监控,在内核中提供了`ObRegisterCallbacks`回调,使用这个内核`回调`函数,可注册一个`对象`回调,不过目前该函数`只能`监控进程与线程句柄操作,通过监控进程或线程句柄,可实现保护指定进程线程不被终止的目的。 阅读全文
posted @ 2022-10-24 09:07 lyshark 阅读(1378) 评论(0) 推荐(0)
摘要:在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。 阅读全文
posted @ 2022-10-23 11:05 lyshark 阅读(1353) 评论(0) 推荐(0)
摘要:微软在`x64`系统中推出了`DSE`保护机制,DSE全称`(Driver Signature Enforcement)`,该保护机制的核心就是任何驱动程序或者是第三方驱动如果想要在正常模式下被加载则必须要经过微软的认证,当驱动程序被加载到内存时会验证签名的正确性,如果签名不正常则系统会拒绝运行驱动,这种机制也被称为驱动强制签名,该机制的作用是保护系统免受恶意软件的破坏,是提高系统安全性的一种手段。 阅读全文
posted @ 2022-10-22 21:38 lyshark 阅读(1274) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核枚举Registry注册表回调》`中我们通过特征码定位实现了对注册表回调的枚举,本篇文章`LyShark`将教大家如何枚举系统中的`ProcessObCall`进程回调以及`ThreadObCall`线程回调,之所以放在一起来讲解是因为这两中回调在枚举是都需要使用通用结构体`_OB_CALLBACK`以及`_OBJECT_TYPE`所以放在一起来讲解最好不过。 阅读全文
posted @ 2022-10-22 09:51 lyshark 阅读(1044) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核枚举LoadImage映像回调》`中`LyShark`教大家实现了枚举系统回调中的`LoadImage`通知消息,本章将实现对`Registry`注册表通知消息的枚举,与`LoadImage`消息不同`Registry`消息不需要解密只要找到`CallbackListHead`消息回调链表头并解析为`_CM_NOTIFY_ENTRY`结构即可实现枚举。 阅读全文
posted @ 2022-10-21 12:54 lyshark 阅读(847) 评论(0) 推荐(0)
摘要:在笔者之前的文章`《驱动开发:内核特征码搜索函数封装》`中我们封装实现了特征码定位功能,本章将继续使用该功能,本次我们需要枚举内核`LoadImage`映像回调,在Win64环境下我们可以设置一个`LoadImage`映像加载通告回调,当有新驱动或者DLL被加载时,回调函数就会被调用从而执行我们自己的回调例程,映像回调也存储在数组里,枚举时从数组中读取值之后,需要进行位运算解密得到地址。 阅读全文
posted @ 2022-10-20 19:11 lyshark 阅读(932) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:Win10枚举完整SSDT地址表》`实现了针对`SSDT`表的枚举功能,本章继续实现对`SSSDT`表的枚举,ShadowSSDT中文名`影子系统服务描述表`,SSSDT其主要的作用是管理系统中的图形化界面,其`Win32`子系统的内核实现是`Win32k.sys`驱动,属于GUI线程的一部分,其自身没有导出表,枚举`SSSDT`表其与`SSDT`原理基本一致。 阅读全文
posted @ 2022-10-20 08:27 lyshark 阅读(960) 评论(0) 推荐(0)
摘要:在前面的博文`《驱动开发:Win10内核枚举SSDT表基址》`中已经教大家如何寻找`SSDT`表基地址了,找到后我们可根据序号获取到指定`SSDT`函数的原始地址,而如果需要输出所有`SSDT`表信息,则可以定义字符串列表,以此循环调用`GetSSDTFunctionAddress()`函数得到,当然在此之间也可以调用系统提供的`MmGetSystemRoutineAddress()`函数顺便把当前地址拿到,并通过循环方式得到完整的SSDT列表。 阅读全文
posted @ 2022-10-19 14:00 lyshark 阅读(921) 评论(0) 推荐(0)
摘要:三年前面朝黄土背朝天的我,写了一篇如何在`Windows 7`系统下枚举内核`SSDT`表的文章`《驱动开发:内核读取SSDT表基址》`三年过去了我还是个`单身狗`,开个玩笑,微软的`Windows 10`系统已经覆盖了大多数个人PC终端,以前的方法也该进行迭代更新了,或许在网上你能够找到类似的文章,但我可以百分百肯定都不能用,今天`LyShark`将带大家一起分析`Win10 x64`最新系统`SSDT`表的枚举实现。 阅读全文
posted @ 2022-10-19 10:47 lyshark 阅读(1217) 评论(0) 推荐(1)
摘要:在笔者上一篇文章`《驱动开发:内核特征码搜索函数封装》`中为了定位特征的方便我们封装实现了一个可以传入数组实现的`SearchSpecialCode`定位函数,该定位函数其实还不能算的上简单,本章`LyShark`将对特征码定位进行简化,让定位变得更简单,并运用定位代码实现扫描内核PE的`.text`代码段,并从代码段中得到某个特征所在内存位置。 阅读全文
posted @ 2022-10-18 16:59 lyshark 阅读(1221) 评论(0) 推荐(1)
摘要:Minifilter 是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的`sfilter`文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微过滤驱动使用过滤管理器`FilterManager`提供接口,由于提供了管理结构以及一系列管理API函数,所以枚举过滤驱动将变得十分容易。 阅读全文
posted @ 2022-10-18 08:22 lyshark 阅读(1716) 评论(0) 推荐(0)
摘要:在前面的系列教程如`《驱动开发:内核枚举DpcTimer定时器》`或者`《驱动开发:内核枚举IoTimer定时器》`里面`LyShark`大量使用了`特征码定位`这一方法来寻找符合条件的`汇编指令`集,总体来说这种方式只能定位特征较小的指令如果特征值扩展到5位以上那么就需要写很多无用的代码,本章内容中将重点分析,并实现一个`通用`特征定位函数。 阅读全文
posted @ 2022-10-17 11:40 lyshark 阅读(1166) 评论(0) 推荐(0)
摘要:在上一篇文章`《驱动开发:内核枚举DpcTimer定时器》`中我们通过枚举特征码的方式找到了`DPC`定时器基址并输出了内核中存在的定时器列表,本章将学习如何通过特征码定位的方式寻找`Windows 10`系统下面的`PspCidTable`内核句柄表地址。 阅读全文
posted @ 2022-10-16 16:05 lyshark 阅读(1139) 评论(0) 推荐(0)
摘要:在笔者上一篇文章`《驱动开发:内核枚举IoTimer定时器》`中我们通过`IoInitializeTimer`这个API函数为跳板,向下扫描特征码获取到了`IopTimerQueueHead`也就是IO定时器的队列头,本章学习的枚举DPC定时器依然使用特征码扫描,唯一不同的是在新版系统中DPC是被异或加密的,想要找到正确的地址,只是需要在找到DPC表头时进行解密操作即可。 阅读全文
posted @ 2022-10-16 04:50 lyshark 阅读(1182) 评论(0) 推荐(0)
摘要:在前面的博文《驱动开发:Win10内核枚举SSDT表基址》中已经教大家如何寻找SSDT表基地址了,找到后我们可根据序号获取到指定SSDT函数的原始地址,而如果需要输出所有SSDT表信息,则可以定义字符串列表,以此循环调用GetSSDTFunctionAddress()函数得到,当然在此之间也可以调用 阅读全文
posted @ 2022-10-14 13:05 lyshark 阅读(378) 评论(0) 推荐(0)
摘要:今天继续分享内核枚举系列知识,这次我们来学习如何通过代码的方式枚举内核`IoTimer`定时器,内核定时器其实就是在内核中实现的时钟,该定时器的枚举非常简单,因为在`IoInitializeTimer`初始化部分就可以找到`IopTimerQueueHead`地址,该变量内存储的就是定时器的链表头部。枚举IO定时器的案例并不多见,即便有也是无法使用过时的,此教程学到肯定就是赚到了。 阅读全文
posted @ 2022-10-14 11:24 lyshark 阅读(822) 评论(3) 推荐(0)
摘要:在上一篇文章`《驱动开发:内核中实现Dump进程转储》`中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍`VAD`结构,该结构的全程是`Virtual Address Descriptor`即`虚拟地址描述符`,VAD是一个`AVL`自`平衡二叉树`,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个`VAD`节点,由一个`MMVAD`结构完整描述。 阅读全文
posted @ 2022-10-13 13:30 lyshark 阅读(1367) 评论(0) 推荐(0)
摘要:多数ARK反内核工具中都存在驱动级别的内存转存功能,该功能可以将应用层中运行进程的内存镜像转存到特定目录下,内存转存功能在应对加壳程序的分析尤为重要,当进程在内存中解码后,我们可以很容易的将内存镜像导出,从而更好的对样本进行分析,当然某些加密壳可能无效但绝大多数情况下是可以被转存的。 阅读全文
posted @ 2022-10-11 18:34 lyshark 阅读(1186) 评论(0) 推荐(0)
摘要:在上一篇博文`《驱动开发:内核通过PEB得到进程参数》`中我们通过使用`KeStackAttachProcess`附加进程的方式得到了该进程的PEB结构信息,本篇文章同样需要使用进程附加功能,但这次我们将实现一个更加有趣的功能,在某些情况下应用层与内核层需要共享一片内存区域通过这片区域可打通内核与应用层的隔离,此类功能的实现依附于MDL内存映射机制实现。 阅读全文
posted @ 2022-10-11 11:47 lyshark 阅读(1575) 评论(2) 推荐(2)
摘要:PEB结构`(Process Envirorment Block Structure)`其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。 阅读全文
posted @ 2022-10-10 16:32 lyshark 阅读(1271) 评论(0) 推荐(0)
摘要:在上一篇文章`《驱动开发:内核取ntoskrnl模块基地址》`中我们通过调用内核API函数获取到了内核进程`ntoskrnl.exe`的基址,当在某些场景中,我们不仅需要得到内核的基地址,也需要得到特定进程内某个模块的基地址,显然上篇文章中的方法是做不到的,本篇文章将实现内核层读取32位应用层中特定进程模块基址功能。 阅读全文
posted @ 2022-10-09 14:33 lyshark 阅读(1115) 评论(0) 推荐(0)
摘要:模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程运行后加载的模块,内核模块指的是内核中特定模块地址,本篇文章将实现一个获取驱动`ntoskrnl.exe`的基地址以及长度,此功能是驱动开发中尤其是安全软件开发中必不可少的一个功能。 阅读全文
posted @ 2022-10-09 09:58 lyshark 阅读(1528) 评论(6) 推荐(0)
摘要:在驱动开发中我们有时需要得到驱动自身是否被加载成功的状态,这个功能看似没啥用实际上在某些特殊场景中还是需要的,如下代码实现了判断当前驱动是否加载成功,如果加载成功, 则输出该驱动的详细路径信息。 阅读全文
posted @ 2022-10-08 20:28 lyshark 阅读(973) 评论(0) 推荐(0)
摘要:内核中执行代码后需要将结果动态显示给应用层的用户,DeviceIoControl 是直接发送控制代码到指定的设备驱动程序,使相应的移动设备以执行相应的操作的函数,如下代码是一个经典的驱动开发模板框架,在开发经典驱动时会用到的一个通用案例。 阅读全文
posted @ 2022-10-03 20:11 lyshark 阅读(747) 评论(0) 推荐(1)
摘要:在前几篇文章中给大家具体解释了驱动与应用层之间正向通信的一些经典案例,本章将继续学习驱动通信,不过这次我们学习的是通过运用`Async`异步模式实现的反向通信,反向通信机制在开发中时常被用到,例如一个杀毒软件如果监控到有异常进程运行或有异常注册表被改写后,该驱动需要主动的通知应用层进程让其知道,这就需要用到驱动反向通信的相关知识点,如下将循序渐进的实现一个反向通信案例。 阅读全文
posted @ 2022-10-03 15:47 lyshark 阅读(1074) 评论(0) 推荐(0)
摘要:在本人前一篇博文`《驱动开发:通过ReadFile与内核层通信》`详细介绍了如何使用应用层`ReadFile`系列函数实现内核通信,本篇将继续延申这个知识点,介绍利用`PIPE`命名管道实现应用层与内核层之间的多次通信方法。 阅读全文
posted @ 2022-10-01 08:33 lyshark 阅读(1207) 评论(0) 推荐(0)
摘要:在本人前一篇博文《驱动开发:通过ReadFile与内核层通信》详细介绍了如何使用应用层ReadFile系列函数实现内核通信,本篇将继续延申这个知识点,介绍利用PIPE命名管道实现应用层与内核层之间的多次通信方法。 什么是PIPE管道? 在Windows编程中,数据重定向需要用到管道PIPE,管道是一 阅读全文
posted @ 2022-10-01 08:33 lyshark 阅读(342) 评论(0) 推荐(0)
摘要:驱动与应用程序的通信是非常有必要的,内核中执行代码后需要将其动态显示给应用层,但驱动程序与应用层毕竟不在一个地址空间内,为了实现内核与应用层数据交互则必须有通信的方法,微软为我们提供了三种通信方式,如下先来介绍通过ReadFile系列函数实现的通信模式。 阅读全文
posted @ 2022-09-30 16:23 lyshark 阅读(1165) 评论(0) 推荐(4)
摘要:在上一篇文章`《驱动开发:内核字符串转换方法》`中简单介绍了内核是如何使用字符串以及字符串之间的转换方法,本章将继续探索字符串的拷贝与比较,与应用层不同内核字符串拷贝与比较也需要使用内核专用的API函数,字符串的拷贝往往伴随有内核内存分配,我们将首先简单介绍内核如何分配堆空间,然后再以此为契机简介字符串的拷贝与比较。 阅读全文
posted @ 2022-09-29 13:21 lyshark 阅读(1355) 评论(0) 推荐(1)
摘要:在内核编程中字符串有两种格式`ANSI_STRING`与`UNICODE_STRING`,这两种格式是微软推出的安全版本的字符串结构体,也是微软推荐使用的格式,通常情况下`ANSI_STRING`代表的类型是`char *`也就是ANSI多字节模式的字符串,而`UNICODE_STRING`则代表的是`wchar*`也就是UNCODE类型的字符,如下文章将介绍这两种字符格式在内核中是如何转换的。 阅读全文
posted @ 2022-09-28 20:33 lyshark 阅读(1875) 评论(8) 推荐(0)
摘要:提到自旋锁那就必须要说链表,在上一篇`《驱动开发:内核中的链表与结构体》`文章中简单实用链表结构来存储进程信息列表,相信读者应该已经理解了内核链表的基本使用,本篇文章将讲解自旋锁的简单应用,自旋锁是为了解决内核链表读写时存在线程同步问题,解决多线程同步问题必须要用锁,通常使用自旋锁,自旋锁是内核中提供的一种高IRQL锁,用同步以及独占的方式访问某个资源。 阅读全文
posted @ 2022-09-28 10:25 lyshark 阅读(1046) 评论(0) 推荐(0)
摘要:首先CR3是什么,CR3是一个寄存器,该寄存器内保存有页目录表物理地址(PDBR地址),其实CR3内部存放的就是页目录表的内存基地址,运用CR3切换可实现对特定进程内存地址的强制读写操作,此类读写属于有痕读写,多数驱动保护都会将这个地址改为无效,此时CR3读写就失效了,当然如果能找到CR3的正确地址,此方式也是靠谱的一种读写机制。 阅读全文
posted @ 2022-09-25 11:16 lyshark 阅读(2330) 评论(1) 推荐(0)
摘要:Windows内核中是无法使用`vector`容器等数据结构的,当我们需要保存一个结构体数组时,就需要使用内核中提供的专用链表结构`LIST_ENTRY`通过一些列链表操作函数对结构体进行装入弹出等操作,如下代码是本人总结的内核中使用链表存储多个结构体的通用案例。 阅读全文
posted @ 2022-09-23 21:02 lyshark 阅读(911) 评论(0) 推荐(0)
摘要:DKOM 即直接内核对象操作,我们所有的操作都会被系统记录在内存中,而驱动进程隐藏就是操作进程的EPROCESS结构与线程的ETHREAD结构、链表,要实现进程的隐藏我们只需要将某个进程中的信息,在系统EPROCESS链表中摘除即可实现进程隐藏。 阅读全文
posted @ 2022-08-31 07:37 lyshark 阅读(471) 评论(0) 推荐(0)
摘要:在前面的博文`《驱动开发:内核读取SSDT表基址》`中已经教大家如何寻找`SSDT`表基地址了,今天给大家分享两个适用于`WinDBG`调试器上的脚本文件,该脚本文件可以很好的枚举出当前系统内的`SSDT`以及`SSSDT`表中的数据,可以方便后续文章的学习参考之用,当然脚本不是我写的,文章末尾我会给出参考原文链接。 阅读全文
posted @ 2022-04-28 09:29 lyshark 阅读(759) 评论(0) 推荐(0)
摘要:驱动程序加载工具有许多,最常用的当属`KmdManager`工具,如果驱动程序需要对外发布那我们必须自己编写实现一个驱动加载工具,当需要使用驱动时可以拉起自己的驱动,如下将实现一个简单的驱动加载工具,该工具可以实现基本的,安装,加载,关闭,卸载等操作日常使用完全没问题。 阅读全文
posted @ 2021-07-16 10:45 lyshark 阅读(1978) 评论(0) 推荐(0)
摘要:与断链隐藏进程功能类似,关于断链进程隐藏可参考`《驱动开发:DKOM 实现进程隐藏》`这一篇文章,断链隐藏驱动自身则用于隐藏自身SYS驱动文件,当驱动加载后那么使用ARK工具扫描将看不到自身驱动模块,此方法可能会触发PG会蓝屏,在某些驱动辅助中也会使用这种方法隐藏自己。 阅读全文
posted @ 2021-07-16 10:17 lyshark 阅读(972) 评论(0) 推荐(0)
摘要:内核中读写内存的方式有很多,典型的读写方式有CR3读写,MDL读写,以及今天要给大家分享的内存拷贝实现读写,拷贝读写的核心是使用`MmCopyVirtualMemory`这个内核API函数实现,通过调用该函数即可很容易的实现内存的拷贝读写。 阅读全文
posted @ 2021-07-12 17:02 lyshark 阅读(1241) 评论(0) 推荐(0)
摘要:MDL内存读写是最常用的一种读写模式,通常需要附加到指定进程空间内然后调用内存拷贝得到对端内存中的数据,在调用结束后再将其空间释放掉,通过这种方式实现内存读写操作,此种模式的读写操作也是最推荐使用的相比于CR3切换来说,此方式更稳定并不会受寄存器的影响。 阅读全文
posted @ 2021-07-05 07:25 lyshark 阅读(1606) 评论(2) 推荐(0)
摘要:监控进程的启动与退出可以使用 `PsSetCreateProcessNotifyRoutineEx` 来创建回调,当新进程产生时,回调函数会被率先执行,然后执行我们自己的`MyCreateProcessNotifyEx`函数,并在内部进行打印输出。 阅读全文
posted @ 2021-05-06 15:42 lyshark 阅读(836) 评论(0) 推荐(0)
摘要:监控进程对象和线程对象操作,可以使用`ObRegisterCallbacks`这个内核回调函数,通过回调我们可以实现保护calc.exe进程不被关闭,具体操作从`OperationInformation->Object`获得进程或线程的对象,然后再回调中判断是否是计算器,如果是就直接去掉`TERMINATE_PROCESS`或`TERMINATE_THREAD`权限即可。 阅读全文
posted @ 2020-06-14 19:59 lyshark 阅读(645) 评论(0) 推荐(0)
摘要:Windbg是Microsoft公司免费调试器调试集合中的GUI的调试器,支持Source和Assembly两种模式的调试。Windbg不仅可以调试应用程序,还可以进行Kernel Debug。结合Microsoft的Symbol Server,可以获取系统符号文件,便于应用程序和内核的调试。Windbg支持的平台包括X86、IA64、AMD64。 阅读全文
posted @ 2020-06-10 15:55 lyshark 阅读(1639) 评论(0) 推荐(0)
摘要:内核层与应用层之间的数据交互是必不可少的部分,只有内核中的参数可以传递给用户数据才有意义,一般驱动多数情况下会使用`SystemBuf`缓冲区进行通信,也可以直接使用网络套接字实现通信,如下将简单介绍通过SystemBuf实现的内核层与应用层通信机制。 阅读全文
posted @ 2020-04-13 10:06 lyshark 阅读(6031) 评论(1) 推荐(9)
摘要:无论在用户层还是内核层,操作文件的流程基本一致,除了在API函数上的区别(用户层调用用户层API,内核层调用内核API)以外其他基本一致,先讲解一下文件系统执行的流程。实现文件的监控呢,比如当文件被访问时自动触发回调,看如下代码实现方式。 阅读全文
posted @ 2019-11-01 14:53 lyshark 阅读(1416) 评论(0) 推荐(0)
摘要:内核枚举进程使用`PspCidTable` 这个未公开的函数,它能最大的好处是能得到进程的EPROCESS地址,由于是未公开的函数,所以我们需要变相的调用这个函数,通过`PsLookupProcessByProcessId`函数查到进程的EPROCESS,如果`PsLookupProcessByProcessId`返回失败,则证明此进程不存在,如果返回成功则把EPROCESS、PID、PPID、进程名等通过DbgPrint打印到屏幕上。 阅读全文
posted @ 2019-10-21 07:50 lyshark 阅读(4247) 评论(0) 推荐(0)
摘要:DKOM 就是直接内核对象操作技术,我们所有的操作都会被系统记录在内存中,而驱动进程隐藏的做旧就是操作进程的EPROCESS结构与线程的ETHREAD结构、链表,要实现进程的隐藏我们只需要将某个进程中的信息,在系统EPROCESS链表中摘除即可实现进程隐藏。 DKOM 隐藏进程的本质是操作EPROCESS结构体,EPROCESS结构体中包含了系统中的所有进程相关信息,还有很多指向其他结构的指针,首先我们可以通过WinDBG在内核调试模式下输入`dt_eprocess` 即可查看到当前的EPROCESS结构体的偏移信息,结构较多,但常用的就下面这几个。 阅读全文
posted @ 2019-10-11 14:38 lyshark 阅读(3891) 评论(0) 推荐(1)
摘要:在前面的章节`《X86驱动:挂接SSDT内核钩子》`我们通过代码的方式直接读取 `KeServiceDescriptorTable` 这个被导出的表结构从而可以直接读取到SSDT表的基址,而在Win64系统中 `KeServiceDescriptorTable` 这个表并没有被导出,所以我们必须手动搜索到它的地址。 阅读全文
posted @ 2019-10-09 09:23 lyshark 阅读(2485) 评论(0) 推荐(0)
摘要:驱动程序与应用程序的通信离不开派遣函数,派遣函数是Windows驱动编程中的重要概念,一般情况下驱动程序负责处理I/O特权请求,而大部分IO的处理请求是在派遣函数中处理的,当用户请求数据时,操作系统会提前处理好请求,并将其派遣到指定的内核函数中执行,接下来将详细说明派遣函数的使用并通过派遣函数读取Shadow SSDT中的内容。 阅读全文
posted @ 2019-09-23 09:05 lyshark 阅读(4410) 评论(0) 推荐(0)
摘要:SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基址、服务函数个数等,SSDT 通过修改此表的函数地址可以对常用 Windows 函数进行内核级的Hook,从而实现对一些核心的系统动作进行过滤、监控的目的。 阅读全文
posted @ 2019-09-21 17:21 lyshark 阅读(1954) 评论(0) 推荐(0)
摘要:SSDT 中文名称为系统服务描述符表,该表的作用是将Ring3应用层与Ring0内核层,两者的API函数连接起来,起到承上启下的作用,SSDT并不仅仅只包含一个庞大的地址索引表,它还包含着一些其它有用的信息,诸如地址索引的基址、服务函数个数等,SSDT 通过修改此表的函数地址可以对常用 Windows 函数进行内核级的Hook,从而实现对一些核心的系统动作进行过滤、监控的目的,接下来将演示如何通过编写简单的驱动程序,来实现搜索 SSDT 函数的地址,并能够实现简单的内核 Hook 挂钩。 阅读全文
posted @ 2019-09-20 17:57 lyshark 阅读(2199) 评论(0) 推荐(0)
摘要:WinDBG 是在`windows`平台下,强大的用户态和内核态调试工具,相比较于`Visual Studio`它是一个轻量级的调试工具,所谓轻量级指的是它的安装文件大小较小,但是其调试功能却比VS更为强大,WinDBG由于是微软的产品所以能够调试`Windows`系统的内核,另外一个用途是可以用来分析`dump`数据,本笔记用于记录如何开启`Windows`系统内核调试功能,并使用`WinDBG`调试驱动。 阅读全文
posted @ 2019-09-19 10:09 lyshark 阅读(3612) 评论(0) 推荐(0)
摘要:Windows Driver Kit 是一种完全集成的驱动程序开发工具包,它包含 WinDDK 用于测试 Windows 驱动器的可靠性和稳定性,本次实验使用的是 WDK8.1 驱动开发工具包,该工具包支持 Windows 7到 Windows 10 系统的驱动开发。VS2013+WDK8.1 驱动开发环境的搭建我研究了很长时间今天总算搭建出来了,而且中途没有错误,这里就把搭建过程分享出来。 阅读全文
posted @ 2019-09-18 10:01 lyshark 阅读(6692) 评论(3) 推荐(1)
摘要:驱动中的默认派遣函数,通过`IRP_MJ_MAXIMUM_FUNCTION`得到所有的派遣函数,并初始化为`DriverDefaultHandle`默认派遣,以及驱动中创建设备对象的基础知识总结。 阅读全文
posted @ 2019-09-14 12:21 lyshark


loading... | loading...
博客园 - 开发者的网上家园