随笔分类 - 《灰帽黑客:攻守道》
摘要:在笔者上一篇文章`《内核RIP劫持实现DLL注入》`介绍了通过劫持RIP指针控制程序执行流实现插入DLL的目的,本章将继续探索全新的注入方式,通过`NtCreateThreadEx`这个内核函数实现注入DLL的目的,需要注意的是该函数在微软系统中未被导出使用时需要首先得到该函数的入口地址,`NtCreateThreadEx`函数最终会调用`ZwCreateThread`,本章在寻找函数的方式上有所不同,前一章通过内存定位的方法得到所需地址,本章则是通过解析导出表实现。
阅读全文
摘要:本章将继续探索内核中解析PE文件的相关内容,PE文件中FOA与VA,RVA之间的转换也是很重要的,所谓的FOA是文件中的地址,VA则是内存装入后的虚拟地址,RVA是内存基址与当前地址的相对偏移,本章还是需要用到`《内核解析PE结构导出表》`中所封装的`KernelMapFile()`映射函数,在映射后对其PE格式进行相应的解析,并实现转换函数。
阅读全文
摘要:在笔者上一篇文章`《内核解析PE结构导出表》`介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中`LyShark`封装实现了`KernelMapFile()`内存映射函数,在之后的章节中这个函数会被多次用到,为了减少代码冗余,后期文章只列出重要部分,读者可以自行去前面的文章中寻找特定的片段。PE结构(Portable Executable Structure)是Windows操作系统用于执行可执行文件和动态链接库(DLL)的标准格式。节表(Section Table)是PE结构中的一个部分,它记录了可执行文件或DLL中每个区域的详细信息,例如代码、数据、资源等。
阅读全文
摘要:在笔者的上一篇文章`《内核特征码扫描PE代码段》`中`LyShark`带大家通过封装好的`LySharkToolsUtilKernelBase`函数实现了动态获取内核模块基址,并通过`ntimage.h`头文件中提供的系列函数解析了指定内核模块的`PE节表`参数,本章将继续延申这个话题,实现对PE文件导出表的解析任务,导出表无法动态获取,解析导出表则必须读入内核模块到内存才可继续解析,所以我们需要分两步走,首先读入内核磁盘文件到内存,然后再通过`ntimage.h`中的系列函数解析即可。
阅读全文
摘要:PEB结构`(Process Envirorment Block Structure)`其中文名是进程环境块信息,进程环境块内部包含了进程运行的详细参数信息,每一个进程在运行后都会存在一个特有的PEB结构,通过附加进程并遍历这段结构即可得到非常多的有用信息。在应用层下,如果想要得到PEB的基地址只需要取`fs:[0x30]`即可,TEB线程环境块则是`fs:[0x18]`,如果在内核层想要得到应用层进程的PEB信息我们需要调用特定的内核函数来获取。
阅读全文
摘要:在上一篇文章`《内核取ntoskrnl模块基地址》`中我们通过调用内核API函数获取到了内核进程`ntoskrnl.exe`的基址,当在某些场景中,我们不仅需要得到内核的基地址,也需要得到特定进程内某个模块的基地址,显然上篇文章中的方法是做不到的,本篇文章将实现内核层读取32位应用层中特定进程模块基址功能。上一篇文章中的`PPEB32,PLIST_ENTRY32`等结构体定义依然需要保留,此处只保留核心代码,定义部分请看前一篇文章,自定义读取模块基址核心代码如下,调用`GetModuleBaseWow64()`用户需传入进程的`PROCESS`结构该结构可通过内核函数`PsLookupProcessByProcessId`获取到。
阅读全文
摘要:模块是程序加载时被动态装载的,模块在装载后其存在于内存中同样存在一个内存基址,当我们需要操作这个模块时,通常第一步就是要得到该模块的内存基址,模块分为用户模块和内核模块,这里的用户模块指的是应用层进程运行后加载的模块,内核模块指的是内核中特定模块地址,本篇文章将实现一个获取驱动`ntoskrnl.exe`的基地址以及长度,此功能是驱动开发中尤其是安全软件开发中必不可少的一个功能。关于该程序的解释,官方的解析是这样的`ntoskrnl.exe`是`Windows`操作系统的一个重要内核程序,里面存储了大量的二进制内核代码,用于调度系统时使用,也是操作系统启动后第一个被加载的程序,通常该进程在任务管理器中显示为`System`。
阅读全文
摘要:在前面的文章中`LyShark`一直在重复的实现对系统底层模块的枚举,今天我们将展开一个新的话题,内核监控,我们以`监控进程线程`创建为例,在`Win10`系统中监控进程与线程可以使用微软提供给我们的两个新函数来实现,此类函数的原理是创建一个回调事件,当有进程或线程被创建或者注销时,系统会通过回调机制将该进程相关信息优先返回给我们自己的函数待处理结束后再转向系统层。
阅读全文
摘要:在笔者前一篇文章`《内核文件读写系列函数》`简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于`ZwQueryDirectoryFile`这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在`PFILE_BOTH_DIR_INFORMATION`结构下,通过遍历该目录即可获取到文件的详细参数,如下将具体分析并实现遍历目录功能。
阅读全文
摘要:在某些时候我们的系统中会出现一些无法被正常删除的文件,如果想要强制删除则需要在驱动层面对其进行解锁后才可删掉,而所谓的解锁其实就是释放掉文件描述符(句柄表)占用,文件解锁的核心原理是通过调用`ObSetHandleAttributes`函数将特定句柄设置为可关闭状态,然后在调用`ZwClose`将其文件关闭,强制删除则是通过`ObReferenceObjectByHandle`在对象上提供相应的权限后直接调用`ZwDeleteFile`将其删除。
阅读全文
摘要:监视对指定目录的更改,并将有关更改的信息打印到控制台,该功能的实现不仅可以在内核层,在应用层同样可以。程序中使用`ReadDirectoryChangesW`函数来监视目录中的更改,并使用`FILE_NOTIFY_INFORMATION`结构来获取有关更改的信息。ReadDirectoryChangesW 是`Windows`操作系统提供的一个函数,用于监视目录的变化。它属于`Windows API`的一部分,主要用于监视文件系统中目录的修改、新增、删除等变化,并通过回调函数向应用程序提供通知。
阅读全文
摘要:11.9.1 遍历磁盘容量 如下代码实现了在Windows系统中获取所有磁盘驱动器的信息。具体包括两个函数,一个用于获取驱动器类型,另一个用于获取驱动器空间信息。主函数则调用这两个函数来遍历所有逻辑驱动器并输出相应的信息。在输出驱动器空间信息时,会输出该驱动器的总大小、已用空间以及可用空间。 #in
阅读全文
摘要:11.8.1 切割文件名与路径 如下代码是一段文件路径切割实现,通过传入文件路径,获取文件名和文件路径的功能。具体实现包括两个函数:GetFileName和GetFilePath。前者接收一个文件路径字符串,并返回该文件路径中的文件名;后者接收一个文件路径字符串,并返回该文件路径中除文件名以外的部分
阅读全文
摘要:注册表是Windows中的一个重要的数据库,用于存储系统和应用程序的设置信息,注册表是一个巨大的树形结构,无论在应用层还是内核层操作注册表都有独立的API函数可以使用,而在内核中读写注册表则需要使用内核装用API函数,如下将依次介绍并封装一些案例,实现对注册表的创建,删除,更新,查询等操作。在Windows内核中,注册表是一种存储系统配置信息的机制,包括应用程序、硬件、驱动程序和操作系统的各种设置。内核提供了一些API函数,可以让驱动程序通过代码访问和修改注册表,以实现系统的配置和管理。下面简单介绍一下内核中的注册表增删改查操作:
阅读全文
摘要:在应用层下的文件操作只需要调用微软应用层下的`API`函数及`C库`标准函数即可,而如果在内核中读写文件则应用层的API显然是无法被使用的,内核层需要使用内核专有API,某些应用层下的API只需要增加Zw开头即可在内核中使用,例如本章要讲解的文件与目录操作相关函数,多数ARK反内核工具都具有对文件的管理功能,实现对文件或目录的基本操作功能也是非常有必要的。
阅读全文
摘要:在编程中,针对磁盘与目录的操作也是非常重要的,本章将重点介绍如何实现针对文件目录与磁盘的操作方法,其中包括了删除文件,文件拷贝,文件读写,目录遍历输出,遍历磁盘容量信息,磁盘格式化,输出分区表数据,监控目录变化等。
阅读全文
摘要:在上一篇文章`《内核中实现Dump进程转储》`中我们实现了ARK工具的转存功能,本篇文章继续以内存为出发点介绍`VAD`结构,该结构的全程是`Virtual Address Descriptor`即`虚拟地址描述符`,VAD是一个`AVL`自`平衡二叉树`,树的每一个节点代表一段虚拟地址空间。程序中的代码段,数据段,堆段都会各种占用一个或多个`VAD`节点,由一个`MMVAD`结构完整描述。
阅读全文
摘要:多数ARK反内核工具中都存在驱动级别的内存转存功能,该功能可以将应用层中运行进程的内存镜像转存到特定目录下,内存转存功能在应对加壳程序的分析尤为重要,当进程在内存中解码后,我们可以很容易的将内存镜像导出,从而更好的对样本进行分析,当然某些加密壳可能无效但绝大多数情况下是可以被转存的。
阅读全文
摘要:当你需要在Windows操作系统中监控进程的启动和退出时,可以使用`PsSetCreateProcessNotifyRoutineEx`函数来创建一个`MyCreateProcessNotifyEx`回调函数,该回调函数将在每个进程的创建和退出时被调用。
阅读全文
摘要:在内核中,可以使用`ObRegisterCallbacks`这个内核回调函数来实现监控进程和线程对象操作。通过注册一个`OB_CALLBACK_REGISTRATION`回调结构体,可以指定所需的回调函数和回调的监控类型。这个回调结构体包含了回调函数和监控的对象类型,还有一个`Altitude`字段,用于指定回调函数的优先级。优先级越高的回调函数会先被调用,如果某个回调函数返回了一个非NULL值,后续的回调函数就不会被调用。当有进程或线程对象创建、删除、复制或重命名时,内核会调用注册的回调函数。回调函数可以访问被监控对象的信息,如句柄、进程ID等,并可以采取相应的操作,如打印日志、记录信息等。
阅读全文