首页
社区
课程
招聘
[原创]Ollydbg插件的编写流程
发表于: 2018-10-17 21:28 15150

[原创]Ollydbg插件的编写流程

2018-10-17 21:28
15150

1. 找到”我的文档”目录

2. 在我的文档中找到vs版本对应的文件夹

3. 把模板复制到”我的文档”\Visual studio 20XX\Templates\ProjectTemplates\

4. 打开VS,新建一个项目

5. 修改项目属性:


         调试工具的插件是一项特别重要的扩展功能,本篇本章总结了简单的插件编写流程。

  • 开发工具 VS2015
  • 调试工具Ollydbg2.01   
  • 用到的工具 源代码放到附件



  • 基本原理
Ollydbg插件其实是一个导出有指定函数的DLL文件,按照指定名称,导出的函数会在Ollydbg执行到某一阶段或触发某个事件时主动调用。
Ollydbg插件其实是一个导出有指定函数的DLL文件,按照指定名称,导出的函数会在Ollydbg执行到某一阶段或触发某个事件时主动调用。

  • Ollydbg需要插件导出的函数
ODBG2_Pluginquery() 是一个必选的导出函数,其余函数可以不导出.。
ODBG2_Pluginquery() 是一个必选的导出函数,其余函数可以不导出.。
ODBG2_Pluginquery() 是一个必选的导出函数,其余函数可以不导出.。

ODBG2_Pluginquery()://判断插件所需要的API版本,如果不能满足则卸载此插件
ODBG2_Plugininit()://当插件通过版本检测后准备加载时,OllyDBG会调用此函数
ODBG2_Pluginoptions()://打开插件对话框时,OllyDBG调用此函数,并派发消息
ODBG2_Pluginreset()://当重新加载程序或打开新程序时,OllyDBG会调用此函数
ODBG2_Pluginuddrecord()://当加载UDD文件或遇到插件预先保存的数据,OllyDBG会针对每条记录分别调用此函ODBG2_Pluginanalyse()://分析模块时,在分析结束后OllyDBG会调用此函数,给插件以机会使之能做一些额外的分析操作ODBG2_Pluginmainloop(NULL)://OllyDBG会周期性地调用此函数
ODBG2_Pluginmainloop()://任意事件传递过来时都会传递给此函数
ODBG2_Pluginexception()://事件是EXCEPTION_DEBUG_EVENT则调用此函数
ODBG2_Plugintempbreakpoint()://插件请求设置的临时断点事件会调用此函数
ODBG2_Pluginnotify()://一些其他的重要事件发生时,OllyDBG会调用此函数
ODBG2_Plugindump()://当OllyDBG重绘其他转储窗口时会调用此函数,插件可以借此机会修改这些窗口的字体或外ODBG2_Pluginmenu()://在点击窗口主菜单或点击右键以期望弹出菜单时,OllyDBG将调用此函数,并将函数返回的数据添加的将要弹出的菜单中
ODBG2_Pluginsaveudd()://当Windows从内存中卸载模块时,OllyDBG会调用此函数,以便插件能将相关数据保存到UDD文件中
ODBG2_Pluginclose()://当用户关闭调试时,OllyDBG在关闭前会调用此函数
ODBG2_Plugindestroy()://当OllyDBG将要终止时,它会在退出前调用一次此

