Cutter 反汇编视图断点管理:从 Add/remove breakpoint 到高级断点对话框的完整指南
2026/9/20 12:48:39 网站建设 项目流程

Cutter 反汇编视图断点管理:从 Add/remove breakpoint 到高级断点对话框的完整指南

【免费下载链接】cutterFree and Open Source Reverse Engineering Platform powered by rizin项目地址: https://gitcode.com/gh_mirrors/cu/cutter

导读

本文围绕 Cutter(基于 rizin 的开源逆向工程平台)反汇编视图中与断点管理相关的右键上下文菜单展开,完整讲解「Add/remove breakpoint」与「Advanced breakpoint」两个核心菜单项的触发方式、快捷键、适用场景及其背后的源码实现。读完本文,你将掌握在反汇编视图中快速切换软件断点、通过高级对话框配置硬件断点 / 条件断点 / 跟踪断点 / 断点命令的完整操作流程,并能从 Cutter 源码层面理解断点的创建、编辑与底层 rizin 交互链路。

一、菜单入口与操作概览

在 Cutter 的反汇编视图中,对任意一条指令单击右键即可弹出反汇编上下文菜单,其中包含一个名为Breakpoint的子菜单,用于集中管理断点。该子菜单包含两项:

菜单项功能默认快捷键
Add/remove breakpoint在当前地址添加断点;若已存在断点则移除F2(亦绑定Ctrl+B
Advanced breakpoint打开高级断点对话框,配置硬件、条件等高级断点Ctrl+F2

该子菜单由 DisassemblyContextMenu.cpp 中的addBreakpointMenu()方法构建:先通过addMenu(tr("Breakpoint"))创建子菜单,再将actionAddBreakpointactionAdvancedBreakpoint两个动作依次加入,两个动作分别通过快捷键标识Debug.toggleBreakpointDebug.advancedBreakpoint注册。

二、Add/remove breakpoint:在当前地址快速切换断点

2.1 描述与操作步骤

  • 描述:在当前指令地址添加一个断点;如果该地址已经存在断点,则执行移除操作,即一个「切换(toggle)」语义。
  • 操作步骤:在反汇编视图中右键点击一条指令,选择Breakpoint -> Add/remove breakpoint
  • 快捷键F2(默认绑定;同时在 DefaultShortcuts.cpp 中额外绑定了Ctrl+B作为备选键位)。

2.2 底层实现:从菜单动作到 rizin

在 DisassemblyContextMenu.cpp 中,addBreakpointTriggered()直接调用Core()->toggleBreakpoint(offset),其中offset是右键点击时菜单记录的目标地址(由setOffset(RVA offset)传入)。

toggleBreakpoint在 Cutter.cpp 中的实现为:

void CutterCore::toggleBreakpoint(RVA addr) { CORE_LOCK(); rz_core_debug_breakpoint_toggle(core, addr); emit breakpointsChanged(addr); }

可以看到 Cutter 将切换逻辑委托给 rizin 高层 APIrz_core_debug_breakpoint_toggle,并在操作完成后发出breakpointsChanged信号,驱动断点列表(BreakpointWidget)、反汇编视图等界面同步刷新。

2.3 菜单文本的动态切换

值得注意的一个细节是:菜单项文本并不是固定不变的。在aboutToShowSlot()(菜单即将显示时触发)中,Cutter 会查询当前地址是否存在断点,并据此动态改写动作文本(见 DisassemblyContextMenu.cpp):

const bool hasBreakpoint = Core()->breakpointIndexAt(offset) > -1; actionAddBreakpoint.setText(hasBreakpoint ? tr("Remove breakpoint") : tr("Add breakpoint")); actionAdvancedBreakpoint.setText(hasBreakpoint ? tr("Edit breakpoint") : tr("Advanced breakpoint"));

也就是说:当目标地址已有断点时,右键菜单会显示「Remove breakpoint」;没有断点时才显示「Add breakpoint」。同理,高级断点菜单项在断点存在时变为「Edit breakpoint」。breakpointIndexAt在 Cutter.cpp 中通过rz_bp_get_index_at判断该地址在 rizin 断点列表中的索引是否存在。

三、Advanced breakpoint:高级断点对话框

3.1 描述与操作步骤

  • 描述:打开高级断点对话框。该对话框不仅支持在当前地址创建常规(软件)断点,还支持配置硬件断点、条件断点、断点命令、跟踪断点、启用状态等高级选项。
  • 操作步骤:在反汇编视图中右键点击一条指令,选择Breakpoint -> Advanced breakpoint
  • 快捷键Ctrl+F2(默认绑定,见 DefaultShortcuts.cpp)。

3.2 底层实现:新建还是编辑由断点状态决定

advancedBreakpointTriggered()的实现(见 DisassemblyContextMenu.cpp):

void DisassemblyContextMenu::advancedBreakpointTriggered() { const int index = Core()->breakpointIndexAt(offset); if (index >= 0) { BreakpointsDialog::editBreakpoint(Core()->getBreakpointAt(offset), parentForDialog()); } else { BreakpointsDialog::createNewBreakpoint(offset, parentForDialog()); } }

即:如果目标地址已有断点,则基于现有断点信息打开编辑模式(editBreakpoint);否则以当前地址预填位置字段并打开新建模式(createNewBreakpoint)。两种模式复用同一个 BreakpointsDialog 对话框,其窗口标题分别为 "Edit breakpoint" 与 "New breakpoint"。

对话框确认后,createNewBreakpoint调用Core()->addBreakpoint(getDescription())editBreakpoint调用Core()->updateBreakpoint(index, getDescription())(见 BreakpointsDialog.cpp)。

四、高级断点对话框字段详解

根据 BreakpointsDialog.cpp 与 BreakpointsDialog.ui 的源码,对话框可配置以下字段:

4.1 位置类型(Position Type)

类型含义说明
Address地址输入地址或创建断点时计算的表达式
Named命名以表达式形式存储断点位置
Module offset模块偏移相对于某加载模块的偏移量,需同时指定模块名

选择 Module offset 时会启用模块选择下拉框(moduleName),模块列表来源于Core()->getMemoryMap()的去重结果,并支持包含匹配的自动补全。位置输入框为空时,对话框的 OK 按钮会被禁用(refreshOkButton)。

4.2 断点类型与硬件权限

  • 软件断点(Software):默认类型,通过修改指令流实现中断。
  • 硬件断点(Hardware):选择后需指定访问权限与尺寸:
    • 读(Read,RZ_PERM_R
    • 写(Write,RZ_PERM_W
    • 执行(Execute,RZ_PERM_X
    • 断点尺寸(size,默认值来自下拉框,最终通过Core()->num()解析)

权限选择存在互斥约束(见configureCheckboxRestrictions):勾选读/写会取消执行;勾选执行会取消读/写;且三者中至少保留一项。在 Cutter.cpp 的addBreakpoint中,硬件断点会通过config.permission & ~(RZ_PERM_X)计算出 watchpoint 保护位,再调用rz_debug_bp_add创建断点。

4.3 条件、命令与行为选项

字段作用源码对应
Condition条件表达式,命中条件满足时才触发断点breakpointCondition可编辑下拉框,写入 rizin 的cond字段
Command断点命中时自动执行的命令breakpointCommand多行文本域,写入 rizin 的data字段
Trace跟踪断点:命中时记录执行轨迹checkTrace,通过setBreakpointTrace设置trace属性
Enabled断点是否启用checkEnabled,控制enabled属性

addBreakpoint中,非空的条件与命令分别通过updateOwnedCharPtr(breakpoint->cond, ...)updateOwnedCharPtr(breakpoint->data, ...)写入 rizin 的RzBreakpointItem结构;跟踪选项则在断点创建后调用setBreakpointTrace(index, config.trace)单独设置(见 Cutter.cpp)。

五、断点数据模型与底层 rizin 交互链路

5.1 BreakpointDescription 数据模型

高级对话框通过getDescription()将界面输入收集为BreakpointDescription结构(BreakpointsDialog.cpp),包含addrindexsizepositionExpressiontypepermissioncommandconditionhwtraceenabled等字段;反向地,rizin 的rz_bp_item_t也会通过breakpointDescriptionFromRizin(Cutter.cpp)转换为该结构,供编辑对话框回填。

5.2 关键调用链总结

右键菜单点击 └─ DisassemblyContextMenu::addBreakpointTriggered / advancedBreakpointTriggered ├─ CutterCore::toggleBreakpoint(offset) │ └─ rz_core_debug_breakpoint_toggle(core, addr) // rizin └─ BreakpointsDialog::createNewBreakpoint / editBreakpoint ├─ CutterCore::addBreakpoint(desc) │ └─ rz_debug_bp_add(core->dbg, addr, size, hw, watchpoint, perm, module, delta) └─ CutterCore::updateBreakpoint(index, desc) └─ rz_bp_del + addBreakpoint(先删后建)

其中updateBreakpoint采用「先按地址删除再重新创建」的方式(Cutter.cpp),源码注释指出这是为了规避rz_bp_del_index对非地址型(Named/Module)断点按索引删除的缺陷。

5.3 断点状态的查询与同步

无论是菜单文本动态切换、还是高级对话框的新建/编辑分流,都依赖CutterCore::breakpointIndexAt(addr)查询地址对应的断点索引,并配合getBreakpointAt(addr)获取完整的BreakpointDescription。所有增删改操作完成后都会发出breakpointsChanged信号,驱动断点停靠窗口(BreakpointWidget)与代码视图同步刷新,保证界面与 rizin 内部状态一致。

六、快捷键与自定义

两个断点菜单项的快捷键通过 Cutter 的 ShortcutManager 注册,默认定义位于 DefaultShortcuts.cpp:

{ "Debug.toggleBreakpoint", { { Qt::Key_F2, Qt::CTRL | Qt::Key_B }, QT_TRANSLATE_NOOP("DecompilerContextMenu", "Add/remove breakpoint"), "DecompilerContextMenu" } }, { "Debug.advancedBreakpoint", { { Qt::CTRL | Qt::Key_F2 }, QT_TRANSLATE_NOOP("DecompilerContextMenu", "Advanced breakpoint"), "DecompilerContextMenu" } },

也就是说:

  • Add/remove breakpointF2Ctrl+B
  • Advanced breakpointCtrl+F2

这些快捷键与反汇编视图共享同一套注册体系(上下文名为DecompilerContextMenu,反汇编与反编译菜单均复用该快捷键),并可在「设置 -> 快捷键」界面中由用户自定义。类似地,断点列表窗口自身还有独立的快捷键:Breakpoint.toggleBreakpoint(空格键)与Breakpoint.delBreakpoint(Delete 键),可在 DefaultShortcuts.cpp 中查看。

七、典型使用场景与小结

  • 快速设断点:分析时对目标指令直接按F2,即可在反汇编视图中实现断点的新增/移除切换,配合断点列表窗口的空格键切换,效率最高。
  • 条件与命令断点:当需要在特定条件(如寄存器值、内存值)满足时才中断,或在命中时自动执行输出寄存器、dump 内存等命令时,使用Ctrl+F2打开高级对话框配置 Condition 与 Command。
  • 硬件断点/观察点:在调试需要监控内存读写(而非仅执行)的场景下,选择 Hardware 断点并勾选读/写权限,Cutter 会将其转换为 rizin 的 watchpoint 语义(watchpointProt = permission & ~RZ_PERM_X)创建。
  • 跟踪断点:需要记录程序执行轨迹时,勾选 Trace 选项,断点命中将写入执行轨迹数据。

通过「快速切换 + 高级对话框」的组合,Cutter 在反汇编视图这一个右键菜单入口内,覆盖了从最常用软件断点到硬件观察点、条件触发、命令注入、轨迹跟踪的完整断点能力,并且全部能力都能追溯到清晰的源码实现(DisassemblyContextMenu.cpp、BreakpointsDialog.cpp、Cutter.cpp),便于二次开发与深度定制。

相关参考文档:manage-breakpoints-context-menu.rst、debug-context-menu.rst。

【免费下载链接】cutterFree and Open Source Reverse Engineering Platform powered by rizin项目地址: https://gitcode.com/gh_mirrors/cu/cutter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询