编写OD插件将IDA中分析出来的函数名导入到OD中
2013-03-03 09:35
375 查看
逆向程序的时候,喜欢用IDA静态分析,用OD动态调试,如果把IDA分析出来的函数名称都导入到OD中,调试的时候就知道哪些函数不需要再看了。以前我一直用GODUP的map loader,但是有些时候感觉它有点问题,还有一个插件叫MapConv也有这个功能,不过我还是打算自己写一个,主要是为了学习如何编写OD插件
![](http://bbs.pediy.com/images/smilies/tongue.gif)
首先我用一个IDC脚本将idb中所有函数的名称都导出到一个文件当中
这个idc脚本文件没有main函数,因为我要使用快捷键来调用它
使用方法:
在IDA的安装目录下面找到idc这个目录,把上面这个脚本保存到这个目录中,然后idc目录下找到
ida.idc这个文件,打开它,在#include<idc.idc>的下面加入#include<CamelLu.idc>,然后在它的main函数里面加入AddHotkey("Alt-9","CamelLu");
接下来你就可以在IDA中按Alt+9来调用这个脚本了(为脚本选择热键的时候要注意,如果这个热键已经被其他脚本或者插件使用的话,AddHotKey会失败,IDA不会给你提示的噢)
接下来再写一个OD插件来解析上面输出的文件,用Quickinsertname和Mergequicknames函数把函数名加到相应的地址就OK。我对插件框架的几个函数用途都写了简单的注释,相信大家看过之后都能自己写OD插件了
![](http://bbs.pediy.com/images/smilies/wink.gif)
VS环境设置为 Use Multi-Byte Character Set
如果提示“Please set default char type to unsigned (option /J)” 解决方案如下:
In Solution Explorer, open the shortcut menu for the project and then chooseProperties.
In the project Property Pages dialog box, in the left pane underConfiguration Properties, expand
C/C++ and then selectCommand Line.
In the Additional Options pane, specify the/J compiler option.
需要注意的是 如果是用VS2012编译 在XP上OD启动加在这个插件会报错,找不到“msvcr110.dll” 但是XP上最多支持msvcr100.dll 即便找来了msvcr110.dll注册它 也是要出错的 所以如果需要在XP上的OD运行该插件 用VS2010编译该插件就行 VS2012编译只能在WIN7 WIN8的OD上运行
OD插件的使用方法:
如果是原版的OD,直接把编译好的DLL放到od主程序的目录就可以了,看雪版的OD把DLL放到plugin目录下。
![](http://bbs.pediy.com/images/smilies/tongue.gif)
首先我用一个IDC脚本将idb中所有函数的名称都导出到一个文件当中
//CamelLu.idc #include <idc.idc> static CamelLu() { auto addr,path,file,imagebase; Message("Functions' Names Dumper - CamelLu(2011.7.19)\n"); file = fopen(GetInputFilePath(),"rb"); if (0 == file) { Warning("open INPUTFILE failed!"); return; } if (0 != fseek(file,0x3c,0)) { Warning("seek e_lfanew failed!"); fclose(file); return; } imagebase = readlong(file,0); if (0 != fseek(file,imagebase + 0x34,0)) { Warning("seek imagebase failed!"); fclose(file); return; } imagebase = readlong(file,0); fclose(file); path = AskFile(1,"*.lu","Please enter output file name"); if (BADADDR == path) { Warning("AskFile failed!"); return; } file = fopen(path,"w"); if (0 == file) { Warning("fopen failed!"); return; } addr = MinEA(); if ("" != GetFunctionName(addr)) fprintf(file,"%X---%s\n",addr,GetFunctionName(addr)); for(addr = NextFunction(addr);BADADDR != addr;addr = NextFunction(addr)) fprintf(file,"%X-%s\n",addr - imagebase,GetFunctionName(addr)); fclose(file); Message("output functions' names finished!"); }
这个idc脚本文件没有main函数,因为我要使用快捷键来调用它
使用方法:
在IDA的安装目录下面找到idc这个目录,把上面这个脚本保存到这个目录中,然后idc目录下找到
ida.idc这个文件,打开它,在#include<idc.idc>的下面加入#include<CamelLu.idc>,然后在它的main函数里面加入AddHotkey("Alt-9","CamelLu");
接下来你就可以在IDA中按Alt+9来调用这个脚本了(为脚本选择热键的时候要注意,如果这个热键已经被其他脚本或者插件使用的话,AddHotKey会失败,IDA不会给你提示的噢)
接下来再写一个OD插件来解析上面输出的文件,用Quickinsertname和Mergequicknames函数把函数名加到相应的地址就OK。我对插件框架的几个函数用途都写了简单的注释,相信大家看过之后都能自己写OD插件了
![](http://bbs.pediy.com/images/smilies/wink.gif)
VS环境设置为 Use Multi-Byte Character Set
如果提示“Please set default char type to unsigned (option /J)” 解决方案如下:
In Solution Explorer, open the shortcut menu for the project and then chooseProperties.
In the project Property Pages dialog box, in the left pane underConfiguration Properties, expand
C/C++ and then selectCommand Line.
In the Additional Options pane, specify the/J compiler option.
需要注意的是 如果是用VS2012编译 在XP上OD启动加在这个插件会报错,找不到“msvcr110.dll” 但是XP上最多支持msvcr100.dll 即便找来了msvcr110.dll注册它 也是要出错的 所以如果需要在XP上的OD运行该插件 用VS2010编译该插件就行 VS2012编译只能在WIN7 WIN8的OD上运行
#include <windows.h> #include <Commdlg.h> //for GetOpenFileName function. #include <tchar.h> //for _tcscpy_s ... function. #include <stdlib.h> //for _countof ... function. #include <Shlwapi.h> //for String function of windows. #include <strsafe.h> //for StringCchPrintf ... function. #include "plugin.h" #pragma comment(lib,"OLLYDBG.LIB") static HWND hwnd = NULL; 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; } //下面四个函数全都是插件回调函数,只有前两个函数是编写OD插件必须有的!!! //ODBG_PluginData这个函数是必须有的,作用就是设置插件的名字(在OD的Plugin) extc int _export cdecl ODBG_Plugindata(TCHAR shortname[32]) { strcpy_s(shortname, 32, "IDA2OD"); return PLUGIN_VERSION; } //ODBG_Plugininit这个函数也是必须有的,看名字就知道是用来做一些初始化工作啦 //ollydbgversion参数可以用来检查当前OD的版本,确保插件运行在兼容的OD版本上,hw是OD主窗口的句柄 extc int _export cdecl ODBG_Plugininit(int ollydbgversion, HWND hw, DWORD *features) { if (ollydbgversion < PLUGIN_VERSION) { MessageBox(hw, TEXT("CamelLu is not compatible with your Ollydbg version!"), 0, 0); return -1; } hwnd = hw; return 0; } //ODBG_Pluginmenu这个函数是用来添加菜单的,每个菜单项之间用'|'字符隔开 extc int _export cdecl ODBG_Pluginmenu(int origin, TCHAR data[4096], VOID *item) { if (origin == PM_MAIN) { strcpy_s(data, 4096, "0&Load functions\' names|1&About"); } return 1; } //ODBG_Pluginaction函数用于添加响应ODBG_Pluginmenu函数添加的菜单,很简单,看看下面的代码就明白了 extc void _export cdecl ODBG_Pluginaction(int origin, int action, VOID *item) { OPENFILENAME ofn; TCHAR wszFile[MAX_PATH]; PTSTR pBuffer = NULL; PTSTR pLocate = NULL; PTSTR pDellimiter = NULL; PTSTR pTemp = NULL; DWORD dwFileSize = 0; DWORD dwBytesRead = 0; DWORD dwImageBase = 0; DWORD dwAddr = 0; int nSize; t_table *table = NULL; t_sorted *sorted = NULL; t_module *module = NULL; HANDLE hFile = INVALID_HANDLE_VALUE; int nIndex = 0; if (origin == PM_MAIN) if (action == 0) { ZeroMemory(&ofn, sizeof(ofn)); ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFile = wszFile; ofn.lpstrFile[0] = '\0'; ofn.nMaxFile = _countof(wszFile); ofn.lpstrFilter = TEXT(".lu\0*.lu\0"); ofn.nFilterIndex = 1; ofn.lpstrFileTitle = NULL; ofn.nMaxFileTitle = 0; ofn.lpstrInitialDir = NULL; ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; if (GetOpenFileName(&ofn)==TRUE) { if (STAT_NONE == _Getstatus()) { MessageBox(hwnd, TEXT("No debugee now!!!"), 0, 0); return; } hFile = CreateFile( wszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hFile) { MessageBox(hwnd, TEXT("Failed to open .lu file!"), 0, 0); return; } dwFileSize = GetFileSize(hFile,NULL); if (INVALID_FILE_SIZE == dwFileSize) { MessageBox(hwnd, TEXT("GetFileSize failed!"), 0, 0); CloseHandle(hFile); return; } pBuffer = (PTSTR)VirtualAlloc( NULL, dwFileSize + sizeof(TCHAR), MEM_COMMIT, PAGE_READWRITE ); if (NULL == pBuffer) { MessageBox(hwnd, TEXT("VirtualAlloc failed!"), 0, 0); CloseHandle(hFile); return; } if (!ReadFile( hFile, pBuffer, dwFileSize, &dwBytesRead, NULL) ) { MessageBox(hwnd, TEXT("ReadFile failed!"), 0, 0); VirtualFree(pBuffer, 0, MEM_RELEASE); CloseHandle(hFile); return; } CloseHandle(hFile); table = (t_table*)_Plugingetvalue(VAL_MODULES); if (NULL == table) { MessageBox(hwnd, TEXT("Get modules failed!"), 0, 0); VirtualFree(pBuffer, 0, MEM_RELEASE); CloseHandle(hFile); return; } sorted = &table->data; for (nIndex = 0;nIndex < sorted->n;++nIndex) { module = (t_module *)((DWORD)sorted->data + nIndex * sorted->itemsize); if (0 == strcmp(module->path, (char *)_Plugingetvalue(VAL_EXEFILENAME))) { dwImageBase = module->base; break; } } pLocate = pBuffer; pDellimiter = strstr(pLocate, "\r\n"); while (*(pDellimiter + 2) != 0) { nSize = pDellimiter - pLocate + sizeof(TCHAR); pTemp = (PTSTR)VirtualAlloc(NULL, nSize, MEM_COMMIT,PAGE_READWRITE); if (NULL == pTemp) { MessageBox(hwnd, TEXT("VirtualAlloc in loop failed!"), 0, 0); VirtualFree(pBuffer, 0, MEM_RELEASE); return; } strncpy_s(pTemp, nSize, pLocate, pDellimiter - pLocate); sscanf_s(pTemp,"%X-",&dwAddr); _Quickinsertname(dwImageBase + dwAddr, NM_LABEL, strchr(pTemp,'-') + sizeof(TCHAR)); VirtualFree(pTemp, 0, MEM_RELEASE); pLocate = pDellimiter + 2; pDellimiter = strstr (pLocate, "\r\n"); } _Mergequicknames(); VirtualFree(pBuffer,0,MEM_RELEASE); MessageBox(hwnd, TEXT("I am done^ ^"), TEXT("CamelLu"), MB_OK); } } else if (action == 1) { MessageBox(hwnd, TEXT("CamelLu Functions\' Names Importer\r\nWritten by CamelLu 2011.7.19\r\n"), TEXT("Camellu"), MB_ICONINFORMATION); } }
OD插件的使用方法:
如果是原版的OD,直接把编译好的DLL放到od主程序的目录就可以了,看雪版的OD把DLL放到plugin目录下。
相关文章推荐
- 编写OD插件将IDA中分析出来的函数名导入到OD中
- [导入]看图说话,编写VS2005插件,增强VS2005 IDE
- ida 插件编写
- 3DMAX导入插件的编写(一)
- 【 IDA】使用IDA load file功能,导入JNI.h解析【JNI 函数】
- Log分析 你还可以去data/anr的目录下把trace.txt这个文件拷贝出来,在该文件中会写了产生anr的函数堆栈可以帮助分析
- 实验 5.2.2-1 文件描述符的复制 1. 编写程序测试函数 dup()和 dup2()。 2. 给出运行结果及分析。
- 1. 插件编写的原则及文件目录分析
- idaPython编写插件
- PE手工分析-导入表和导入函数地址表分析
- 常用的Win API函数在od分析可以用到
- CNI插件编写框架分析
- 8.3分析下面函数能否实现其功能,并编写出正确的程序
- windows PE Image 文件分析(4)--- 导入函数的绑定
- 使用C#编写IDA插件 IDACSharp v1.0.2010.0605
- 简单编写OD插件(附prince's TracKid源码)
- IDA反汇编/反编译静态分析iOS模拟器程序(三)函数表示与搜索函数
- IDA 汇编命令分析以及函数调用过程
- 通过编写一个程序,来说明字符数组 以及操作字符数组的函数的用法。该程序读入一组文本行,并把最长的文本行打印出来。
- 编写函数parseUrl,将url解析成各个域打印出来