编写OD插件将IDA中分析出来的函数名导入到OD中
逆向程序的时候,喜欢用IDA静态分析,用OD动态调试,如果把IDA分析出来的函数名称都导入到OD中,调试的时候就知道哪些函数不需要再看了。以前我一直用GODUP的map loader,但是有些时候感觉它有点问题,还有一个插件叫MapConv也有这个功能,不过我还是打算自己写一个,主要是为了学习如何编写OD插件
首先我用一个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插件了
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中相关推荐
- php中怎么连接数据库中的表,php 连接 excel表格数据库数据-php中如何将execl的数据导入到数据库中...
php中如何将execl的数据导入到数据库中 php导出大量数据的Excel: PHP从数据库分多次读取100万行记录,和分多次将100万行写入文本文件都没问题 Excel可以支持100万行记录,Ex ...
- php如何导入数据,““php中如何将execl的数据导入到数据库中
php中如何将execl的数据导入到数据库中 1.使用PHP Excel Parser Pro,但是这个软件为收费软件: 2.可EXCEL表保存为CSV,然后通过phpmyadmin或者SQLyog导 ...
- php使用excel表格数据库数据,php使用excel表格数据库数据库-php中如何将execl的数据导入到数据库中...
php中如何将execl的数据导入到数据库中 1.使用PHP Excel Parser Pro软件,但是这件为收费软件: 2.可将EXCEL表保CSV,然后通过 phpmyadmin 或者SQLyog ...
- flash中制的SWC组件怎样导入到flex中使用
flash中制的SWC组件怎样导入到flex中使用 2010-04-30 11:18 在使用FLASH导出SWC组件文件后,放入项目的LIB文件夹,然后要用实例化一个对象才能进行时操作使用, 但要记得 ...
- pandas使用replace函数替换dataframe中的值:replace函数使用正则表达式对dataframe中的值进行替换
pandas使用replace函数替换dataframe中的值:replace函数使用正则表达式对dataframe中的值进行替换 目录
- [vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗?
[vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗? 莫名其妙的问题.可以同名,但data会覆盖methods.并且本就不该同名,同名说明你命名不规范.然后解释为什么会覆盖,因为 ...
- 习题 8.5 将本章的例8.4改写为一个多文件的程序:1.将类定义放在头文件arraymax.h中;2.将成员函数定义放在源文件arraymax.cpp中;3.主函数放在源文件file1.cpp中。
C++程序设计(第三版) 谭浩强 习题8.5 个人设计 习题 8.5 将本章的例8.4改写为一个多文件的程序: 1.将类定义放在头文件arraymax.h中: 2.将成员函数定义放在源文件arraym ...
- c语言中函数名可变,C语言中可变参数函数
转帖两封: 首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表printf函数的实现原理. 一.printf函数的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++ ...
- c语言中格式化字符串系列函数包括,解析C语言中常用的格式化输入、输出函数...
fprintf(格式化输出数据至文件) 这个函数的功能类似于文件操作函数 fwrite();通过一个文件描述符将数据写入该文件描述符所指向的文件中. 函数定义: int fprintf(FILE * ...
最新文章
- 合理估算线程池线程数量
- 图解 SQL 中 JOIN 的各种用法
- [c#基础]关于try...catch最常见的笔试题
- Java中的多线程你只要看这一篇就够了
- 聚焦WCF行为的扩展
- wpf 动画_WPF中监视动画进度
- linux系统sql语句报错_如果数据库管理工具1045错误出现在Linux系统中怎么
- 3D人脸重建——PRNet网络输出的理解
- C语言当中int,float,double,char这四个有什么区别?
- 通过反射获取私有方法
- js通过url链接下载文件
- c语言error lnk 2005,易语言5.71静态编译问题LIBC.lib(crt0dat.obj) : error LNK2005:
- 太宰治《人间失格》经典语录20句,句句引人深思
- vbr,cbr,abr区别
- 云计算10个入门基础知识
- 反激开关电源的工作原理
- Android常用库和插件避免重复造轮子(持续更新)
- CentOS8下超详细安装配置kubernetes(K8S)
- 冷却塔为什么设计成双曲线型?
- macbook重装系统 选择方案_超详细的mac重装系统教程
热门文章
- 通过阿里云容器服务K8S Ingress Controller实现应用服务的灰度发布
- 仿抖音底部导航效果(一)
- MIMO系统ML检测(最大似然检测)
- Linux下php5.3编译oracle客户端
- SQLite.NET提供程序的选择
- [转]中国CIO的空前机会和空前责任
- C#程序设计笔记(第九章)
- 4python 解析库的使用
- 安装xml2js出现npm ERR! code E404 npm ERR! 404 Not Found: event-stream@3.3.6
- 1055. 集体照 (25)