OllyDbg插件深入分析一
本帖最后由 元始天尊 于 2015-1-2 23:44 编辑第一章 初探OllyDbg1插件
官网http://www.ollydbg.de/给出了关于插件开发的信息。OllyDbg1.10的插件开发包在http://www.ollydbg.de/plug11.zip。该压缩包包含以下文件:
│ Bookmark.c OllyDbg书签插件源码,该插件支持调试程序时设置10个书签
│ Cmdexec.c OllyDbg命令行插件,该插件支持输入命令进行调试
│ Cmdline.rtf 命令行插件的帮助文件
│ Command.c
│ Ollydbg.def OllyDbg定义文件,某些编译器用之生成输入链接库ollydbg.lib
│ Plugin.h 插件公共头文件
│ Plugins.hlp 插件编写说明
(Win8.1打不开hlp的解决方法http://www.microsoft.com/zh-cn/download/details.aspx?id=40899)
│
├─Bc55 Borland C++系列编译器工程
│ BOOKMARK.MAK
│ CMDLINE.BPR
│ CMDLINE.CPP
│ CMDLINE.MAK
│ OLLYDBG.LIB
│ SAMPLE.BPR
│ SAMPLE.CPP
│
└─Vc50 Visual C++系列编译器工程,这也是本文所使用的开发环境
BOOKMARK.DSP
BOOKMARK.DSW
BOOKMARK.MAK
CMDLINE.DSP
CMDLINE.DSW
CMDLINE.MAK
OLLYDBG.LIB
一、基本原理
OllyDbgv1.10是OllyDbg1系列的最终版本,作者已停止开发,转而开发v2.0版本,新版本和1.xx版本是不兼容的,插件也是如此。对于1.xx版本,插件大体上通用,这几个版本的改动有:
lt_reg和t_bpoint结构体扩展
l新选项“总在最前”需要插件窗口特殊支持
lBrowsefilename支持保存文件对话框
插件是提供附加功能的DLL文件,位于OllyDbg目录下。OllyDbg启动时会逐个加载所有可用的DLL文件,检查名为_ODBG_Plugindata和_ODBG_Plugininit的入口点(输出函数),如果存在并且插件版本号兼容,OllyDbg会注册插件并在插件子菜单增加相应项。插件可以在反汇编、转储、堆栈、内存、模块、线程、断点、监视、参考、界面窗口、运行跟踪窗口增加菜单项和监视全局/局部快捷键。插件可以是MDI窗口;可以在.udd文件中写入模块相关的自定义数据;可以访问和修改ollydbg.ini的数据结构以描述调试信息。插件使用多个回调函数和OllyDbg通信,可以调用170+个插件API函数。插件接口不是面向对象的。
插件API函数不是线程安全的,没有实现临界区,插件创建的新线程不能调用这些函数,否则可能导致OllyDbg和程序崩溃。
二、编译
请将编译器按如下设置以便插件和OllyDbg通信,plugin.h会检查这些设置:
通过名称输出所有导出函数,而非序数
l 如果使用C++编译器则需要禁用导出函数的名称修饰(使用extern “C”)l 强制所有API函数和导出函数使用C格式调用_cdecll 强制所有结构体按字节对齐l 默认字符类型为unsigned型编译自定义插件会用到plugin.h ollydbg.lib,需要复制到工程目录中。
现在以VS2010为例介绍如何编写无任何功能的插件。首先建立一个Windows动态链接库的空项目,在工程属性中,选C/C++ -> 命令行,右侧“其它选项”加入“/J”。之后向工程添加helloworld.cpp,内容如下:
#include <windows.h>#include "Plugin.h" HINSTANCE hinst=NULL;BOOL WINAPIDllEntryPoint(HINSTANCE hi,DWORD reason,LPVOID reserved){//DLL入口点 if (reason==DLL_PROCESS_ATTACH) hinst=hi; return 1; } extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features){ MessageBox(NULL,"HelloWorld","HelloWorld",MB_OK); return 0;} extc int _export cdecl ODBG_Plugindata(char shortname) {//用于插件菜单中显示插件名 strcpy(shortname,"HelloWorld"); return PLUGIN_VERSION;}
编译得到的dll放到ollydbg根目录下,启动ollydbg就可以看到弹出对话框,同时插件菜单栏多了一项“Hello Wolrd”。
使用dumpbin或depends工具查看ollydbg.exe输出表,可以看到700+个函数,这些就是插件API函数。为何exe会导出函数呢?早在《理论科普:如何让exe输出函数之输出函数自导自演》http://www.0xaa55.com/forum.php?mod=viewthread&tid=777&extra=中我已介绍了这种情况,这里是一个应用实例。ollydbg这样使用是用于制作插件,将如设置断点、反编译等一些相对独立的模块,抽取出来,可供第三方调用。调用OllyDbg-API:欲调用OllyDbg导出函数(例如FuncA),首先在源文件中包含Plugin.h,并在调用之前增加代码“#pragmacomment(lib,"ollydbg.lib")”,同时将插件开发包Vc50目录下的ollydbg.lib拷贝到工程目录中。此外OllyDbg作者写的Plugin.h不适用于VS系列编译器,由于ollydbg.exe实际导出符号为下划线版本(_FuncA),而plugin.h声明的是无下划线形式,因此直接编译会出现链接问题,而作者仅对ODBG系列函数作出调整而未对OllyDbg-API声明作出相应调整,因此所有用到的OllyDbg-API都需要进行手工调整,先找到Plugin.h中这样的代码段:#define ODBG_Plugindata _ODBG_Plugindata#define ODBG_Plugininit _ODBG_Plugininit#define ODBG_Pluginmainloop_ODBG_Pluginmainloop#define ODBG_Pluginsaveudd _ODBG_Pluginsaveudd#define ODBG_Pluginuddrecord_ODBG_Pluginuddrecord#define ODBG_Pluginmenu _ODBG_Pluginmenu#define ODBG_Pluginaction _ODBG_Pluginaction#define ODBG_Pluginshortcut_ODBG_Pluginshortcut#define ODBG_Pluginreset _ODBG_Pluginreset#define ODBG_Pluginclose _ODBG_Pluginclose#define ODBG_Plugindestroy _ODBG_Plugindestroy#define ODBG_Paused _ODBG_Paused#define ODBG_Pausedex _ODBG_Pausedex#define ODBG_Plugincmd _ODBG_Plugincmd在其后加入自己的声明,如: #define Plugingetvalue _Plugingetvalue#define Getstatus _Getstatus这样方可正常编译链接。 生成ollydbg.lib:ollydbg.lib可以由插件根目录存在ollydbg.def文件手动生成,这里会用到VS编译器自带工具lib.exe,命令如下:lib/MACHINE:X86 /DEF:ollydbg.def 调试:写插件本身具有难度,然而调试OllyDbg运行插件似乎就更难了。然而我却不以为然,将OllyDbg拷贝到生成dll的目录中(前提是该版本OllyDbg读取插件的目录为自身根目录),设置工程属性=>调试=>命令,将拷贝后的OllyDbg文件路径写入该处,调试即可在DLL源码中断下。三、使用MFC开发OllyDbg1插件
上面介绍的是使用MSVC的Windows DLL工程的情况,而这里介绍如何结合MFC进行插件开发。经我测试,VS2010及之后的MFC,由于内部使用的ATL和/J编译指令冲突,因此无法编译,而VC6版本可以很好地编译。下面是开发步骤,以test为例:
1. 新建名为test的MFC DLL工程2. 在自动生成的StdAfx.h文件末尾加入 #inclue “Plugin.h” 同时将Plugin.h拷入工程目录3. 在test.cpp中添加ODBG_***导出函数4. 在调用OllyDbg导出函数之前,加入#pragma comment(lib,"ollydbg.lib")
四、插件生命周期
OllyDbg所规定的插件输出函数,其实正好反映了插件的生命周期,类似于窗口的生命周期,它与消息机制相关。下面通过实例得到插件生命周期:
#include <windows.h>#include "Plugin.h" extc int _export cdecl ODBG_Plugindata(char shortname) {//插件检测 strcpy(shortname,"菜单显示项"); MessageBox(NULL,"ODBG_Plugindata","",MB_OK); return PLUGIN_VERSION;} extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features){//插件初始化 MessageBox(NULL,"ODBG_Plugininit","",MB_OK); return 0;} extc int_export cdecl ODBG_Pluginmenu(int origin,char data,void *item){//初始化菜单项 MessageBox(NULL,"ODBG_Pluginmenu","",MB_OK); return 0;} extc int_export cdecl ODBG_Pluginclose(void){//用户关闭OllyDbg时触发 MessageBox(NULL,"ODBG_Pluginclose","",MB_OK); return 0;} extc void _export cdecl ODBG_Plugindestroy(void){//OllyDbg退出时触发 MessageBox(NULL,"ODBG_Plugindestroy","",MB_OK);}
结果为:
ODBG_Plugindata=> ODBG_Plugininit => ODBG_Pluginmenu => ODBG_Pluginclose => ODBG_Plugindestroy 本帖最后由 元始天尊 于 2015-1-2 23:42 编辑
附录一 OllyDbg1输出函数 按字母排序:
1 000054EFC _Addsorteddata
2 10005A60C _Addtolist
3 20007F284 _Analysecode
164 300031AD8 _Animate
4 4000054AC _Assemble
180 500077D8C _Attachtoactiveprocess
5 60005A474 _Broadcast
6 700076224 _Browsefilename
7 800054B20 _Calculatecrc
8 900015E60 _Checkcondition
9 A00008208 _Compress
10 B00053154 _Createdumpwindow
11 C0005B1F0 _Createlistwindow
181 D0009F260 _Createpatchwindow
126 E0008E720 _Createprofilewindow
165 F0008DD10 _Creatertracewindow
12 1000054D98 _Createsorteddata
166 11000795C8 _Createthreadwindow
167 120007A2D8 _Createwatchwindow
168 1300098E28 _Createwinwindow
13 140007D6B0 _Decodeaddress
127 150000BE78 _Decodeascii
14 1600015C4C _Decodecharacter
15 1700092E04 _Decodefullvarname
16 180000C2C8 _Decodeknownargument
17 1900064C38 _Decodename
18 1A0005DFE0 _Decoderange
19 1B0007E2A8 _Decoderelativeoffset
20 1C000789E0 _Decodethreadname
128 1D0000C0A4 _Decodeunicode
21 1E00008480 _Decompress
22 1F000558D0 _Defaultbar
23 2000019518 _Deletebreakpoints
169 2100008C08 _Deletehardwarebreakbyaddr
24 22000089EC _Deletehardwarebreakpoint
25 2300064FC8 _Deletenamerange
26 2400055414 _Deletenonconfirmedsorteddata
129 250008AD78 _Deleteruntrace
27 2600055224 _Deletesorteddata
28 2700055308 _Deletesorteddatarange
130 2800079844 _Deletewatch
29 290006395C _Demanglename
30 2A 00054CD8 _Destroysorteddata
31 2B00015F48 _Disasm
32 2C0007E940 _Disassembleback
33 2D0007EB0C _Disassembleforward
34 2E0006498C _Discardquicknames
170 2F0004CF54 _Dumpbackup
35 300005401C _Error
36 3100097724 _Expression
37 320007099C _Findallcommands
175 3300070BE8 _Findalldllcalls
131 34000710E4 _Findallsequences
38 350005DF00 _Finddecode
39 360005DF58 _Findfileoffset
40 370005DE80 _Findfixup
118 380001ABCC _Findhittrace
41 390006512C _Findimportbyname
42 3A00064F04 _Findlabel
43 3B00065074 _Findlabelbyname
44 3C00061A48 _Findmemory
45 3D0005DE18 _Findmodule
46 3E000649C0 _Findname
47 3F00064E5C _Findnextname
132 400001E510 _Findnextproc
119 410008BAB4 _Findnextruntraceip
133 420001E4AC _Findprevproc
120 430008BA24 _Findprevruntraceip
134 440001E3DC _Findprocbegin
135 450001E454 _Findprocend
48 460006FE04 _Findreferences
49 4700055510 _Findsorteddata
50 48000555C8 _Findsorteddataindex
51 4900055568 _Findsorteddatarange
52 4A0007053C _Findstrings
136 4B0000B0A8 _Findsymbolicname
53 4C00078978 _Findthread
137 4D00097700 _Findunknownfunction
54 4E0003192C _Flash
176 4F0007D568 _Followcall
55 500009763C _Get3dnow
138 5100041210 _Get3dnowxy
56 5200091A44 _Getaddressfromline
57 530009765C _Getasmfindmodel
139 540003E674 _Getasmfindmodelxy
58 550009307C _Getbprelname
59 5600019D78 _Getbreakpointtype
184 5700019D9C _Getbreakpointtypecount
60 580002D564 _Getcputhreadid
61 590001E5E0 _Getdisassemblerrange
62 5A000975F4 _Getfloat
63 5B000975CC _Getfloat10
140 5C0003D684 _Getfloat10xy
141 5D0003D7A8 _Getfloatxy
64 5E000976CC _Gethexstring
142 5F000403D8 _Gethexstringxy
65 60000975B0 _Getline
66 61000918F0 _Getlinefromaddress
143 620003D234 _Getlinexy
67 6300097588 _Getlong
144 640003D090 _Getlongxy
68 650009761C _Getmmx
145 6600040FF4 _Getmmxxy
69 6700019E20 _Getnextbreakpoint
146 6800008458 _Getoriginaldatasize
147 690001E558 _Getproclimits
177 6A0003D198 _Getregxy
70 6B0007393C _Getresourcestring
121 6C0008BF8C _Getruntraceprofile
122 6D0008BB3C _Getruntraceregisters
71 6E000557DC _Getsortedbyselection
72 6F00091D00 _Getsourcefilelimits
73 70000972A4 _Getstatus
148 7100055DB0 _Gettableselectionxy
74 720009767C _Gettext
149 730003EAFC _Gettextxy
150 74000799A0 _Getwatch
75 7500034A14 _Go
76 760006207C _Guardmemory
171 7700008F54 _Hardbreakpoints
77 78000612E4 _Havecopyofmemory
78 7900031768 _Infoline
151 7A00034494 _Injectcode
79 7B00063EFC _Insertname
152 7C000798D0 _Insertwatch
153 7D0007F02C _Isfilling
178 7E0007EFE4 _Isprefix
80 7F00047224 _Isretaddr
154 800007ECD8 _Issuspicious
81 8100054800 _IstextA
82 8200054840 _IstextW
186 8300060914 _Listmemory
83 84000976A4 _Manualbreakpoint
84 85000976F4 _Mergequicknames
85 8600031630 _Message
123 870001AC34 _Modifyhittrace
86 88000541CC _Newtablewindow
155 890007731C _OpenEXEfile
87 8A00055ECC _Painttable
88 8B000972AC _Plugingetvalue
89 8C00097154 _Pluginreadintfromini
90 8D000971E0 _Pluginreadstringfromini
91 8E00096D4C _Pluginsaverecord
92 8F00097004 _Pluginwriteinttoini
93 90000970B4 _Pluginwritestringtoini
94 910007E820 _Print3dnow
95 920007E5CC _Printfloat10
96 930007E450 _Printfloat4
97 940007E510 _Printfloat8
156 950007E88C _Printsse
98 9600031820 _Progress
99 9700064304 _Quickinsertname
100 980005470C _Quicktablewindow
157 9900061684 _Readcommand
101 9A0006130C _Readmemory
102 9B0001E5CC _Redrawdisassembler
103 9C0005413C _Registerotclass
104 9D00096F2C _Registerpluginclass
158 9E00078854 _Restoreallthreads
159 9F00078788 _Runsinglethread
124 A00008B9F8 _Runtracesize
125 A10008C188 _Scrollruntracewindow
105 A20005A2D0 _Selectandscroll
172 A30002DF84 _Sendshortcut
106 A400097754 _Setbreakpoint
185 A500019560 _Setbreakpointext
107 A60002D618 _Setcpu
160 A70002DEA4 _Setdisasm
173 A800046E58 _Setdumptype
108 A900008690 _Sethardwarebreakpoint
109 AA000192D8 _Setmembreakpoint
174 AB0008C040 _Settracecondition
182 AC0008C110 _Settracecount
183 AD0008C13C _Settracepauseoncommands
110 AE00095554 _Showsourcefromaddress
111 AF00055630 _Sortsorteddata
161 B00008B86C _Startruntrace
162 B100054884 _Stringtotext
112 B200034290 _Suspendprocess
113 B30005835C _Tablefunction
179 B400019F1C _Tempbreakpoint
114 B500096FE4 _Unregisterpluginclass
115 B60005A5EC _Updatelist
116 B700071594 _Walkreference
163 B80007160C _Walkreferenceex
117 B900061728 _Writememory
187 BA00001059 __GetExceptDLLinfo
188 BB000B0128 ___CPPdebugHook
页:
[1]