x64dbg 桥接 API 解析:GuiScriptSetInfoLine 如何向脚本视图写入 Info 信息行
2026/9/20 0:46:05 网站建设 项目流程
  • 逆向工程
  • 调试器
  • 开发工具
  • 应用安全

【免费下载链接】x64dbg

An open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.

项目地址:https://gitcode.com/gh_mirrors/x6/x64dbg
点击查看免费下载

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;

消息参数在此处完成类型还原:lineduint转回intinfoconst 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 列就会随之更新为最新日志——这正是调试脚本时最常见的可视化反馈方式。

值得注意的是,scriptIpOldGuiScriptSetIp(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. 行号是 1 基的:传入的line从 1 开始计数,GUI 内部会自动-1转为 0 基索引;传入 0 或超出脚本行数范围的行号不会产生有效写入,但函数本身不会报错。
  2. 写入目标是 Info 列:更新的是 ScriptView 三列布局中的第 2 列("Info"),与代码文本列("Text")互不影响,适合存放运行提示、日志摘要等附加信息。
  3. 异步投递、无返回值:函数为void,消息经桥接层异步送达 GUI;不要依赖返回值,也不要在同一线程内假设 UI 已立即完成重绘。
  4. 编码建议info参数建议使用 UTF-8 编码,桥接层会将其转换为QString,非 UTF-8 文本可能出现乱码。
  5. 源码研读入口:完整的实现与调用证据可依次查阅 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.

项目地址:https://gitcode.com/gh_mirrors/x6/x64dbg
点击查看免费下载

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

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

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

立即咨询