IDA Pro 加载 C++ 插件需满足架构与SDK版本匹配,导出含正确 plugin_t 结构及 init/run/term 函数的 .dll(Windows)或 .so(Linux/macOS),置于 plugins/ 目录,避免依赖冲突与线程不安全调用。

IDA Pro 里怎么加载 C++ 插件(.dll / .so)
IDA Pro 的插件必须匹配 IDA 版本架构(x64 IDA 只能加载 x64 插件)和 SDK 版本,C++ 编写的插件本质是导出特定函数的动态库,IDA 启动时按约定符号查找入口。
-
plugin_t结构体必须正确定义,init、run、term三个函数指针不能为nullptr,否则 IDA 直接忽略该插件 - Windows 下插件后缀必须是
.dll,Linux/macOS 是.so;文件名不能含空格或特殊字符,否则 IDA 日志里只显示“failed to load”但不报错原因 - 插件需放在
plugins/子目录下(不是根目录),路径错误时 IDA 完全不扫描——可打开File → Script file…看是否能手动选中,来快速验证路径和权限 - 依赖的运行时(如
msvcp140.dll)必须与 IDA 自带的 VC 运行时兼容;IDA 7.5+ 默认用 VS2019 工具链,用 VS2022 编译的插件大概率因 ABI 不兼容而崩溃
Python 脚本调用 C++ 函数(比如解析 vtable 或 demangle)
纯 Python 在 IDA 里处理 C++ 符号效率低,常见做法是把耗时逻辑写成 C++ 扩展模块,再用 idaapi.require 或 import 加载。关键不是“能不能调”,而是“怎么让 Python 安全拿到 C++ 返回的内存数据”。
- C++ 模块导出的函数返回值尽量用基本类型(
int、size_t)或固定长度数组;避免返回std::string或std::vector,Python 无法自动析构,容易内存泄漏 - IDAPython 的
idc.get_strlit_contents和idc.get_cmt是线程安全的,但你自己写的 C++ 函数若调用 IDA API(如get_name),必须确保在主线程执行——脚本里用ida_kernwin.execute_sync包一层 - demangle 场景下,别直接调
__cxa_demangle(Linux)或UnDecorateSymbolName(Windows),IDA 自带的demangle_name更可靠:它已适配了 IDA 的符号缓存机制,重复调用不会反复解析
插件读取 C++ 类信息失败:常见 IDA 类型系统陷阱
IDA 的 ida_typeinf 模块能解析 PDB 或 DWARF,但 C++ 类结构(尤其是虚函数表、多重继承、模板实例化)极易解析不全。不是插件写错了,而是 IDA 本身对某些编译器生成的调试信息支持有限。
- Clang/LLVM 编译的二进制,若没带
-grecord-gcc-switches,IDA 可能完全看不到成员函数参数类型,get_tinfo返回空 —— 此时应优先检查idc.get_type是否能拿到原始字符串,再手工补全 - MSVC 编译的 64 位程序,虚表偏移常被优化掉(
/d2noftol除外),IDA 显示的vftable地址可能是 stub,实际跳转目标需要结合ida_xref追踪call [rax]指令才能确认 - 使用
ida_struct.get_struc_id获取类结构体 ID 后,务必用ida_struct.get_struc_size校验大小;某些模板类(如std::vector<int>)在不同 STL 版本中 padding 不同,硬编码偏移会错位
脚本热重载失败:为什么改完 Python 再 run 还是旧逻辑
IDAPython 缓存模块对象,import 过的模块不会自动 reload,尤其当插件内部又 import 了另一个 .py 文件时,修改后者根本不起作用。
立即学习“C++免费学习笔记(深入)”;
- 强制重载要用
importlib.reload,但前提是模块已存在于sys.modules—— 建议脚本开头加if 'my_plugin' in sys.modules: importlib.reload(sys.modules['my_plugin']) - IDAPython 的
exec执行代码块时,变量作用域隔离,里面定义的函数无法被后续脚本调用;想调试 C++ 插件回调,得把逻辑封装进类方法,再通过全局变量暴露句柄 - 最隐蔽的坑:IDA 的
Script file…对话框默认勾选 “Run in new thread”,而 C++ 插件注册的 UI 回调(如add_toolbar_button)只能在主线程触发 —— 关掉这个选项,否则按钮点了没反应,还以为插件没生效
复杂点在于 C++ 插件和 Python 脚本的生命周期不一致:插件加载一次就驻留,Python 模块却可能被反复 reload;两者共享的数据(比如全局 map)若没加锁或没用 IDA 提供的线程安全容器(qmutex_t),很容易 crash。



