ODBG2_Pluginquery()://判断插件所需要的API版本,如果不能满足则卸载此插件
ODBG2_Plugininit()://当插件通过版本检测后准备加载时,OllyDBG会调用此函数
ODBG2_Pluginoptions()://打开插件对话框时,OllyDBG调用此函数,并派发消息
ODBG2_Pluginreset()://当重新加载程序或打开新程序时,OllyDBG会调用此函数
ODBG2_Pluginuddrecord()://当加载UDD文件或遇到插件预先保存的数据,OllyDBG会针对每条记录分别调用此函ODBG2_Pluginanalyse()://分析模块时,在分析结束后OllyDBG会调用此函数,给插件以机会使之能做一些额外的分析操作ODBG2_Pluginmainloop(NULL)://OllyDBG会周期性地调用此函数
ODBG2_Pluginmainloop()://任意事件传递过来时都会传递给此函数
ODBG2_Pluginexception()://事件是EXCEPTION_DEBUG_EVENT则调用此函数
ODBG2_Plugintempbreakpoint()://插件请求设置的临时断点事件会调用此函数
ODBG2_Pluginnotify()://一些其他的重要事件发生时,OllyDBG会调用此函数
ODBG2_Plugindump()://当OllyDBG重绘其他转储窗口时会调用此函数,插件可以借此机会修改这些窗口的字体或外ODBG2_Pluginmenu()://在点击窗口主菜单或点击右键以期望弹出菜单时,OllyDBG将调用此函数,并将函数返回的数据添加的将要弹出的菜单中
ODBG2_Pluginsaveudd()://当Windows从内存中卸载模块时,OllyDBG会调用此函数,以便插件能将相关数据保存到UDD文件中
ODBG2_Pluginclose()://当用户关闭调试时,OllyDBG在关闭前会调用此函数
ODBG2_Plugindestroy()://当OllyDBG将要终止时,它会在退出前调用一次此


  • 模板的使用
将附件中的模板导入到VS文件目录下。
将附件中的模板导入到VS文件目录下。

1. 找到”我的文档”目录

2. 在我的文档中找到vs版本对应的文件夹

3. 把模板复制到”我的文档”\Visual studio 20XX\Templates\ProjectTemplates\

4. 打开VS,新建一个项目

     

5. 修改项目属性:







  • 插件编写过程


1. 导出一个必选的函数
pentry(int)
ODBG2_Pluginquery(int ollydbgversion, /*OD自身的版本号*/
ulong *features,/*保留*/
wchar_t pluginname[SHORTNAME],/*插件的名字,需要函
数内部自己填充*/
wchar_t pluginversion[SHORTNAME])/*插件的版本号,
需要函数内部自己填充,版本号没有要求*/
{
// 初始化插件的名字和版本号.
wcscpy_s(pluginname, SHORTNAME, L"第一个OD插件");
wcscpy_s(pluginversion, SHORTNAME, L"0.1");
return PLUGIN_VERSION;// 返回当前使用的API版本
}

pentry(int)
ODBG2_Pluginquery(int ollydbgversion, /*OD自身的版本号*/
ulong *features,/*保留*/
wchar_t pluginname[SHORTNAME],/*插件的名字,需要函
数内部自己填充*/
wchar_t pluginversion[SHORTNAME])/*插件的版本号,
需要函数内部自己填充,版本号没有要求*/
{
// 初始化插件的名字和版本号.
wcscpy_s(pluginname, SHORTNAME, L"第一个OD插件");
wcscpy_s(pluginversion, SHORTNAME, L"0.1");
return PLUGIN_VERSION;// 返回当前使用的API版本
}

