- 逆向工程
- 调试器
- 开发工具
- 应用安全
【免费下载链接】x64dbg
An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.
x64dbg(An open-source user mode debugger for Windows,专注于逆向工程与恶意软件分析)通过一套"桥接(bridge)"机制将调试核心(src/dbg)与 Qt 图形界面(src/gui)解耦。GuiScriptSetInfoLine正是这套桥接 API 中面向**脚本视图(Script View)**的一组调用之一,其作用是把一段文本写入脚本视图指定行的 Info 列。本文以该函数为主线,结合桥接层的完整调用链,讲解其参数语义、底层实现与典型使用场景,帮助插件开发者与脚本引擎维护者准确使用这一 API。
函数签名与基本语义
GuiScriptSetInfoLine的声明位于桥接头文件 src/bridge/bridgemain.h,属于BRIDGE_IMPEXP导出的 GUI 桥接函数族:
BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info);其语义非常直观:将脚本视图中第line行的 Info 列内容设置为字符串info。x64dbg 的脚本视图(ScriptView)是一个三列表格,各列含义在 ScriptView.cpp 的构造代码中有明确定义:
addColumnAt(8 + charwidth * 4, tr("Line"), false); // 列 0:行号 addColumnAt(8 + charwidth * 60, tr("Text"), false); // 列 1:脚本代码文本 addColumnAt(8 + charwidth * 40, tr("Info"), false); // 列 2:信息列也就是说,GuiScriptSetInfoLine最终更新的正是第 2 列("Info" 列)的内容——该列通常用于显示脚本执行过程中的附加提示信息。
参数说明
line—— 目标行号(基于 1 的行号)
- 类型:
int - 含义:脚本视图中要写入 Info 信息的目标行号。
- 注意行号基准:该参数使用从 1 开始的行号,与 GUI 侧内部使用的 0 基索引相差 1。从 GUI 端实现 ScriptView.cpp 可以看到这一点:
void ScriptView::setInfoLine(int line, QString info) { setCellContent(line - 1, 2, info); reloadData(); //repaint }setCellContent接收的是 0 基行号与列号,因此传入line后会先执行line - 1再做写入。同理,调试器侧在调用时也遵循 1 基行号约定(见下文脚本日志实现)。
info—— 要写入的文本内容
- 类型:
const char* - 含义:要显示在 Info 列的文本字符串,通常为 UTF-8 编码。
- 桥接层会将该 C 字符串转换为
QString再交给 GUI(见 Bridge.cpp),因此字符串的编码一致性(推荐 UTF-8)是保证中文等非 ASCII 文本正确显示的前提。
返回值
该函数没有返回值(返回类型为void)。信息写入是"发后即忘"式的异步投递——调用方无需也不能依赖返回值判断写入是否成功。
底层调用链:一次完整的桥接往返
GuiScriptSetInfoLine的完整实现横跨调试器核心、桥接层与 GUI 三个模块,理解这条链路有助于排查插件中调用无效的问题。
第一步:调试器侧发起消息(src/dbg→ bridge)
函数本体定义在 src/bridge/bridgemain.cpp:
BRIDGE_IMPEXP void GuiScriptSetInfoLine(int line, const char* info) { _gui_sendmessage(GUI_SCRIPT_SETINFOLINE, (void*)(duint)line, (void*)info); }它并不直接操作任何 UI,而是把参数打包进消息GUI_SCRIPT_SETINFOLINE并交给_gui_sendmessage投递。该消息在两个方向上都有正式的类型声明:
- 桥接头文件 bridgemain.h 中的消息宏表:
msg(GUI_SCRIPT_SETINFOLINE, int line, const char* info) \- 头文件同时导出的函数声明:bridgemain.h。
第二步:GUI 侧接收消息并派发(bridge → Qt 信号)
桥接 DLL 在 GUI 进程中的消息分发器 src/gui/Src/Bridge/Bridge.cpp 处理该消息:
case GUI_SCRIPT_SETINFOLINE: emit scriptSetInfoLine((int)(duint)param1, QString((const char*)param2)); break;消息参数在此处完成类型还原:line从duint转回int,info从const char*构造为QString,然后以 Qt 信号scriptSetInfoLine(int, QString)发射(信号声明见 Bridge.h)。
第三步:ScriptView 槽函数落盘到表格(Qt 信号 → UI)
ScriptView在构造函数中通过connect将信号绑定到自身槽函数(见 ScriptView.cpp):
connect(Bridge::getBridge(), SIGNAL(scriptSetInfoLine(int, QString)), this, SLOT(setInfoLine(int, QString)));槽函数setInfoLine(ScriptView.cpp)如前所述,把内容写入(line - 1, 2)单元格并触发reloadData()重绘。至此,一次从调试器核心到界面表格的完整信息写入完成。
典型使用场景:脚本日志输出
仓库中对GuiScriptSetInfoLine最直接的实际调用位于脚本引擎 src/dbg/simplescript.cpp:
void ScriptLogLocked(const char* msg) { if(!bScriptLogEnabled) return; GuiScriptSetInfoLine(scriptIpOld, msg); }这是 x64dbg 内建脚本引擎的日志输出逻辑:当脚本日志开关bScriptLogEnabled开启时,把要记录的文本写入当前指令指针所在行(scriptIpOld)的 Info 列。也就是说,脚本执行到哪一行,该行的 Info 列就会随之更新为最新日志——这正是调试脚本时最常见的可视化反馈方式。
值得注意的是,scriptIpOld与GuiScriptSetIp(simplescript.cpp 等处调用)所维护的scriptIp是同一套 1 基行号体系,与桥接 API 的行号约定完全一致,二者配合即可实现"移动指针 + 行内提示"的联动效果。
使用示例
以插件开发场景为例,假设插件加载了一个外部脚本文件,希望在脚本执行到第 10 行时在该行 Info 列显示一段提示:
#include "bridgemain.h" // 在脚本执行回调中调用 void OnScriptStep() { // 在第 10 行的 Info 列写入提示文本 GuiScriptSetInfoLine(10, "Current line executed by plugin callback"); // 也可以配合行指针移动使用 GuiScriptSetIp(10); // 若执行出错,可用 GuiScriptError 弹出错误对话框 // GuiScriptError(10, "Something went wrong at line 10"); }结合上述桥接链路,该调用会依次完成:bridgemain.cpp打包消息 →Bridge.cpp分发 →ScriptView::setInfoLine写入第 10 行(内部line - 1 = 9)的 Info 列并重绘。
与同族桥接函数的关系
GuiScriptSetInfoLine隶属于一组完整的脚本控制桥接 API,它们共同覆盖脚本视图的增删改查与交互,全部声明集中在 bridgemain.h:
| 函数 | 作用 |
|---|---|
GuiScriptAdd(int count, const char** lines) | 向脚本视图批量追加代码行 |
GuiScriptClear() | 清空脚本视图 |
GuiScriptSetIp(int line) | 设置/移动当前执行指针(IP) |
GuiScriptError(int line, const char* message) | 在指定行触发错误弹窗 |
GuiScriptSetTitle(const char* title) | 设置脚本视图窗口标题 |
GuiScriptSetInfoLine(int line, const char* info) | 向指定行 Info 列写入文本(本文主题) |
GuiScriptMessage(const char* message) | 弹出一条普通消息 |
GuiScriptMsgyn(const char* message) | 弹出 Yes/No 询问并返回用户选择 |
GuiScriptEnableHighlighting(bool enable) | 开关脚本语法高亮 |
它们通过消息宏表(bridgemain.h)逐一映射到GUI_SCRIPT_*消息,并由Bridge.cpp中的case GUI_SCRIPT_*分支统一派发。想要完整定制脚本视图行为的开发者,可将本函数与上述同族 API 组合使用。
实践要点总结
- 行号是 1 基的:传入的
line从 1 开始计数,GUI 内部会自动-1转为 0 基索引;传入 0 或超出脚本行数范围的行号不会产生有效写入,但函数本身不会报错。 - 写入目标是 Info 列:更新的是 ScriptView 三列布局中的第 2 列("Info"),与代码文本列("Text")互不影响,适合存放运行提示、日志摘要等附加信息。
- 异步投递、无返回值:函数为
void,消息经桥接层异步送达 GUI;不要依赖返回值,也不要在同一线程内假设 UI 已立即完成重绘。 - 编码建议:
info参数建议使用 UTF-8 编码,桥接层会将其转换为QString,非 UTF-8 文本可能出现乱码。 - 源码研读入口:完整的实现与调用证据可依次查阅 bridgemain.cpp(消息封装)、Bridge.cpp(消息分发)、ScriptView.cpp(UI 落盘)以及 simplescript.cpp(脚本日志的实际调用),官方 API 文档页见 GuiScriptSetInfoLine.md。
- 逆向工程
- 调试器
- 开发工具
- 应用安全
【免费下载链接】x64dbg
An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.
相关推荐
x64dbg 插件开发指南:GuiScriptSetTitle 详解——为脚本视图设置窗口标题的桥接 API
x64dbg 插件开发指南:GuiScriptSetTitle 详解——为脚本视图设置窗口标题的桥接 API GuiScriptSetTitle 是 x64db
逆向工程调试器开发工具应用安全x64dbg 桥接 API 解析:GuiUpdateDumpView 函数与 Dump 视图刷新机制
x64dbg 桥接 API 解析:GuiUpdateDumpView 函数与 Dump 视图刷新机制 本文以 GuiUpdateDumpView 官方 API
逆向工程调试器开发工具应用安全x64dbg BridgeSettingSet 详解:向调试器设置库写入配置的桥接 API 实战指南
x64dbg BridgeSettingSet 详解:向调试器设置库写入配置的桥接 API 实战指南 导读 BridgeSettingSet 是 x64dbg
逆向工程调试器开发工具应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考