- 博客(206)
- 收藏
- 关注
原创 为自己的驱动程序签名
这条命令指示signtool准备:以详细模式执行。定位:在本地计算机的证书存储中,找到一个名为的证书,并使用其关联的私钥。计算:使用SHA256 算法计算“驱动路径”所指文件的哈希值。加戳:联系DigiCert 的时间戳服务器,获取当前签名时间的权威证明。生成签名:用第2步找到的私钥,加密第3步计算出的哈希值,并将此加密结果、证书公钥信息、以及第4步得到的时间戳,打包成一个“数字签名”数据块。写入:将第5步生成的签名数据块,嵌入到驱动文件的特定位置(通常是文件的“安全目录”节中)。
2026-03-31 22:41:11
354
原创 浅析64位Windows的SEH机制
笔者花费了一些时间,学习了64位WindowsSEH机制的底层原理。现写为博客,希望对大家有帮助。要使SEH发挥作用,必须得到编译器、硬件和操作系统的配合支持。SEH 在特定平台上的具体实现方式可能因架构而异。
2026-03-29 12:47:52
415
1
原创 x86经典分页机制
两次内存访问:转换过程需要额外访问两次内存(取 PDE,取 PTE),之后才能访问目标数据。这是分页机制的性能开销来源。对齐要求:页目录和页表的基址必须 4KB 对齐(低 12 位为 0)。控制位作用:PDE 和 PTE 的低 12 位控制位决定了访问权限、缓存策略和状态(如存在位 P 为 0 会触发缺页异常)。这个例子清晰地展示了一个 32 位线性地址如何通过两级索引,最终被转换为物理地址。
2026-03-26 19:50:23
545
原创 Windows驱动重要数据结构
每个驱动程序会有唯一的驱动对象与之对应,并且这个驱动对象是在驱动加载的时候,被内核中的对象管理程序所创建的。驱动对象用DRIVER_OBJECT数据结构表示,它作为驱动的一个实例被内核加载,并且内核对一个驱动只加载一个实例。确切地说,是由内核中的I/O管理器负责加载的。驱动程序需要在DriverEntry中初始化。
2026-03-23 15:56:48
323
原创 Windows内核驱动重要知识
执行体是 Windows 内核的“业务逻辑层”,它封装了硬件细节和底层机制,为驱动程序和系统服务提供了稳定、统一的高级 API 接口。
2026-03-23 09:44:15
411
原创 PE文件之TLS
线程局部存储(Thread Local Storage,TLS)是各线程独立的数据存储空间,使用TLS可以像修改自身局部变量一样修改进程的全局变量而不影响其它线程。这很好地解决了多线程程序设计中变量的同步问题。TLS机制最重要的地方在于:用来向目标文件写入内容的代码在所有线程中都是一样的,而从TLS中取出的文件偏移和字节数却各不相同。实现TLS比较常见的办法是在进程中建立一个全局表,通过线程的ID去查询相应的数据结构,因为每个线程的ID是不一样的,所以查到的数据也自然就不一样了。
2026-03-22 10:57:57
373
原创 CodePatch hook api
该种hook方法修改了目标api入口地址处的一些字节(32位和64位需要修改的字节数不同),通常修改为jmp xxx的形式,使得目标api跳转到我们的代码中执行。注意我们需要保存目标api入口处的原字节,以便脱钩。为了能够在目标进程中执行这些操作,我们需要将代码注入到目标进程中去,通常使用远程线程dll注入技术达到该目的。
2026-03-21 12:15:19
167
原创 说说c++四大强制类型转换运算符
const_cast和。这不是简单的语法糖,而是设计理念的根本不同。C语言的强制类型转换像是"我说了算"的霸道指令。你用括号把目标类型括起来,放在变量前面,编译器就照做,基本不检查转换是否合理。这种转换太过强大,也太过危险,很容易隐藏bug。C++的四种转换运算符则是"有明确目的"的精细工具。每种转换负责特定的转换场景,编译器会做更多的检查,不合理的转换会报错。这反映了C++的类型安全设计思想。
2026-03-21 09:18:58
415
原创 说说VirtualAlloc的第三个参数
Windows的VirtualAlloc函数是内存管理的核心API,它负责在进程的虚拟地址空间中分配内存。这个函数有四个主要参数,其中第三个参数常常被简单带过,但它实际上包含了内存分配行为的关键控制信息。
2026-03-20 23:20:16
422
原创 说说Windows进程的令牌(token)
令牌是Windows内核中的一个数据结构,它包含了与安全相关的一切信息。当一个用户登录系统时,会创建一个主令牌。之后启动的每个进程都会继承或获得一个令牌,这个令牌决定了进程能做什么、不能做什么。可以把令牌想象成现实世界中的身份证加门禁卡。身份证证明你是谁,门禁卡决定你能进哪些房间。Windows令牌同样包含这两类信息:身份信息和权限信息。在进行DLL注入、调试HookAPI、CodePatch等工具的时候,也需要设置号相应的令牌。
2026-03-20 23:15:12
610
原创 《逆向工程核心原理》使用调试函数hook api的实验在64位Windows11上的复现
简单来说,我们自己的Hook程序是目标进程的调试器,需要将目标进程地址空间中我们需要Hook的api的首地址改为0xCC,也就是int3中断指令,当目标进程调用到我们下断点的api时,它就会触发一个0xCC异常,此时控制权转移到我们的程序上,此时我们就可以操作目标进程的地址空间了。这属于inline hook(见《加密与解密》)。总之就是使用了Windows系统提供的异常处理功能:我们主要关注的是EXCEPTION_DEBUG_EVENT调试事件中的EXCEPTION_BREAKPOINT异常。
2026-03-19 23:44:23
315
原创 C++字符串复制实例反汇编
可以看到,对字符数组的初始化,是拷贝数据段中的一块内存到函数的栈空间中的,而这样的拷贝,每次都拷贝一个寄存器的大小,这样可以节约复制的时间。比如这个getline函数,它明显有三个参数,从左到右为输入流对象、接收输入的缓冲区首地址,缓冲区的大小。这样,就可以确定第二个参数就是一个数组,并且大小为14h。在IDA中要注意对数组的识别。数组的特征为连续的,大小相同的变量。也可以通过对一些函数的分析,明确某一局部变量为数组。实际上,上面的代码是strlen函数的内联形式,编译器对strlen的调用做了内联优化。
2026-03-17 11:27:48
25
原创 记录一个与时间有关的crackme
题目链接:https://crackmes.one/crackme/5ab77f5633c5d40ad448c28b。
2026-03-15 12:32:17
381
原创 PE文件之资源表
当字段作为ID使用的时候,是可以放入一个双字的,如果使用字符串定义的时候,一个双字是不够的,这就需要将两种情况分别对待,区分的方法是使用字段的最高位(位31)。当位31是0的时候,表示字段的值作为ID使用;
2026-03-14 20:45:33
472
原创 Windows内核驱动开发时是否要设置版本控制宏
的 Windows API 定义(通常是 Windows 2000 或 XP 级别)。默认情况下,编译器会使用。
2026-03-10 23:55:26
423
原创 Windows内核驱动开发构建选项
宏值含义必要性_AMD64_或_X86_1指定目标架构必须1编译内核模式代码必须WIN32或_WIN321Windows 平台必须_WIN64164位系统仅 64 位时STD_CALL1调用约定通常自动NT_INST0内核模式标识必须。
2026-03-10 23:53:19
415
原创 PE文件之重定位表
因为不能保证每次加载PE文件到内存中时都加载到文件头中指定的ImageBase,所以在使用直接寻址的地方,就会发生重定位:根据实际加载的地址修正直接寻址的地址。具体修复公式如下:直接寻址的地址 - PE文件中的ImageBase + 实际加载的ImageBase我们使用重定位表来记录需要重定位的地址的首地址,重定位表有数据目录的第六项指定:该项存储了重定位表的RVA和大小。
2026-03-09 18:35:28
422
原创 一道使用base64加密的re题
由此可知,这是对我们输入的flag进行base64编码之后得到一个str,再对这个str进行循环中的变换。最终得到的str与e3nifIH9b_C@n@dH进行比较。经过验证发现,这不是flag(无论是否使用base64解码)。将得到的字符串进行base64解码就是flag。发现base64编码的关键字符串。
2026-03-08 00:58:09
33
原创 说说栈保护指令
栈保护指令是编译器安全加固的一部分。虽然增加了一点性能开销,但大大提高了攻击门槛。在逆向分析中,这些指令提供了额外的信息,有助于理解程序结构和安全特性。
2026-03-07 01:25:03
390
原创 ajj.1 CKme
其实这个crackme小程序花了我3天时间,我的思路还是太单一,总想拿着程序丢进ida或者od里面就开始破解。我花了大量时间寻找serial断点。其实对于Delphi程序,有许多特别好用的破解工具,如果在破解之前能多去网上搜集一些关于Delphi的破解资料,就会发现这些工具,这会节省我大量时间。
2026-03-06 23:48:53
321
原创 Delphi逆向基础
Delphi逆向是个专门的领域,有自己的特点。理解Delphi的对象模型、字符串处理、异常机制,是逆向的基础。工具上,结合通用逆向工具和Delphi专用工具,效率更高。虽然Delphi现在用的人少了,但还有很多遗留的Delphi程序在运行。掌握Delphi逆向技术,对维护、分析这些程序很有帮助。即使不专门做逆向,了解这些知识对理解Windows程序结构也有好处。
2026-03-06 21:48:33
1048
原创 Windows内核(三):Windows内核函数前缀的学问
Windows内核函数的前缀是个很有用的设计。虽然刚开始要记的东西多,但习惯了之后,看函数名就知道大概功能和所属模块。这对理解内核架构、调试问题都有帮助。写内核代码要特别注意函数的选择。用对了函数,代码稳定;用错了,可能出各种奇怪的问题。了解这些前缀的含义,是写好内核代码的第一步。
2026-03-05 23:38:19
372
原创 写一个简单通用的Windows错误处理函数
Windows的错误处理看似简单,但要做好需要考虑到各种细节。安全版本的字符串函数防止缓冲区溢出,细致的字符串清理让显示更美观,完整的错误信息方便调试。这个函数是个不错的模板,可以直接用,也可以根据自己的需要修改。比如可以把错误信息输出到日志文件,或者在某些情况下不用消息框而用其他方式通知用户。写Windows程序,好的错误处理能省去很多调试时间。特别是在客户环境出问题的时候,有详细的错误信息,可能远程就能判断出问题原因。
2026-03-05 10:00:06
383
原创 汇编里的JB指令
JB是汇编里基本的条件跳转指令,专门用于无符号数的“小于”比较。理解它的工作原理,关键要明白两点:一是它检查的是CF标志,二是它用于无符号数比较。写汇编代码的时候,选择正确的条件跳转指令很重要。用错了,逻辑就全乱了。特别是处理那些可能被解释为有符号或无符号的数时,要特别小心。JB、JL看起来差不多,但用错了地方,结果可能完全不对。虽然现在直接用汇编写代码的人少了,但理解这些底层的东西,对理解计算机怎么工作,还是有好处的。特别是调试底层问题的时候,知道条件跳转怎么工作的,能省不少事。
2026-03-05 09:00:48
426
原创 理解汇编的ADC指令
ADC是汇编里处理进位传递的标准做法。理解了这个指令,就理解了计算机怎么处理超过机器字长的运算。虽然现在用高级语言不用自己写这些,但知道底层怎么实现的,对理解计算机的工作原理有帮助。
2026-03-05 08:54:26
428
原创 Windows内核(二):运行第一个内核驱动程序
在运行第一个内核驱动程序之前,我们有必要了解一下Windows中的,这是一个十分重要的概念。Windows 系统中具有一个服务控制器(SCM)用于控制服务。服务的安装、删除、启动、停止、控制与 I/O 都是通过服务控制器。我们可以在命令提示符中使用sc命令来管理服务,Windows也提供了关于服务的API供我们编程使用。实际上,sc命令内部也是对Windows服务API进行本地调用实现的。这篇博客是讲内核的,主要关注内核驱动服务。对于服务API的编程,读者可以自行了解。
2026-03-04 14:38:18
396
原创 TCP/IP 体系结构
该层定义了不同主机之间进程的通信规则。我的理解是,当数据包从传输层传递过来时,应用层的协议规定了需要接收该数据包的进程如何处理这个数据包。
2026-03-03 11:53:44
81
原创 AfKayAs.2
在实际分析过程中,我犯了一个严重的错误,就是过于追究代码的细节,而不是将代码视为几个部分,这让我深陷语言的反汇编细节中,而不是关注算法的过程。另外,在分析的过程中需要时刻记住自己关注的点是什么,不要让繁杂的反汇编代码牵着自己的鼻子走,要记住自己的目标去看代码。
2026-03-02 23:43:19
731
原创 给出一份适用于nvim-lsp的c/cpp格式化配置文件(微软风格)
有时间再出一篇在Windows上使用lua配置nvim的教程(配置完成之后支持普通的C/CPP开发,win32开发,内核驱动开发,前端开发和python开发,带有语法高亮和格式化,编辑时错误提示等)。首先需要确保自己配置好了C/CPP的lsp,并且安装了clang-format。
2026-03-02 17:51:35
336
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