在笔者上一篇文章`《驱动开发:内核注册并监控对象回调》`介绍了如何运用`ObRegisterCallbacks`注册`进程与线程`回调,并通过该回调实现了`拦截`指定进行运行的效果,本章`LyShark`将带大家继续探索一个新的回调注册函数,`PsSetLoadImageNotifyRoutine`常用于注册`LoadImage`映像监视,当有模块被系统加载时则可以第一时间获取到加载模块信息,需要
在笔者上一篇文章`《驱动开发:内核监视LoadImage映像回调》`中`LyShark`简单介绍了如何通过`PsSetLoadImageNotifyRoutine`函数注册回调来`监视驱动`模块的加载,注意我这里用的是`监视`而不是`监控`之所以是监视而不是监控那是因为`PsSetLoadImageNotifyRoutine`无法实现参数控制,而如果我们想要控制特定驱动的加载则需要自己做一些事情来
在笔者前一篇文章`《驱动开发:内核枚举Registry注册表回调》`中实现了对注册表的枚举,本章将实现对注册表的监控,不同于32位系统在64位系统中,微软为我们提供了两个针对注册表的专用内核监控函数,通过这两个函数可以在不劫持内核API的前提下实现对注册表增加,删除,创建等事件的有效监控,注册表监视通常会通过`CmRegisterCallback`创建监控事件并传入自己的回调函数,与该创建对应的是
本篇文章与上一篇文章`《驱动开发:内核注册并监控对象回调》`所使用的方式是一样的都是使用`ObRegisterCallbacks`注册回调事件,只不过上一篇博文中`LyShark`将回调结构体`OB_OPERATION_REGISTRATION`中的`ObjectType`填充为了`PsProcessType`和`PsThreadType`格式从而实现监控进程与线程,本章我们需要将该结构填充为`I
通常使用`Windows`系统自带的`任务管理器`可以正常地`结束`掉一般`进程`,而某些`特殊的`进程在应用层很难被结束掉,例如某些`系统核心进程`其权限是在`0环`内核态,但有时我们不得不想办法结束掉这些特殊的进程,当然某些正常进程在特殊状态下也会无法被正常结束,此时使用驱动前行在内核态将其结束掉就变得很有用了,驱动结束进程有多种方法。
本章开始`LyShark`将介绍如何在内核中实现`InlineHook`挂钩这门技术,内核挂钩的第一步需要实现一个动态计算汇编指令长度的功能,该功能可以使用`LDE64`这个反汇编引擎,该引擎小巧简单可以直接在驱动中使用,LDE引擎是`BeaEngine`引擎的一部分,后来让`BeatriX`打包成了一个`ShellCode`代码,并可以通过`typedef`动态指针的方式直接调用功能,本章内容作
内核中的`InlineHook`函数挂钩技术其实与应用层完全一致,都是使用劫持执行流并跳转到我们自己的函数上来做处理,唯一的不同只有一个内核`Hook`只针对内核API函数,虽然只针对内核API函数实现挂钩但由于其身处在最底层所以一旦被挂钩其整个应用层都将会受到影响,这就直接决定了在内核层挂钩的效果是应用层无法比拟的,对于安全从业者来说学会使用内核挂钩也是很重要的。
本章`LyShark`将带大家学习如何在内核中使用标准的`Socket`套接字通信接口,我们都知道`Windows`应用层下可直接调用`WinSocket`来实现网络通信,但在内核模式下应用层API接口无法使用,内核模式下有一套专有的`WSK`通信接口,我们对WSK进行封装,让其与应用层调用规范保持一致,并实现内核与内核直接通过`Socket`通信的案例。
在上一篇文章`《驱动开发:内核封装WSK网络通信接口》`中,`LyShark`已经带大家看过了如何通过WSK接口实现套接字通信,但WSK实现的通信是内核与内核模块之间的,而如果需要内核与应用层之间通信则使用TDK会更好一些因为它更接近应用层,本章将使用TDK实现,TDI全称传输驱动接口,其主要负责连接`Socket`和协议驱动,用于实现访问传输层的功能,该接口比`NDIS`更接近于应用层,在早期W
操作系统是用来管理与协调硬件工作的,开发一款操作系统有利于理解底层的运转逻辑,本篇内容主要用来理解操作系统是如何启动的,又是如何加载磁盘中的内核的,该系列文章参考各类底层书籍,通过自己的理解并加以叙述,让内容变得更加简单,一目了然,即可学到知识又能提高自己的表述能力。 注释: 该系列笔记是在学习《操
目前我们已进入保护模式,但依然会受到限制,虽然地址空间达到了4GB,但此空间是包括操作系统共享的4GB空间,我们把段基址+段内偏移地址称为线性地址,线性地址是唯一的,只属于某一个进程。在我们机器上即使只有512MB的内存,每个进程自己的内存空间也是4GB,这是指的虚拟内存空间。一直以来我们都是在内存
这里在实验之前需要下载 Bochs-win32-2.6.11 作者使用的是Linux版本的,在Linux写代码不太舒服,所以最好在Windows上做实验,下载好虚拟机以后还需要下载Nasm汇编器,以及GCC编译器,为了能够使用DD命令实现磁盘拷贝,这里你可以安装windows 10 下面的子系统Ub
在正式开始驱动开发之前,需要自行搭建驱动开发的必要环境,首先我们需要安装`Visual Studio 2013`这款功能强大的程序开发工具,在课件内请双击`ISO`文件并运行内部的`vs_ultimate.exe`安装包,`Visual Studio`的安装非常的简单,您只需要按照提示全部选择默认参数即可,根据机器配置不同可能需要等待一段时间;
本章将探索驱动程序开发的基础部分,了解驱动对象`DRIVER_OBJECT`结构体的定义,一般来说驱动程序`DriverEntry`入口处都会存在这样一个驱动对象,该对象内所包含的就是当前所加载驱动自身的一些详细参数,例如驱动大小,驱动标志,驱动名,驱动节等等,每一个驱动程序都会存在这样的一个结构,首先来看一下微软对其的定义,此处我已将重要字段进行了备注。
本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,一般来说IO定时器是DDK中提供的一种,该定时器可以为间隔为N秒做定时,但如果要实现毫秒级别间隔,微秒级别间隔,就需要用到DPC定时器,如果是秒级定时其两者基本上无任何差异,本章将简单介绍`IO/DPC`这两种定时器的使用技巧。
在前几篇文章中`LyShark`通过多种方式实现了驱动程序与应用层之间的通信,这其中就包括了通过运用`SystemBuf`缓冲区通信,运用`ReadFile`读写通信,运用`PIPE`管道通信,以及运用`ASYNC`反向通信,这些通信方式在应对`一收一发`模式的时候效率极高,但往往我们需要实现一次性吐出多种数据,例如ARK工具中当我们枚举内核模块时,往往应用层例程中可以返回几条甚至是几十条结果,如
在开始学习内核内存读写篇之前,我们先来实现一个简单的内存分配销毁堆的功能,在内核空间内用户依然可以动态的申请与销毁一段可控的堆空间,一般而言内核中提供了`ZwAllocateVirtualMemory`这个函数用于专门分配虚拟空间,而与之相对应的则是`ZwFreeVirtualMemory`此函数则用于销毁堆内存,当我们需要分配内核空间时往往需要切换到对端进程栈上再进行操作,接下来`LyShark
在前面的文章`《驱动开发:运用MDL映射实现多次通信》`LyShark教大家使用`MDL`的方式灵活的实现了内核态多次输出结构体的效果,但是此种方法并不推荐大家使用原因很简单首先内核空间比较宝贵,其次内核里面不能分配太大且每次传出的结构体最大不能超过`1024`个,而最终这些内存由于无法得到更好的释放从而导致坏堆的产生,这样的程序显然是无法在生产环境中使用的,如下`LyShark`将教大家通过在应
在笔者上一篇文章`《驱动开发:内核MDL读写进程内存》`简单介绍了如何通过MDL映射的方式实现进程读写操作,本章将通过如上案例实现远程进程反汇编功能,此类功能也是ARK工具中最常见的功能之一,通常此类功能的实现分为两部分,内核部分只负责读写字节集,应用层部分则配合反汇编引擎对字节集进行解码,此处我们将运用`capstone`引擎实现这个功能。
关于内存管理和分页模式,不同的操作系统和体系结构可能会有略微不同的实现方式。9-9-9-9-12的分页模式是一种常见的分页方案,其中物理地址被分成四级页表:PXE(Page Directory Pointer Table Entry)、PPE(Page Directory Entry)、PDE(Page Table Entry)和PTE(Page Table Entry)。这种分页模式可以支持大量