标题: 如何手工执行IDA插件 创建: 2018-01-29 00:00 更新: 2018-01-30 12:22 链接: https://scz.617.cn/misc/201801290000.txt 有天因故问了hume一个问题,重新执行eh_parse.dll、eh_parse64.dll,这个动作怎 么完成?hume当时的回答是: 这个插件只能用RunPlugin()之类的函数重新执行,"Edit->Plugins"里没有它。但是 还得看插件的run函数怎么写的,如果是Hook到一些IDA事件上,就得看能不能想办法 触发这些事件,所以得逆向插件看了才能找到办法。 本文介绍如何逆向eh_parse64.dll,找出run函数所在,进而确定手工执行方案。 参看 SDK tryblks.hpp python\ida_tryblks.py plugins\eh_parse.dll plugins\eh_parse64.dll 关于run_plugin(),参看 python\ida_loader.py load_and_run_plugin() run_plugin() python\idc.py load_and_run_plugin() python\idc_bc695.py RunPlugin() 从未写过C版本的IDA插件。下面只是简单地记录一下我是如何在完全无知的情况下定 位eh_parse64.dll的run函数的。 翻了一下SDK,找到: plugins\hello\hello.cpp 内容很简单,两个函数,一个结构: -------------------------------------------------------------------------- /* * 固定的初始化函数 */ int idaapi init ( void ) { return( PLUGIN_OK ); } /* * 插件的主代码所在 */ bool idaapi run ( size_t ) { ... return( true ); } /* * 向IDA注册用的结构 */ plugin_t PLUGIN = { /* * 这个值应该随SDK版本而变化 */ IDP_INTERFACE_VERSION, // +0x0 700(0x2BC) PLUGIN_UNL, // +0x4 plugin flags, 0x0008 init, // +0x8 initialize NULL, // +0x10 terminate. this pointer may be NULL. run, // +0x18 invoke plugin NULL, // +0x20 long comment about the plugin NULL, // +0x28 multiline help about the plugin "Hello, world", // +0x30 the preferred short name of the plugin NULL // +0x38 the preferred hotkey to run the plugin // +0x40 }; -------------------------------------------------------------------------- 看过hello.cpp,假设所有的插件都有一个PLUGIN结构,其第一个4字节成员都是接口 版本,就目前的测试环境,该值等于0x000002BC。 用IDA反汇编eh_parse64.dll,在"Hex View-1"中搜索"BC 02",果然只找到一处,那 肯定是PLUGIN所在: -------------------------------------------------------------------------- 00000000152C4000 BC 02 00 00 PLUGIN dd 2BCh /* * PLUGIN_MOD | PLUGIN_HIDE | PLUGIN_PROC */ 00000000152C4004 51 00 00 00 dd 51h /* * init() */ 00000000152C4008 40 10 2B 15 00 00 00 00 dq offset init_152B1040 00000000152C4010 60 10 2B 15 00 00 00 00 dq offset sub_152B1060 /* * run() */ 00000000152C4018 00 10 2B 15 00 00 00 00 dq offset run_152B1000 /* * Load debug information from a TDS file */ 00000000152C4020 A0 E4 2B 15 00 00 00 00 dq offset aLoadDebugInfor /* * EH parse\n\nThis module allows you to parse EH information from a file.\n */ 00000000152C4028 D0 E4 2B 15 00 00 00 00 dq offset aEhParseThisMod /* * EH parse file */ 00000000152C4030 18 E5 2B 15 00 00 00 00 dq offset aEhParseFile 00000000152C4038 26 E5 2B 15 00 00 00 00 dq offset unk_152BE526 -------------------------------------------------------------------------- 注意到该位置已有符号PLUGIN,最后确认这是导出符号,因此没有必要搜"BC 02"。 其第2个成员,在loader.hpp中查到: -------------------------------------------------------------------------- #define PLUGIN_MOD 0x0001 ///< Plugin changes the database. ///< IDA won't call the plugin if ///< the processor module prohibited any changes. #define PLUGIN_HIDE 0x0010 ///< Plugin should not appear in the Edit, Plugins menu. ///< This flag is checked at the start. #define PLUGIN_PROC 0x0040 ///< Load plugin when a processor module is loaded. (and keep it ///< until the processor module is unloaded) -------------------------------------------------------------------------- 由于PLUGIN_HIDE置位,所以"Edit->Plugins"里没有它。 -------------------------------------------------------------------------- int init_152B1040 () { hook_to_notification_point( 0, sub_152B10A0, 0 ); /* * 2 */ return( PLUGIN_KEEP ); } bool run_152B1000 ( bool sth ) { /* * 检查全局变量inf的某成员 */ if ( inf.xxx ) { if ( sth ) { return( false ); } sub_152B1670(); sub_152B94A0(); sub_152B93F0(); } return( true ); } -------------------------------------------------------------------------- 尽管init()中确有Hook动作,但从run()的流程判断,可以直接执行: load_and_run_plugin("eh_parse64",0) 对于熟悉C版IDA插件编写的人来说,前面的都是废话,我就是讲讲一无所知的情况下 我是怎么做的。