IDA C++ Plug-in 浅尝
0x00 相关
ida 的c++插件的实质就是一个动态链接库,即Windows 的DLL文件,Linux 的SO文件和Mac的dylib文件。与普通动态链接库相比,IDA 的C++插件需要导出一个类型为plugin_t
导出名称为PLUGIN
的结构体变量。
0x01 环境
os : Windows 10 x64
SDK : ida sdk 75
ide : Microsoft Visual Studio 2017
0x02 细节
前面说到,ida 的C++ 插件必须导出plugin_t PLUGIN
结构体变量,其详细定义如下:
//头文件 loader.hpp
class plugin_t
{
public:
int version; //接口版本填充 IDP_INTERFACE_VERSION 就好
int flags; //加载条件标志
plugmod_t *(idaapi *init)(void); //初始化函数,首次加载插件时调用
void (idaapi *term)(void); //销毁函数,卸载插件时调用,可置NULL
bool (idaapi *run)(size_t arg); //激活函数,当ida中激活该插件时调用
const char *comment; //非本文非关键
const char *help; //非本文非关键
const char *wanted_name; //插件名称,在Edit->Plugs 中显示的名称
const char *wanted_hotkey; //插件激活快捷键
};
-
version:指示接口版本,填充
IDP_INTERFACE_VERSION
-
flags:加载条件标志,可选项有以下几个,该值可以是多个标志的集合,一般来说填0就够了,但该标志可以控制插件加载时机。
#define PLUGIN_MOD 0x0001 //插件会修改数据库,当处理器模式不允许修改时,比应该使用该标志
#define PLUGIN_DRAW 0x0002 //加载插件后。ida重新分析所有内容
#define PLUGIN_SEG 0x0004 //当前地址属于某一个程序段时加载
#define PLUGIN_UNL 0x0008 //该插件运行一次run函数后就被卸载
#define PLUGIN_HIDE 0x0010 //插件不会出现在菜单栏
#define PLUGIN_DBG 0x0020 //调试插件
#define PLUGIN_PROC 0x0040 //当选中一个处理器模式时,加载该插件并且驻留,直到退出处理器模式时卸载该插件
#define PLUGIN_FIX 0x0080 //当ida启动时加载插件,直到ida退出时,卸载插件
#define PLUGIN_MULTI 0x0100 //插件可以使用多个idb文件
#define PLUGIN_SCRIPTED 0x8000 //脚本插件,不使用,由ida 设置
注:当使用PLUGIN_PROC
标志时,插件会获得较早的加载时机
-
init:初始化函数,在此可以做一些资源的初始化操作,判断是否加载该插件等,其返回值有三个选择:
#define PLUGIN_SKIP nullptr //不加载插件
#define PLUGIN_OK ((plugmod_t *)1) //用户使用菜单或快捷键时加载插件
#define PLUGIN_KEEP ((plugmod_t *)2) //加载插件并驻留内存
-
term:销毁函数,卸载插件时调用此函数 -
run:激活函数,当用户使用菜单或快捷键激活插件时调用 -
wanted_name:插件名称,在Edit->Plugs 中显示的名称 -
wanted_hotkey:插件激活快捷键
对于插件的激活,这里分为两种的:一种是主动的菜单或快捷键激活,另一种是被动的事件通知
-
第一种是由用户选择调用时机,使用菜单或快捷键激活调用run函数快捷键和在Edit->Plugs中显示的名称在PLUGIN中指定
-
第二种是回调函数通知方式,当需要捕捉某个特定时机时,被注册的回调函数被激活使用
hook_to_notification_point
注册回调,使用unhook_from_notification_point
删除回调
//相关事件枚举值
enum hook_type_t
{
HT_IDP, ///< Hook to the processor module.
///< The callback will receive all processor_t::event_t events.
HT_UI, ///< Hook to the user interface.
///< The callback will receive all ::ui_notification_t events.
HT_DBG, ///< Hook to the debugger.
///< The callback will receive all ::dbg_notification_t events.
HT_IDB, ///< Hook to the database events.
///< These events are separated from the ::HT_IDP group
///< to speed things up (there are too many plugins and
///< modules hooking to the ::HT_IDP). Some essential events
///< are still generated in th ::HT_IDP group:
///< make_code, make_data
///< This list is not exhaustive.
///< A common trait of all events in this group: the kernel
///< does not expect any reaction to the event and does not
///< check the return code. For event names, see ::idb_event.
HT_DEV, ///< Internal debugger events.
///< Not stable and undocumented for the moment
HT_VIEW, ///< Custom/IDA views notifications.
///< Refer to ::view_notification_t
///< for notification codes
HT_OUTPUT, ///< Output window notifications.
///< Refer to ::msg_notification_t
///< (::view_notification_t)
HT_GRAPH, ///< Handling graph operations
///< (::graph_notification_t)
HT_IDD, ///< Hook to the debugger plugin.
///< The callback will receive all debugger_t::event_t events.
HT_LAST
};
//hook_to_notification_point和unhook_from_notification_point定义如下
idaman bool ida_export hook_to_notification_point(
hook_type_t hook_type, //事件
hook_cb_t *cb, //回调函数
void *user_data = NULL);
idaman int ida_export unhook_from_notification_point(
hook_type_t hook_type, //事件
hook_cb_t *cb, //回调函数
void *user_data = NULL);
grcode_dblclicked
插件除了能够调用IDA SDK中的接口函数外,也能够调用平台相关的API(eg. Windows - MessageBox)
0x03 环境设置
-
创建动态链接库项目
2.设置包含SDK 头文件
__IDP__
;__X64__
;__NT__
,其他平台设置参考pro.h
头文件__stdcall
0x04 完整代码
#include "pch.h"
#include "ida.hpp"
#include "idp.hpp"
#include "loader.hpp"
#pragma comment(lib, "ida.lib")
# define __EA64__
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
ssize_t idaapi hook_func(void *user_data, int notification_code, va_list va)
{
if (notification_code == view_notification_t::view_click)
{
msg("Current address is : 0x%pn", get_screen_ea());
}
return 0;
}
plugmod_t* IDAP_init(void)
{
hook_to_notification_point(HT_VIEW, hook_func, NULL);
msg("==================code by MinL@Syclover==================n");
return PLUGIN_KEEP;
}
void IDAP_term(void)
{
msg("==================code by MinL@Syclover==================n");
unhook_from_notification_point(HT_OUTPUT, hook_func, NULL);
}
bool IDAP_run(size_t arg)
{
msg("Current address is : 0x%pn", get_screen_ea());
msg("IDA Plug is running!n");
return TRUE;
}
char IDAP_comment[] = "This is my test plug-in";
char IDAP_help[] = "MinL plugin";
char IDAP_name[] = "MinL plugin";
char IDAP_hotkey[] = "Ctrl-Alt-l";
//导出变量
//#define ida_module_data __declspec(dllexport)
ida_module_data plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
0,
IDAP_init,
IDAP_term,
IDAP_run,
IDAP_comment,
IDAP_help,
IDAP_name,
IDAP_hotkey
};
整体功能十分简单,在output window 输出在view 中选定的地址,使用了两种方式激活插件,一是设置快捷键为Ctrl-Alt-l,二是安装了事件通知回调
效果如下:
参考
-
《IDA Pro权威指南 第2版 》 17章节 -
SDK 官方文档 https://www.hex-rays.com/products/ida/support/sdkdoc/index.html -
SDK 下载链接 https://bbs.pediy.com/thread-261011-1.htm
长
按
关
注
三叶草小组公众号
微信号 : 三叶草小组Syclover
新浪微博:@三叶草小组Syclover
点击原文链接查看更多〜
本文始发于微信公众号(三叶草小组Syclover):IDA C++ Plug-in 浅尝
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论