NET: STABLE
MEM: 14%
Double tap to skip initialization...
Featured image of post 逆向基础-工具篇:x64bdg使用

逆向基础-工具篇:x64bdg使用

好用的动态调试器

x64dbg开源,一直在更新,支持64位程序,还多了一些功能,比Ollydbg好用,没学OD的可以不用学了(

⚠️ Warning

以下内容分析目标是64位程序,使用的是x64dbg,部分功能具体可能不同(比如寄存器名称、硬件断点可用字节数)

CPU窗口

随便拖入一个可执行文件,会自动进入到CPU选项卡界面,可以看到四个窗口:

image-20251103105758147

反汇编窗口

左上角的反汇编窗口,这里显示是我们要分析的程序的反汇编代码(注意是可以上下左右拖动的):

image-20251103105813878

最左侧蓝色箭头显示的是EIP寄存器的指向,也就是运行到此处时下一条执行指令的位置,一般用于查看跳转,点击对应行,相应的箭头指示会变粗

黑灰色的一行表示程序的入口

拿出来一行看看:

00007FFA08B44402 | 48:C7C1 FEFFFFFF      | mov rcx,FFFFFFFFFFFFFFFE         | rcx:NtQueryInformationThread+14
  • 第一列:00007FFA08B44402

    表示的是当前这条汇编指令所在的地址

    每一列的地址都是依次排序的,第二行的地址是第一行的地址再加上指令长度

    在第一列双击可以看到一个箭头,你可以 以这个位置为起始地址,看到相对于这个地址的偏移:

    image-20251103110008124

  • 第二列:48:C7C1 FEFFFFFF

    是机器码/操作码opcode,是给计算机看的语言

    在这个位置双击(或者选择该行点击F2),可以下一个断点,对应的地址列会变红:

    image-20251103110116880

  • 第三列:mov rcx,FFFFFFFFFFFFFFFE

    是汇编指令,也就是opcode指令翻译成的汇编语言

    在这个位置按空格可以修改汇编代码(最好勾选上剩余字节以NOP填充):

    image-20251103110531515

  • 第四列:rcx:NtQueryInformationThread+14

    是注释

    点击;键可以添加/修改注释:

    image-20251103110658442

寄存器窗口

右上角的寄存器窗口显示调试程序的寄存器信息:

image-20251103111126272

可以双击某一个寄存器对值进行修改:

image-20251103113500162

💡 Tip

或许你会看见不同的寄存器名称:

时代 位宽 寄存器命名特征 示例
8086(out) 16 位 AX、BX、CX、DX、SI、DI、BP、SP、IP 如:AX 表示累加寄存器
80386 32 位 在 16 位基础上加前缀 E(Extended,扩展) EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP、EIP
x86-64 64 位 在 16 位基础上加前缀 R(Register) RAX、RBX、RCX、RDX、RSI、RDI、RBP、RSP、RIP

内存窗口

左下角的数据窗口是内存地址的内容

最左边是内存地址,接着是对应地址的十六进制数据,最右侧是十六进制对应的ASCII码:

image-20251103111357147

我们可以选中数据进行复制:

image-20251103113354760

也可以双击某一个字节进行修改:

image-20251103113421990

堆栈窗口

右下角是堆栈窗口,显示的是堆栈信息:

image-20251103111420920

可以双击某一行对它进行修改:

image-20251103113546302

快捷键

💡 Tip

善用鼠标右键,很多功能都在里面,包括常用的查找搜索功能等等,快捷键只是更快使用它们而已

选项 -> 快捷键,可以查看和自定义快捷键:

image-20251103122728365

下面是一些常用的快捷键:

快捷键 功能说明
F2 设置 / 取消断点
Ctrl + F2 重新启动调试(F2的断点还在)
Alt + F2 关闭当前程序
F4 运行到选中行处
F7 单步步入(进入函数,跟着call去函数内部)
F8 单步步过(不进入函数,跳过call,执行完当前函数)
Shift + F7 条件单步步入
Shift + F8 条件单步步过
Ctrl + F7 自动步入(重复单步进入)
Ctrl + F8 自动步过(重复单步步过)
F9 运行程序 / 继续执行
Ctrl + F9 执行到返回,用于快速跳出当前函数
Alt + F9 执行到用户代码,用于快速跳出系统函数
F12 暂停程序
Ctrl + G 跳转到目标地址 / 表达式
Ctrl + Shift + F 在模块中搜索字符串
Ctrl + F 搜索指令或数据
Ctrl + B 搜索十六进制
Ctrl + L 搜索下一个
Alt + Ins 复制地址
Shift + D 在引用窗口全局搜索字符串
Enter 跟随跳转(如 call / jmp 目标)
Alt + M 打开内存映射窗口
Alt + K 打开调用堆栈窗口
Alt + B 打开断点列表
Space 汇编 / 编辑当前指令
; 添加注释
Ctrl + P 打开补丁窗口

断点

软件断点

在程序执行到特定指令时暂停程序执行

这种断点类型是由调试器模拟实现的,通常通过修改程序指令来实现

它是最常见的断点类型,因为可以在任何代码段中设置断点(但有些地方下断会导致系统崩溃,特别是内核)

快捷键下断点

通过F2 / 双击操作码可以在对应位置下断点,会以红色标注,而当前IP指针则会使灰色显示,如下图所示:

image-20251103122930653

命令下断点

软件断点同样可以在最下方的命令输入窗口使用bp/bpx等命令下断,或通过bc来取消断点:

bp 00007FFA08B44425

image-20251103124533917

image-20251103124509514

跳转目标位置下断点

当需要在特定函数上下断点时,可通过Ctrl+G调出地址跳转表达窗口,输入目标函数,跳转后手动下断点:

image-20251103124638825

image-20251103124650419

当然也支持输入命令:

bp MessageBoxA

结合条件下断点

这个是对断点附加触发条件的方法

右键对应指令设置条件断点:

image-20251103132426611

输入暂停条件,只有当满足特定条件表达式时,断点才会触发:

image-20251103132440008

硬件断点

硬件断点是利用CPU的调试寄存器DR0–DR3来实现的,这些寄存器用于跟踪指令地址和数据访问地址

硬件断点不修改内存,通常比软件断点更快,但是受到硬件限制,每次能断的字节和总数量有限

在内存数据窗口选中某一块地址,之后右键即可选择要下的硬件断点:

image-20251103125236902

硬件访问断点

当程序尝试从指定内存地址读取数据时触发

比较少使用,主要是监控敏感变量或内存内容被读取

硬件写入断点

当程序尝试向指定内存地址写入数据时触发

是常用的类型,比如跟踪变量、缓冲区、密钥、解密结果等数据什么时候被修改

硬件执行断点

当程序执行到指定地址时触发

相当于软件断点,但由CPU调试寄存器实现,不修改代码,无INT3中断指令

放在函数入口或特定指令上中断执行,能避免被反调试检测

内存断点

通过改变页表属性或分段保护实现,当程序在特定内存地址处读取、写入或执行时,暂停程序执行

内存断点是按照内存页(4KB)监控的,也就是一旦监控了一个地址,就等于监控该地址所在整个页面

它的范围广,但性能开销高,并且某些情况下是不够精确的,因为页的内存可能有很多指令在修改,会有干扰

内存断点分两种:

类型 触发次数 触发后行为 说明 常见用途
一次性断点 仅触发 一次 命中后自动删除 程序命中该断点暂停一次后,调试器会自动清除该断点 临时观察某处是否会被访问或执行,用于快速验证逻辑
重复断点 可触发 多次 命中后仍保留 程序每次命中都会暂停 长期监控某个内存或代码地址,例如循环中的多次写入或读取

image-20251103125851853

内存访问断点

当程序试图访问特定内存地址时触发

最通用的类型,监控任意对敏感内存的操作,如全局变量或关键数据区

内存读取断点

当程序试图从特定内存地址读取数据时触发

用于分析某数据在何处被读取,例如密码、密钥或结构体成员

内存写入断点

当程序试图写入特定内存地址时触发

用于跟踪变量变化、解密过程、缓冲区写入等场景

内存执行断点

当程序试图执行特定内存地址处的指令时触发

类似软件断点,但不依靠INT3,而是靠修改页属性,用于检测动态代码执行、Shellcode或自修改代码

消息断点

这是一种特殊的断点,通过监控处理消息循环实现,当程序接收到指定类型的消息时,暂停程序执行

可以用于监视程序执行期间的Windows消息,包括键盘输入、鼠标操作、窗口消息等

img

消息断点在调试GUI程序时非常有用,可以帮助调试窗口消息的处理代码,定位程序中的错误或异常行为

例如,当你想要调试一个窗口消息处理函数时,可以在该函数上设置消息断点,当程序接收到对应的消息时,程序会暂停在该函数内部,方便进行调试

保存文件

如图,我们随便修改了这个程序的一些指令:

image-20251103133647080

为了试运行而不影响源文件,就需要另存为新的文件

在反汇编窗口右键,选择补丁(patch),或者Ctrl+P:

image-20251103133749663

接着点击修补文件即可另存:

image-20251103164713057

基础使用就到这里,更多方法还要在实战里体会~

最后更新于 2025-12-04
距离小站第一行代码被置下已经过去
使用 Hugo 构建
主题 StackJimmy 设计
...当然还有kakahuote🤓👆