2. 给OD添加菜单需要导出一个函数
/*!
* \brief ODBG2_Pluginmenu [OD插件可选导出函数]
* 点击窗口主菜单或点击右键以期望弹出菜单时,OllyDBG将调用此函数,并将
函数返回的数据添加到将要弹出的菜单中
* \param wchar_t * type 准备弹出菜单的窗口的名字,以PWM_xxx系列宏来表
示
* \return 返回需要添加的菜单结构体数组, 数组必须以一个全0的元素为结
尾.
* PWM_ATTACH ‐进程附加区
* PWM_BPHARD ‐ 硬件断点区
* PWM_BPMEM ‐ 内存断点区
* PWM_BPOINT ‐ INT3 断点区
* PWM_DISASM ‐ 反汇编窗口
* PWM_DUMP ‐ 所有的dump区(除了反汇编去和栈区)
* PWM_INFO ‐ 寄存器信息菜单
* PWM_LOG ‐ 日志窗口
* PWM_MAIN ‐ 主菜单
* PWM_MEMORY ‐ 内存窗口
* PWM_MODULES ‐ 模块窗口
* PWM_NAMELIST ‐ 标签列表窗口
* PWM_PATCHES ‐ 补丁列表窗口
* PWM_PROFILE ‐ Profile window
* PWM_REGISTERS ‐ 寄存器窗口
* PWM_SEARCH ‐ 搜索控件
* PWM_SOURCE ‐ 源代码窗口
* PWM_SRCLIST ‐ 源代码列表窗口
* PWM_STACK ‐ CPU栈信息面板
* PWM_THREADS ‐ 线程窗口
* PWM_TRACE ‐ Run跟踪窗口
* PWM_WATCH ‐ 监视窗口
* PWM_WINDOWS ‐ list of windows owned by the debugged
application
*/
pentry(t_menu *) ODBG2_Pluginmenu(wchar_t *type)
{
// 菜单数组必须以全0元素结尾
static t_menu menu[2] = { 0 };
menu[0].name = L"第一个插件的菜单";
menu[0].index = 100;
// Lambda函数:
// [] + () + {}
// [] : 捕获列表
// () : 参数列表
// {} : 函数体
// () 和 {} 之间 ‐> 数据类型 表示函数的返回值类型
// int MENUFUNC(struct t_table*,wchar_t*,ulong,int);
menu[0].menufunc =
[](struct t_table*, wchar_t*, ulong id, int model)‐>int {
if (model == MENU_VERIFY) {
return MENU_NORMAL;
}
switch (id)
{
case 100: {
MessageBox(0, L"菜单被点击", 0, 0);
}break;
case 101:
MessageBox(0, L"反汇编窗口菜单被点击", 0, 0);
break;
default:
break;
}
return MENU_ABSENT;
};
static t_menu menu2[2] = { 0 };
menu2[0].name = L"xxxx";
menu2[0].index = 101;
menu2[0].menufunc = menu[0].menufunc;
// 判断调用当前函数的时候, 弹出菜单的位置是否是主菜单
// 如果是才返回菜单, 否则就不返回了.
if (wcscmp(type, PWM_MAIN) == 0) {
return menu;
}
else if (wcscmp(type, PWM_DISASM) == 0) {
return menu2;
}
return NULL;
}


/*!
* \brief ODBG2_Pluginmenu [OD插件可选导出函数]
* 点击窗口主菜单或点击右键以期望弹出菜单时,OllyDBG将调用此函数,并将
函数返回的数据添加到将要弹出的菜单中
* \param wchar_t * type 准备弹出菜单的窗口的名字,以PWM_xxx系列宏来表
示
* \return 返回需要添加的菜单结构体数组, 数组必须以一个全0的元素为结
尾.
* PWM_ATTACH ‐进程附加区
* PWM_BPHARD ‐ 硬件断点区
* PWM_BPMEM ‐ 内存断点区
* PWM_BPOINT ‐ INT3 断点区
* PWM_DISASM ‐ 反汇编窗口
* PWM_DUMP ‐ 所有的dump区(除了反汇编去和栈区)
* PWM_INFO ‐ 寄存器信息菜单
* PWM_LOG ‐ 日志窗口
* PWM_MAIN ‐ 主菜单
* PWM_MEMORY ‐ 内存窗口
* PWM_MODULES ‐ 模块窗口
* PWM_NAMELIST ‐ 标签列表窗口
* PWM_PATCHES ‐ 补丁列表窗口
* PWM_PROFILE ‐ Profile window
* PWM_REGISTERS ‐ 寄存器窗口
* PWM_SEARCH ‐ 搜索控件
* PWM_SOURCE ‐ 源代码窗口
* PWM_SRCLIST ‐ 源代码列表窗口
* PWM_STACK ‐ CPU栈信息面板
* PWM_THREADS ‐ 线程窗口
* PWM_TRACE ‐ Run跟踪窗口
* PWM_WATCH ‐ 监视窗口
* PWM_WINDOWS ‐ list of windows owned by the debugged
application
*/
pentry(t_menu *) ODBG2_Pluginmenu(wchar_t *type)
{
// 菜单数组必须以全0元素结尾
static t_menu menu[2] = { 0 };
menu[0].name = L"第一个插件的菜单";
menu[0].index = 100;
// Lambda函数:
// [] + () + {}
// [] : 捕获列表
// () : 参数列表
// {} : 函数体
// () 和 {} 之间 ‐> 数据类型 表示函数的返回值类型
// int MENUFUNC(struct t_table*,wchar_t*,ulong,int);
menu[0].menufunc =
[](struct t_table*, wchar_t*, ulong id, int model)‐>int {
if (model == MENU_VERIFY) {
return MENU_NORMAL;
}
switch (id)
{
case 100: {
MessageBox(0, L"菜单被点击", 0, 0);
}break;
case 101:
MessageBox(0, L"反汇编窗口菜单被点击", 0, 0);
break;
default:
break;
}
return MENU_ABSENT;
};
static t_menu menu2[2] = { 0 };
menu2[0].name = L"xxxx";
menu2[0].index = 101;
menu2[0].menufunc = menu[0].menufunc;
// 判断调用当前函数的时候, 弹出菜单的位置是否是主菜单
// 如果是才返回菜单, 否则就不返回了.
if (wcscmp(type, PWM_MAIN) == 0) {
return menu;
}
else if (wcscmp(type, PWM_DISASM) == 0) {
return menu2;
}
return NULL;
}


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2018-10-27 11:45 被Jabez编辑 ,原因:
上传的附件:
收藏
免费 5
支持
分享
打赏 + 1.00雪花
打赏次数 1 雪花 + 1.00
 
