逆向程序的时候,喜欢用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)”  解决方案如下:

  1. In Solution Explorer, open the shortcut menu for the project and then chooseProperties.

  2. In the project Property Pages dialog box, in the left pane underConfiguration Properties, expand C/C++ and then selectCommand Line.

  3. 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中相关推荐

  1. php中怎么连接数据库中的表,php 连接 excel表格数据库数据-php中如何将execl的数据导入到数据库中...

    php中如何将execl的数据导入到数据库中 php导出大量数据的Excel: PHP从数据库分多次读取100万行记录,和分多次将100万行写入文本文件都没问题 Excel可以支持100万行记录,Ex ...

  2. php如何导入数据,““php中如何将execl的数据导入到数据库中

    php中如何将execl的数据导入到数据库中 1.使用PHP Excel Parser Pro,但是这个软件为收费软件: 2.可EXCEL表保存为CSV,然后通过phpmyadmin或者SQLyog导 ...

  3. php使用excel表格数据库数据,php使用excel表格数据库数据库-php中如何将execl的数据导入到数据库中...

    php中如何将execl的数据导入到数据库中 1.使用PHP Excel Parser Pro软件,但是这件为收费软件: 2.可将EXCEL表保CSV,然后通过 phpmyadmin 或者SQLyog ...

  4. flash中制的SWC组件怎样导入到flex中使用

    flash中制的SWC组件怎样导入到flex中使用 2010-04-30 11:18 在使用FLASH导出SWC组件文件后,放入项目的LIB文件夹,然后要用实例化一个对象才能进行时操作使用, 但要记得 ...

  5. pandas使用replace函数替换dataframe中的值:replace函数使用正则表达式对dataframe中的值进行替换

    pandas使用replace函数替换dataframe中的值:replace函数使用正则表达式对dataframe中的值进行替换 目录

  6. [vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗?

    [vue] 在使用计算属性的时,函数名和data数据源中的数据可以同名吗? 莫名其妙的问题.可以同名,但data会覆盖methods.并且本就不该同名,同名说明你命名不规范.然后解释为什么会覆盖,因为 ...

  7. 习题 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 ...

  8. c语言中函数名可变,C语言中可变参数函数

    转帖两封: 首先在介绍可变参数表函数的设计之前,我们先来介绍一下最经典的可变参数表printf函数的实现原理. 一.printf函数的实现原理 在C/C++中,对函数参数的扫描是从后向前的.C/C++ ...

  9. c语言中格式化字符串系列函数包括,解析C语言中常用的格式化输入、输出函数...

    fprintf(格式化输出数据至文件) 这个函数的功能类似于文件操作函数 fwrite();通过一个文件描述符将数据写入该文件描述符所指向的文件中. 函数定义: int fprintf(FILE * ...

最新文章

  1. 合理估算线程池线程数量
  2. 图解 SQL 中 JOIN 的各种用法
  3. [c#基础]关于try...catch最常见的笔试题
  4. Java中的多线程你只要看这一篇就够了
  5. 聚焦WCF行为的扩展
  6. wpf 动画_WPF中监视动画进度
  7. linux系统sql语句报错_如果数据库管理工具1045错误出现在Linux系统中怎么
  8. 3D人脸重建——PRNet网络输出的理解
  9. C语言当中int,float,double,char这四个有什么区别?
  10. 通过反射获取私有方法
  11. js通过url链接下载文件
  12. c语言error lnk 2005,易语言5.71静态编译问题LIBC.lib(crt0dat.obj) : error LNK2005:
  13. 太宰治《人间失格》经典语录20句,句句引人深思
  14. vbr,cbr,abr区别
  15. 云计算10个入门基础知识
  16. 反激开关电源的工作原理
  17. Android常用库和插件避免重复造轮子(持续更新)
  18. CentOS8下超详细安装配置kubernetes(K8S)
  19. 冷却塔为什么设计成双曲线型?
  20. macbook重装系统 选择方案_超详细的mac重装系统教程

热门文章

  1. 通过阿里云容器服务K8S Ingress Controller实现应用服务的灰度发布
  2. 仿抖音底部导航效果(一)
  3. MIMO系统ML检测(最大似然检测)
  4. Linux下php5.3编译oracle客户端
  5. SQLite.NET提供程序的选择
  6. [转]中国CIO的空前机会和空前责任
  7. C#程序设计笔记(第九章)
  8. 4python 解析库的使用
  9. 安装xml2js出现npm ERR! code E404 npm ERR! 404 Not Found: event-stream@3.3.6
  10. 1055. 集体照 (25)