裸机编程:操作系统开发的无限乐趣
本文章仅提供学习,切勿将其用于不法手段!
Bochs 3.0 Devel 是一款功能强大的 x86 架构模拟器,其内置的调试器支持丰富的命令,用于调试操作系统内核、引导程序或应用程序。以下是 Bochs 3.0 Devel 调试命令的分类汇总(基于 2023-2025 年最新技术博客整理):
一、调试器控制命令
用于管理调试会话的全局命令,如退出、设置全局参数等。
| 命令格式 | 描述 | 示例 |
|---|---|---|
q/quit/exit | 退出调试器并关闭虚拟机(最常用)。 | q |
set $reg = expr | 设置通用寄存器的值(如 eax、ecx 等,不可设置 eflags、cs 等特殊寄存器)。 | set $eax = 0x01234567 |
set $eflags = expr | 设置标志寄存器 eflags 的值(仅支持部分标志位修改)。 | set $eflags = 0x202 |
set $cpu = N | 在 SMP(对称多处理)模拟中,切换到第 N 个 CPU 核心。 | set $cpu = 1 |
set $auto_disassemble = 1 | 每次执行停止时,自动反汇编当前准备执行的指令(0 为关闭)。 | set $auto_disassemble = 1 |
set show_mod on | 当 CPU 切换模式(如实模式→保护模式)时,提示模式变化。 | set show_mod on |
set show_int on | 每次发生中断时,提示中断类型(softint:软件中断;extint:外部中断;iret:iretd 指令)。 | set show_int on |
二、执行控制命令
用于控制虚拟机的执行流程,如继续运行、单步调试、设置断点等。
1. 基础执行命令
| 命令格式 | 描述 | 示例 |
|---|---|---|
c/cont/continue | 继续执行虚拟机,直到遇到断点或手动中断(Ctrl+C)。 | c |
s/step/stepi [count] | 单步执行 count 条指令(默认 1 条),会进入函数调用。 | s 10(执行 10 条指令) |
n/next [count] | 单步执行 count 条指令(默认 1 条),跳过函数调用(视为整体)。 | n(执行 1 条指令,跳过函数) |
Ctrl+C | 中断当前执行,返回调试器命令行(最常用的中断方式)。 | Ctrl+C |
2. 断点管理命令
断点是调试中最常用的工具,用于在特定地址或条件下暂停执行。Bochs 支持虚拟地址断点、线性地址断点、物理地址断点、指令数断点、IO 断点等多种类型。
(1)设置断点
| 命令格式 | 描述 | 示例 |
|---|---|---|
vb/vbreak seg:off | 在虚拟地址(seg:off,如 0x07C0:0x0000)设置断点。 | vb 0x07C0:0x0000(引导扇区入口) |
lb/lbreak addr | 在线性地址(addr,如 0x7C00)设置断点。 | lb 0x7C00(实模式引导扇区加载地址) |
pb/pbreak/b/break [*] addr | 在物理地址(addr,如 0x7C00)设置断点(* 为可选 GDB 兼容语法)。 | pb 0x7C00(物理内存地址) |
sb delta | 在当前执行后 delta 条指令设置断点(delta 为 64 位整数,如 1000L)。 | sb 1000L(执行 1000 条指令后中断) |
sba time | 在CPU 启动后第 time 条指令设置断点(time 为 64 位整数)。 | sba 5000(执行 5000 条指令后中断) |
watch read addr | 在物理地址 addr 设置读监视点(当该地址被读取时中断)。 | watch read 0x90000(监控 0x90000 地址的读操作) |
watch write addr | 在物理地址 addr 设置写监视点(当该地址被写入时中断)。 | watch write 0xA0000(监控 0xA0000 地址的写操作) |
(2)断点管理
| 命令格式 | 描述 | 示例 |
|---|---|---|
info break/blist | 显示所有断点的信息(编号、类型、地址、状态)。 | info break |
d/del/delete [n] | 删除第 n 号断点(n 由 info break 获取)。 | d 1(删除 1 号断点) |
bpd/bpe [n] | 禁用(bpd)或启用(bpe)第 n 号断点。 | bpd 1(禁用 1 号断点);bpe 1(启用 1 号断点) |
unwatch [addr] | 移除所有监视点或指定地址的监视点。 | unwatch(移除所有监视点);unwatch 0x90000(移除指定地址的监视点) |
三、内存操作命令
用于查看、修改物理/线性内存的内容,是调试内存错误的关键工具。
| 命令格式 | 描述 | 示例 |
|---|---|---|
xp /nuf addr | 查看**物理地址 addr** 的内存内容(n:数量;u:单元大小;f:格式)。 | xp /16xb 0x7C00(查看物理地址 0x7C00 开始的 16 个字节,十六进制格式) |
x /nuf addr | 查看**线性地址 addr** 的内存内容(参数含义同 xp)。 | x /16xw 0x00000000(查看线性地址 0x00000000 开始的 16 个字,十六进制格式) |
setpmem addr datasize val | 设置**物理地址 addr** 开始的 datasize 字节内存为 val(datasize 最大为 4)。 | setpmem 0x90000 4 0x12345678(设置 0x90000 地址的 4 字节为 0x12345678) |
crc addr1 addr2 | 计算**物理地址 addr1 到 addr2** 范围内的 CRC 校验值(用于验证内存完整性)。 | crc 0x1000 0x2000(计算 0x1000-0x2000 内存的 CRC) |
info dirty | 显示自上次执行以来被修改的物理页(最多显示 20 个,用于定位内存写入错误)。 | info dirty |
四、CPU 与寄存器操作命令
用于查看、修改 CPU 寄存器的状态,是调试指令执行的关键工具。
1. 寄存器查看命令
| 命令格式 | 描述 | 示例 |
|---|---|---|
r/reg/regs/registers | 查看通用寄存器(eax、ecx 等)、段寄存器(cs、ds 等)、标志寄存器(eflags)的值。 | r(显示所有寄存器);r eax(仅显示 eax 寄存器) |
fp/fpu | 查看浮点单元(FPU) 的状态(如 ST0-ST7 寄存器)。 | fp |
mmx | 查看MMX 寄存器(mm0-mm7)的状态。 | mmx |
sse | 查看SSE 寄存器(xmm0-xmm7)的状态。 | sse |
sreg | 查看段寄存器(cs、ds、es、fs、gs、ss)的详细信息(如基地址、限长)。 | sreg |
dreg | 查看调试寄存器(dr0-dr7)的状态(用于硬件断点)。 | dreg |
creg | 查看控制寄存器(cr0、cr1、cr2、cr3、cr4)的状态(用于分页、保护模式)。 | creg |
2. CPU 状态命令
| 命令格式 | 描述 | 示例 |
|---|---|---|
info cpu | 显示CPU 所有寄存器的完整状态(包括通用寄存器、段寄存器、标志寄存器等)。 | info cpu |
info eflags | 显示**标志寄存器 eflags** 的解码状态(如 CF、ZF、SF 等标志位)。 | info eflags |
info page laddr | 显示线性地址 laddr 对应的物理地址(用于线性地址到物理地址的映射调试)。 | info page 0x00100000(显示 0x00100000 线性地址的物理地址) |
ptime | 显示Bochs 自启动以来的总执行指令数(用于性能分析)。 | ptime |
五、反汇编命令
用于反汇编物理/线性内存中的指令,是分析代码执行流程的关键工具。
| 命令格式 | 描述 | 示例 |
|---|---|---|
u/disasm/disassemble [/num] [start] [end] | 反汇编**物理地址 start 到 end** 的指令(/num:反汇编的指令数;不指定地址则反汇编 EIP 指向的指令)。 | u /10(反汇编当前 EIP 开始的 10 条指令);u 0x7C00 0x7C10(反汇编 0x7C00-0x7C10 的指令) |
| `set $disassemble_size = 16 | 32 | 64` |
六、其他实用命令
| 命令格式 | 描述 | 示例 |
|---|---|---|
info program | 显示程序执行状态(如是否暂停、当前指令地址)。 | info program |
print-stack [num] | 显示堆栈顶端 num 个字(默认 16,仅适用于保护模式堆栈段基地址为 0 的情况)。 | print-stack 32(显示堆栈顶端 32 个字) |
?/calc | 内置计算器,支持算术运算(如 ? 0x10 + 0x20)。 | ? 0x10 * 0x20(计算 0x10 * 0x20=0x200) |
record filename | 将控制台输入记录到文件 filename(用于后续回放)。 | record debug.log |
playback filename | 从文件 filename 回放控制台输入(用于自动化调试)。 | playback debug.log |
注意事项
- 地址类型区分:Bochs 中的地址分为虚拟地址(实模式下为段:偏移,保护模式下为 CS:EIP)、线性地址(分段后的地址)、物理地址(实际内存地址),使用命令时需明确地址类型(如
vb用虚拟地址,lb用线性地址,pb用物理地址)。 - 断点优先级:物理地址断点的优先级高于线性地址断点,线性地址断点高于虚拟地址断点。
- 寄存器修改限制:部分特殊寄存器(如
cs、ss、eflags的某些标志位)无法通过set命令修改,需通过指令间接修改。 - 反汇编模式:
set $disassemble_size需与当前 CPU 模式匹配(如实模式设为16,保护模式设为32,64 位模式设为64)。
以上是 Bochs 3.0 Devel 调试命令的完整汇总,覆盖了调试过程中的核心操作。如需更详细的帮助,可在 Bochs 调试器中使用 help 命令查看具体命令的语法(如 help set、help break)。
注:本文仅用于教育目的,实际渗透测试必须获得合法授权。未经授权的黑客行为是违法的。

1021

被折叠的 条评论
为什么被折叠?



