Windows x64内核(5)——过滤驱动
过滤驱动代码例子来源: Win驱动9]Windows分层驱动_windows分层驱动程序 数据-CSDN博客
过滤驱动是一种独立的驱动程序,直接插入内核驱动栈中,拦截并处理驱动程序之间的数据传输。它可以拦截底层的I/O请求,并在不改变原始请求的情况下,修改、延迟或直接处理这些请求。
过滤驱动:位于设备驱动程序堆栈的上层,负责拦截、修改和处理 I/O 请求或响应,并可能将其转发给目标驱动。
目标驱动:位于设备驱动程序堆栈的下层,直接与硬件交互,处理实际的 I/O 操作。
和注册回调的区别:过滤驱动运行在内核模式下的驱动栈中,拦截并处理I/O请求;回调函数则在某些事件发生时被内核或应用调用,可能在用户模式或内核模式下运行。过滤驱动可以拦截设备级的I/O请求(如文件读写、网络包),而回调函数通常处理系统事件(如进程创建、线程创建、加载模块等)。过滤驱动适合用于文件系统、网络、设备的深度控制和拦截;回调函数则用于监控和响应特定的系统事件,例如进程管理、内存分配等。
最重要的是:这玩意贼稳定,受微软支持的,想附加就附加
当请求完成的时候,会 ...
Windows x64内核(4)——回调函数
Windows x64内核x64内核的回调函数因为x64再想要去Hook例如各种门,SSDT表之类的重要数据结构变得异常困难
为了在内核模式下提供合法的扩展和拦截机制,微软提供了许多回调函数,这些回调允许驱动开发者在特定事件发生时执行自定义代码,而不必直接修改关键的内核数据结构。
还有一点,如果没有加载数字签名,调用以下API可能会报错,我们需要在编译选项加一些东西:/INTEGRITYCHECK
进程监控
API: PsSetCreateProcessNotifyRoutine / PsSetCreateProcessNotifyRoutineEx
描述:
PsSetCreateProcessNotifyRoutine:注册一个回调函数,当进程创建或终止时,系统会调用此回调函数。该函数已被PsSetCreateProcessNotifyRoutineEx替代。
PsSetCreateProcessNotifyRoutineEx:与前者类似,但提供了更多信息,如父进程ID、命令行参数等。
具体代码,用于检测任何进程的创建与卸载
12345678910111213 ...
Windows x64内核(3)——分页机制
Windows x64内核9-9-9-9-12分页机制介绍之前我们学过的x86用的是2-9-9-12和10-10-12的分页机制
x64下,分页大小有4K,2M,1G的大小
如果PDE的PS位为0,则为4K,为1则为2M
如果PDPTE 的PS=1的话,指向 1GB 页
x64下,4k分页变成了9-9-9-9-12的分页机制
虽然64位下的地址有64位,但是实际用到的只有48位,这主要因为以下原因:
当前需求有限:
管理复杂度:
使用完整的 64 位地址空间将引入极大的管理和硬件复杂性。
页表大小和效率:
使用四级页表(9-9-9-9-12 分级结构)能够有效管理 48 位的虚拟地址空间。使用更多位数意味着增加页表层级,可能需要五级或更多级页表,这会带来额外的内存和性能开销。当前四级页表架构已经能够高效地处理 48 位地址,而无需增加复杂性。
我们来依次解析下每一个数字的含义:
PML4(Page Map Level 4):页目录指针表
在windows叫PXE
最高的页表层级,用 9 位来索引 PML4 表项。PML4 表最多可以有 512 个条 ...
Windows x64内核(2)——天堂之门
Windows x64内核天堂之门简介在x86-64 架构中,有一个特殊的机制可以让 CPU 在 64 位模式和 32 位模式之间进行切换。Heaven's Gate 就是利用这个机制,在 32 位环境下进入 64 位模式,从而执行 64 位代码并调用 64 位 API。
在长模式下(即 64 位处理器启用 64 位功能时),段选择子可以用来确定 CPU 运行在 64 位模式还是兼容模式。 (具体是CS段寄存器的L位,设置为1就是64位模式)
通过以下代码,32位程序可以转而执行64位汇编代码
123push 0x33 ; 将 64 位代码段选择子压入堆栈push 64bit_address ; 压入 64 位模式下要执行的代码地址retf ; 远返回,切换到 64 位模式
实战一波具体我们实验一下
1234567891011121314151617181920212223242526272829#include <windows.h>#include <iostream>using ...
win x64内核(1)——x64内核与x86的一些区别
Windows x64内核x64下的分段机制
前情回顾:
1. GDT(全局描述符表)
分段机制: GDT是分段机制的核心部分。它定义了系统中所有的段描述符,供处理器在保护模式下使用。GDT中的描述符用于定义代码段、数据段以及系统段的基地址、段限长、访问权限等。
功能:
代码段和数据段: GDT包含代码段(代码段描述符)和数据段(数据段描述符)的定义,描述段的起始地址、段限长、段的特权级(DPL,Descriptor Privilege Level)、段类型等。
系统段: 包括TSS(任务状态段)、LDT(局部描述符表)等的描述符,用于任务切换和其他系统级功能。
2. LDT(局部描述符表)
分段机制: LDT也是分段机制的一部分,但它是GDT的一个补充。LDT允许每个进程或任务有自己独立的段描述符表,从而支持每个进程或任务使用不同的段设置。
功能:
局部描述符: LDT提供了局部段描述符,用于定义特定于某个任务或进程的代码段和数据段。每个LDT包含的描述符范围仅限于该LDT,而不是整个系统。
任务隔离: 通过使用LDT,操作系统可以实现任务间的段隔离,允许不同任务使用不同的段配 ...
MFC逆向分析(找消息处理函数)
MFC事件逆向分析选用测试软件:家庭账本3.5.9
相较于Win32窗口编程,拿到消息后可以在消息处理回调函数里面寻找对应的消息处理函数不同
MFC程序的运行常常令我摸不着头脑,有时候根本就不知道如何去找到对应的处理函数,例如按钮事件的事件处理函数。
最近遇到一些MFC的ctf题目和一些MFC写的软件想要尝试破解,但是无奈按钮事件非常难找,一旦字符串加密或者没有弹窗,很难去找到对应函数体
所以特地花了很多事件去整理了下MFC程序应该如何去逆向
这篇文章前面会讲理论,后边会结合实际逆向分析例子。
MFC消息映射机制在 Windows 编程中,窗口与系统、用户交互主要是通过消息传递的。每个窗口都有一个消息队列,系统通过向消息队列发送消息来通知窗口事件(如鼠标点击、键盘输入、窗口重绘等)。MFC 消息映射机制使得处理这些消息变得更加结构化和便捷。
MFC 中,每个支持消息映射的类都必须使用 DECLARE_MESSAGE_MAP 宏(在类声明中)和 BEGIN_MESSAGE_MAP、END_MESSAGE_MAP 宏(在类实现中)来定义消息映射。
DECLARE_MESSAGE_MAP ...
Windows内核(16)——探究SSDT
Windows内核探究SSDTSSDT简介在Windows x86系统中,系统服务描述表(System Service Descriptor Table,简称SSDT)是一个核心数据结构,主要用于管理和调度系统调用(syscall)。SSDT在操作系统的内核模式下提供了一种机制,使得用户模式的应用程序能够请求内核模式服务,比如文件操作、进程管理、内存管理等。以下是SSDT的主要作用:
系统调用接口SSDT充当了用户模式应用程序与操作系统内核之间的桥梁。应用程序通过调用标准的Windows API(如ReadFile、WriteFile等),这些API最终会通过系统调用的方式进入内核模式。SSDT中包含了一组函数指针,这些指针指向具体的内核服务例程。每个系统调用在SSDT中都有对应的入口,通过这些入口可以找到实现该调用的内核函数。
系统调用号到函数指针的映射每个系统调用在SSDT中都有一个唯一的索引号(系统调用号)。当应用程序发出系统调用时,会使用该调用的系统调用号在SSDT中查找对应的内核服务例程的地址。然后,系统将控制权转移给这个地址处的服务例程来执行实际的操作。例如,通过sysc ...
Windows内核(15)——键盘Hook,调用门
Windwos内核通过IDT Hook键盘IRETD(Interrupt Return Double-word)是 x86 架构中的一条汇编指令,用于从中断或异常处理程序中返回到调用程序。
当一个中断或异常发生时,CPU 会将当前的 EFLAGS 寄存器、CS(代码段)寄存器和 EIP(指令指针)压入堆栈,并跳转到中断处理程序的入口地址。
当中断处理程序完成时,IRETD 指令会从堆栈中弹出这些值并恢复它们,返回到中断发生前的状态。
当你 Hook 一个中断函数时,通常会使用“裸函数”(Naked Function),这是因为中断处理程序具有特殊的要求,不允许编译器在函数的入口和退出时自动插入额外的代码。这些额外的代码可能包括保存和恢复寄存器、设置堆栈帧等常规操作。为了确保中断处理程序的行为符合预期,裸函数就显得非常重要。
12345678910111213141516__declspec(naked) void KeyboardProc(){ __asm{ pushad pushf } //写入代码 ...
Windows内核(14)——补笔记
Windows内核(补笔记)在高两G空间里面,FS段选择子经过变换后指向的是 _KPCR(系统内核数据结构)
在低两G空间里面,FS段选择子经过变换后指向的是_TEB
MmGetPhysicalAddress的作用: 用于将虚拟地址转换为物理地址。在Windows操作系统中,内核代码可以通过这个函数来获取对应于某个虚拟地址的物理地址。MmMapIoSpace的作用:于将物理地址范围映射到内核虚拟地址空间,从而使内核模式代码可以访问该物理地址范围。
完善交换内存的代码以及优化完成下面的代码:
以下代码存在问题,就是如果被交换到磁盘,就有可能会映射失败
下面是改进的代码
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495NTSTATUS DriverEntry(IN PDRIVER ...
FPS矩阵原理
FPS矩阵原理参考文章: FPS通用的方框透视公式的原理_fps透视原理-CSDN博客
FPS游戏方框透视基本原理_fps 透视矩阵算法-CSDN博客
之前我们做的非矩阵画线,位置不准确,还很难进行缩放
但是下图是矩阵的效果,看上去就非常的好
游戏坐标转换原理:游戏中通过建模完成的3D物体要想在2D屏幕上显示出来需要进行坐标的转换。
具体过程看 FPS游戏方框透视基本原理_fps 透视矩阵算法-CSDN博客 吧(看得我十分头大,不过我们只需要大概了解即可)
按照上面的原理,我们只要找到人物在世界坐标系中的坐标 (x1,y1,z1) ,就可以在屏幕上画出人物边框
第一步:世界坐标 -> 裁剪坐标
z1后面的那个1是w,为了兼容4*4矩阵
12345678910X = a11*x1 + a12*y1 + a13*z1 + a14 Y = a21*x1 + a22*y1 + a23*z1 + a24 Z = a31*x1 + a32*y1 + a33*z1 + a34 W = a41*x1 + a42*y1 + a43*z1 + a44 //(x, y, z) ...