ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

x64dbg 插件开发指南:GuiGetGlobalNotes 全局笔记读取接口详解

x64dbg 插件开发指南:GuiGetGlobalNotes 全局笔记读取接口详解 x64dbg 插件开发指南GuiGetGlobalNotes 全局笔记读取接口详解【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbgGuiGetGlobalNotes是 x64dbg 向插件开发者暴露的一组 GUI 桥接bridge接口之一用于把用户在 Notes笔记视图中编写的全局笔记以字符串指针的形式返回给调用方。本文以该接口为核心完整讲解其声明、参数语义、内存管理约定、消息桥接原理并结合源码说明全局笔记与调试目标Debuggee笔记的存储差异帮助插件开发者正确读写这两类笔记数据。接口概述在 x64dbg 中笔记Notes是用户随手记录调试心得、待办事项与关键地址的工具。笔记分为两类全局笔记Global Notes与具体调试目标无关适用于所有会话存储在notes.txt文件中调试目标笔记Debuggee Notes与当前被调试程序绑定存储在调试数据库database中会随目标一起保存与恢复。GuiGetGlobalNotes用于读取全局笔记而GuiGetDebuggeeNotes用于读取当前调试目标的本地笔记。两者的函数签名完全一致仅消息与存储通道不同。void GuiGetGlobalNotes(char** text);该函数在 src/bridge/bridgemain.h 中与其余三个笔记相关接口一同声明BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text); BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text); BRIDGE_IMPEXP void GuiSetDebuggeeNotes(const char* text); BRIDGE_IMPEXP void GuiGetDebuggeeNotes(char** text);所有以Gui前缀开头的函数都属于 GUI 桥接层插件可在任意线程调用桥接层负责将调用安全地投递到 GUI 线程处理。参数与返回值语义text参数输出text是一个指向char*的指针即“指针的指针”。函数返回后*text将指向一个包含全局笔记内容的以\0结尾的 UTF-8 字符串缓冲区。返回值该函数不返回任何值笔记内容完全通过text输出参数带出。这一点与多数返回值型 API 不同调用方必须通过检查指针是否为nullptr来判断是否成功取得内容。内存管理约定返回的缓冲区由 x64dbg 内部GUI 侧分配调用方不得直接free或delete而应使用 x64dbg 提供的BridgeFree释放。这一约定在官方示例中体现得十分明确char* text nullptr; GuiGetGlobalNotes(text); if(text) { // do something with text BridgeFree(text); }BridgeFree是桥接层统一提供的释放函数与桥接层内部使用的分配器配对可避免跨模块DLL 边界堆损坏问题。这是编写 x64dbg 插件时必须遵守的黄金法则凡是由Gui桥接函数返回的指针一律用BridgeFree释放。完整示例读取并处理全局笔记将上述片段扩展为一段可直接嵌入插件的代码#include bridgemain.h void ReadGlobalNotes() { char* text nullptr; GuiGetGlobalNotes(text); if(text) { // 将笔记输出到 x64dbg 日志窗口 dprintf(Global notes:\n%s\n, text); BridgeFree(text); // 必须使用 BridgeFree 释放 } else { dprintf(No global notes available.\n); } }同理读取调试目标笔记只需替换函数名char* text nullptr; GuiGetDebuggeeNotes(text); if(text) { dprintf(Debuggee notes:\n%s\n, text); BridgeFree(text); }底层实现消息桥接机制从源码结构看GuiGetGlobalNotes的实现非常轻量它本身不做任何存储操作只是把调用封装成一条跨线程消息发送给 GUI// src/bridge/bridgemain.cpp BRIDGE_IMPEXP void GuiGetGlobalNotes(char** text) { _gui_sendmessage(GUI_GET_GLOBAL_NOTES, text, nullptr); }见 src/bridge/bridgemain.cpp。与之对应的写入接口同样如此BRIDGE_IMPEXP void GuiSetGlobalNotes(const char* text) { _gui_sendmessage(GUI_SET_GLOBAL_NOTES, (void*)text, nullptr); }消息枚举GUI_GET_GLOBAL_NOTES、GUI_SET_GLOBAL_NOTES、GUI_GET_DEBUGGEE_NOTES、GUI_SET_DEBUGGEE_NOTES定义于 src/bridge/bridgemain.h是桥接层协议的一部分。GUI 侧处理同步等待在 GUI 侧Bridge.cpp的Bridge::WinMsgGlobalMessage中处理这些消息。读取类消息采用同步等待模式GUI 线程处理完请求后调用线程才会继续// src/gui/Src/Bridge/Bridge.cpp case GUI_GET_GLOBAL_NOTES: { BridgeResult result(BridgeResult::GetGlobalNotes); emit getGlobalNotes(param1); result.Wait(); // 阻塞等待 GUI 线程完成填充 } break; case GUI_SET_GLOBAL_NOTES: { QString text QString((const char*)param1); emit setGlobalNotes(text); } break;见 src/gui/Src/Bridge/Bridge.cpp。BridgeResult是专门用于“从 GUI 请求数据并同步返回”的辅助类其类型枚举GetGlobalNotes、GetDebuggeeNotes定义于 src/gui/Src/Bridge/BridgeResult.h。数据真正存于何处NotesManagerGUI 侧真正持有笔记文本的是NotesManager组件src/gui/Src/Gui/NotesManager.cpp它是一个带两个标签页的QTabWidgetGlobal 标签页NotepadView实例mGlobal对应全局笔记Debuggee 标签页NotepadView实例mDebuggee对应调试目标笔记仅在调试初始化后才显示见dbgStateChangedSlot中根据initialized/stopped状态切换标签页的逻辑。NotepadView内部通过BridgeResult完成跨线程的数据回传setNotes/getNotes槽函数分别对应写入与读取。全局笔记与调试目标笔记的存储差异两类笔记的持久化路径完全不同这决定了它们的使用场景特性全局笔记Global调试目标笔记Debuggee存储位置用户目录下的notes.txt文件调试数据库database适用范围所有会话、所有目标仅当前被调试目标生命周期随 x64dbg 启停随调试目标保存/恢复读取接口GuiGetGlobalNotesGuiGetDebuggeeNotes写入接口GuiSetGlobalNotesGuiSetDebuggeeNotes全局笔记的持久化notes.txt全局笔记的读写发生在 x64dbg 调试器引擎的初始化与退出阶段启动时加载x64dbg.cpp中的DbgInit读取%USERDIR%\notes.txt若文件存在且读取成功则通过GuiSetGlobalNotes推送给 GUIsrc/dbg/x64dbg.cpp退出时保存通过GuiGetGlobalNotes取回 GUI 中的笔记文本再写入notes.txt若文本为空则删除该文件src/dbg/x64dbg.cpp。这一过程与官方用户文档的描述一致全局笔记存储在工作目录的notes.txt中任何输入都会被保存并在未来的调试会话中恢复见 docs/gui/views/Notes.rst。调试目标笔记的持久化调试数据库调试目标笔记的存取发生在调试数据库database的保存与加载流程中src/dbg/database.cpp加载dbLoad时调用GuiGetDebuggeeNotes取回当前文本随后写入数据库src/dbg/database.cpp保存从数据库读出笔记后通过GuiSetDebuggeeNotes推送回 GUIsrc/dbg/database.cpp新建目标初始化时用GuiSetDebuggeeNotes()清空笔记src/dbg/database.cpp。因此插件中若想为不同调试目标维护各自的上下文信息应当使用 Debuggee 笔记接口若信息对所有目标通用则使用 Global 笔记接口。关联接口速查本文涉及的四个笔记接口组成一个完整的读写闭环官方文档位于 docs/developers/functions/gui 目录下GuiSetGlobalNotes写入全局笔记GuiGetGlobalNotes读取全局笔记本文主题GuiSetDebuggeeNotes写入当前调试目标笔记GuiGetDebuggeeNotes读取当前调试目标笔记。常见使用注意事项必须判空未初始化或尚无笔记时*text可能为nullptr访问前务必判空必须用BridgeFree释放不要用free、delete或其他释放函数替代否则可能造成跨模块堆损坏同步阻塞语义GuiGetGlobalNotes会阻塞等待 GUI 线程完成数据填充不要在 GUI 线程内调用它以免死锁插件回调中若已在 GUI 线程也应避免在同一个消息处理中同步调用UTF-8 编码返回的字符串为 UTF-8 编码显示前若涉及宽字符转换需自行处理线程安全桥接层保证从任意线程调用都是安全的这是Gui系列接口的设计初衷。小结GuiGetGlobalNotes虽是一个“仅有一个输出参数、无返回值”的简单接口但其背后牵涉 x64dbg 的消息桥接协议、GUI 线程同步等待、BridgeFree内存管理约定以及notes.txt/ 调试数据库两套持久化机制。理解它的完整链路是掌握 x64dbg 插件 GUI API 编写规范的良好起点——同样的模式也适用于GuiGetDebuggeeNotes及其他所有“通过输出指针取回数据”的桥接函数。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表