赞赏  junkboy   +1.00 2018/10/17
最新回复 (20)
雪    币: 11716
活跃值: (133)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢分享
2018-10-17 21:59
0
雪    币: 44
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
谢谢分享 ...
2018-10-17 23:56
0
雪    币: 407
活跃值: (566)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2018-10-18 01:17
0
雪    币: 7352
活跃值: (4552)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错,谢谢你的共享精神
2018-10-18 08:54
0
雪    币: 18
活跃值: (80)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
2018-10-18 09:39
0
雪    币: 3738
活跃值: (3872)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
感谢分享
2018-10-18 10:06
0
雪    币: 6575
活跃值: (4531)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
8
很详细,感谢分享
2018-10-18 10:09
0
雪    币: 238
活跃值: (49)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sbd
9
感谢
2018-10-18 11:21
0
雪    币: 3181
活跃值: (1801)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
模板很棒
2018-10-18 14:54
0
雪    币: 5596
活跃值: (2173)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
感谢分享!
2018-10-19 08:42
0
雪    币: 120
活跃值: (1597)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享~~
2018-10-22 15:48
0
雪    币: 2265
活跃值: (2381)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
支持楼主。
2018-10-25 08:54
0
雪    币: 189
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
我是菜鸟问下,调试工具Ollydbg2.01   附件里有没有?
2018-10-26 20:44
0
雪    币: 2305
活跃值: (332)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
gameuu 我是菜鸟问下,调试工具Ollydbg2.01 附件里有没有?
我重新传了一下
2018-10-27 11:45
0
雪    币: 189
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
谢谢了,学习中。
2018-10-27 20:34
0
雪    币: 189
活跃值: (121)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
原本以为只是配置,没想到需要WINDOWS编程基础。。好吧,我忘了;
2018-10-27 20:48
0
雪    币: 24
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
vs2017能用吗
2018-10-30 21:55
0
雪    币: 2305
活跃值: (332)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
19
旖旎中子 vs2017能用吗
应该没问题  你可以试试
2018-10-31 19:30
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
vs2008  可以吗??
2018-11-3 10:19
0
雪    币: 193
活跃值: (1215)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
谢谢分享错不错
2022-1-8 22:53
0
游客
登录 | 注册 方可回帖
返回
//