OllyDbg插件
| 第一章 初探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版本,插件大體上通用,這幾個版本的改動有: l??t_reg和t_bpoint結構體擴展 l??新選項“總在最前”需要插件窗口特殊支持 l??Browsefilename支持保存文件對話框 插件是提供附加功能的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格式調用_cdecl l 強制所有結構體按字節對齊 l 默認字符類型為unsigned型 編譯自定義插件會用到plugin.h ollydbg.lib,需要復制到工程目錄中。 現在以VS2010為例介紹如何編寫無任何功能的插件。首先建立一個Windows動態鏈接庫的空項目,在工程屬性中,選C/C++ -> 命令行,右側“其它選項”加入“/J”。之后向工程添加helloworld.cpp,內容如下: #include?<windows.h> #include?"lugin.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[32]) {//用于插件菜單中顯示插件名 ? ?? ? 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 /DEFllydbg.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?"lugin.h" extc?int?_export?cdecl?ODBG_Plugindata(char?shortname[32]) {//插件檢測 ? ?? ? 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[4096],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 |
總結
- 上一篇: MSN 无法登陆,错误代码: 80072
- 下一篇: 数据中台之血缘篇:Atlas 详解