首页
社区
课程
招聘
[原创]编写OD插件将IDA中分析出来的函数名导入到OD中(CamelLu Functions' Names Importer)
发表于: 2011-7-20 00:31 36311

[原创]编写OD插件将IDA中分析出来的函数名导入到OD中(CamelLu Functions' Names Importer)

2011-7-20 00:31
36311
逆向程序的时候,喜欢用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插件了
#include <windows.h>
#include <string.h>

#include "plugin.h"

#pragma comment(lib,"OLLYDBG.LIB")
static HINSTANCE hinst = NULL;
static HWND hwnd = NULL;
BOOL WINAPI DllEntryPoint(HINSTANCE hinstance,DWORD dwreason,LPVOID lpvreserved) 
{
    if (dwreason==DLL_PROCESS_ATTACH)
        hinst=hinstance;                          
    return 1;                           
}

//下面四个函数全都是插件回调函数,只有前两个函数是编写OD插件必须有的!!!
//ODBG_PluginData这个函数是必须有的,作用就是设置插件的名字(在OD的Plugin)
extc int _export cdecl ODBG_Plugindata(char shortname[32]) 
{
    strcpy(shortname,"CamelLu");       
    return PLUGIN_VERSION;
}
//ODBG_Plugininit这个函数也是必须有的,看名字就知道是用来做一些初始化工作啦
//ollydbgversion参数可以用来检查当前OD的版本,确保插件运行在兼容的OD版本上,hw是OD主窗口的句柄
extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features) 
{
    hwnd = hw;
    return 0;
}

//ODBG_Pluginmenu这个函数是用来添加菜单的,每个菜单项之间用'|'字符隔开
extc int _export cdecl ODBG_Pluginmenu(int origin,char data[4096],void *item) 
{
    if (origin == PM_MAIN)
        strcpy(data,"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;     
    wchar_t wszFile[MAX_PATH]; 
    unsigned char *pBuffer = NULL;
    unsigned char *pLocate = NULL;
    unsigned char *pDellimiter = NULL;
    unsigned char *pTemp = NULL;
    DWORD dwFileSize = 0;
    DWORD dwBytesRead = 0;
    DWORD dwImageBase = 0;
    DWORD dwAddr = 0;
    char szBuffer[10];
    HANDLE hFile = INVALID_HANDLE_VALUE;
    if (origin == PM_MAIN)
        if (action == 0)
        {
   
            ZeroMemory(&ofn, sizeof(ofn));
            ofn.lStructSize = sizeof(ofn);
            ofn.hwndOwner = hwnd;
            ofn.lpstrFile = wszFile;
            ofn.lpstrFile[0] = L'\0';
            ofn.nMaxFile = sizeof(wszFile);
            ofn.lpstrFilter = L".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())
                {
                    MessageBoxW(hwnd,L"No debugee now!!!",0,0);
                    return;
                }
                hFile = CreateFileW(
                    wszFile,
                    GENERIC_READ,
                    FILE_SHARE_READ,
                    NULL,
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    NULL);
                if (INVALID_HANDLE_VALUE == hFile)
                {
                    MessageBoxW(hwnd,L"Failed to open .lu file!",0,0);
                    return;
                }
                dwFileSize = GetFileSize(hFile,NULL);
                if (INVALID_FILE_SIZE == dwFileSize)
                {
                    MessageBoxW(hwnd,L"GetFileSize failed!",0,0);
                    CloseHandle(hFile);
                    return;
                }
                pBuffer = VirtualAlloc(
                    NULL,
                    dwFileSize + 1 * sizeof(unsigned char),
                    MEM_COMMIT,
                    PAGE_READWRITE
                    );
                if (NULL == pBuffer)
                {
                    MessageBoxW(hwnd,L"VirtualAlloc failed!",0,0);
                    CloseHandle(hFile);
                    return;
                }
                if (!ReadFile(
                    hFile,
                    pBuffer,
                    dwFileSize,
                    &dwBytesRead,
                    NULL)
                    )
                {
                    MessageBoxW(hwnd,L"ReadFile failed!",0,0);
                    VirtualFree(pBuffer,0,MEM_RELEASE);
                    CloseHandle(hFile);
                    return;
                }
                CloseHandle(hFile);
                dwImageBase = _Plugingetvalue(VAL_MAINBASE);
                pLocate = pBuffer;
                pDellimiter = strstr(pLocate,"\r\n");
                while (*(pDellimiter + 2) != 0)
                {
                    pTemp = VirtualAlloc(NULL,pDellimiter - pLocate + 1 * sizeof(unsigned char),MEM_COMMIT,PAGE_READWRITE);
                    if (NULL == pTemp)
                    {
                        MessageBoxW(hwnd,L"VirtualAlloc in loop failed!",0,0);
                        VirtualFree(pBuffer,0,MEM_RELEASE);
                        return;
                    }
                    strncpy(pTemp,pLocate,pDellimiter - pLocate);
                    sscanf(pTemp,"%X-",&dwAddr);
                    _Quickinsertname(dwImageBase + dwAddr,NM_LABEL,strchr(pTemp,'-') + 1 * sizeof(unsigned char));
                    VirtualFree(pTemp,0,MEM_RELEASE);
                    pLocate = pDellimiter + 2;
                    pDellimiter = strstr(pLocate,"\r\n");
                }
                _Mergequicknames();
                VirtualFree(pBuffer,0,MEM_RELEASE);
                MessageBoxW(hwnd,L"I am done^ ^",L"CamelLu",MB_OK);
            }

        }
        else if (action == 1)
        {
            MessageBoxW(hwnd,L"CamelLu Functions\' Names Importer\r\nWritten by CamelLu 2011.7.19\r\n",L"Camellu",MB_ICONINFORMATION);
        }

}



OD插件的使用方法:
如果是原版的OD,直接把编译好的DLL放到od主程序的目录就可以了,看雪版的OD把DLL放到plugin目录下。

附件中包含了CamelLu.idc,CamelLu Functions' Names Importer插件的源代码以及编译好的DLL
PS.
我这个插件还有点问题,就是调试DLL的话不能用,因为我发现调试DLL的时候_Plugingetvalue(VAL_MAINBASE)函数得到的是LoadDll.exe的基址,基址一错自然写名称的地方就错啦= =!
好了,明天还要干活,回去睡觉去了

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

上传的附件:
收藏
免费 9
支持
分享
最新回复 (41)
雪    币: 716
活跃值: (162)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
2
向工作到凌晨的同志致敬!!!
2011-7-20 07:34
0
雪    币: 204
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好东西 果断收藏。好想跟大牛们一样搞点东东出来哦。
不过还在量变的过程
2011-7-20 08:48
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
4
直接生成 map 文件不是更方便么?
2011-7-20 08:50
0
雪    币: 239
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
这个贴一定要顶,收藏慢慢看
2011-7-20 14:02
0
雪    币: 30
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主好精力,能熬到凌晨来发帖
2011-7-20 14:10
0
雪    币: 75
活跃值: (623)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
7
顶啊...我比较懒,直接用 ida调试程序--!
2011-7-20 15:24
0
雪    币: 204
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
IDA不能动态调试啊
2011-7-20 15:34
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
9
#include <windows.h>
#include <string.h>

#include "plugin.h"

#pragma comment(lib,"OLLYDBG.LIB")
static HINSTANCE hinst = NULL;
static HWND hwnd = NULL;
BOOL WINAPI DllEntryPoint(HINSTANCE hinstance,DWORD dwreason,LPVOID lpvreserved) 
{
    if (dwreason==DLL_PROCESS_ATTACH)
        hinst=hinstance;                          
    return 1;                           
}

//下面四个函数全都是插件回调函数,只有前两个函数是编写OD插件必须有的!!!
//ODBG_PluginData这个函数是必须有的,作用就是设置插件的名字(在OD的Plugin)
extc int _export cdecl ODBG_Plugindata(char shortname[32]) 
{
    strcpy(shortname,"CamelLu");       
    return PLUGIN_VERSION;
}
//ODBG_Plugininit这个函数也是必须有的,看名字就知道是用来做一些初始化工作啦
//ollydbgversion参数可以用来检查当前OD的版本,确保插件运行在兼容的OD版本上,hw是OD主窗口的句柄
extc int _export cdecl ODBG_Plugininit(int ollydbgversion,HWND hw,ulong *features) 
{
    if (ollydbgversion < PLUGIN_VERSION)
    {
        MessageBoxW(hw,L"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,char data[4096],void *item) 
{
    if (origin == PM_MAIN)
        strcpy(data,"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;     
    wchar_t wszFile[MAX_PATH]; 
    unsigned char *pBuffer = NULL;
    unsigned char *pLocate = NULL;
    unsigned char *pDellimiter = NULL;
    unsigned char *pTemp = NULL;
    DWORD dwFileSize = 0;
    DWORD dwBytesRead = 0;
    DWORD dwImageBase = 0;
    DWORD dwAddr = 0;
    char szBuffer[10];
    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] = L'\0';
            ofn.nMaxFile = sizeof(wszFile);
            ofn.lpstrFilter = L".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())
                {
                    MessageBoxW(hwnd,L"No debugee now!!!",0,0);
                    return;
                }
                hFile = CreateFileW(
                    wszFile,
                    GENERIC_READ,
                    FILE_SHARE_READ,
                    NULL,
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    NULL);
                if (INVALID_HANDLE_VALUE == hFile)
                {
                    MessageBoxW(hwnd,L"Failed to open .lu file!",0,0);
                    return;
                }
                dwFileSize = GetFileSize(hFile,NULL);
                if (INVALID_FILE_SIZE == dwFileSize)
                {
                    MessageBoxW(hwnd,L"GetFileSize failed!",0,0);
                    CloseHandle(hFile);
                    return;
                }
                pBuffer = VirtualAlloc(
                    NULL,
                    dwFileSize + 1 * sizeof(unsigned char),
                    MEM_COMMIT,
                    PAGE_READWRITE
                    );
                if (NULL == pBuffer)
                {
                    MessageBoxW(hwnd,L"VirtualAlloc failed!",0,0);
                    CloseHandle(hFile);
                    return;
                }
                if (!ReadFile(
                    hFile,
                    pBuffer,
                    dwFileSize,
                    &dwBytesRead,
                    NULL)
                    )
                {
                    MessageBoxW(hwnd,L"ReadFile failed!",0,0);
                    VirtualFree(pBuffer,0,MEM_RELEASE);
                    CloseHandle(hFile);
                    return;
                }
                CloseHandle(hFile);
                table = (t_table*)_Plugingetvalue(VAL_MODULES);
                if (NULL == table)
                {
                    MessageBoxW(hwnd,L"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,_Plugingetvalue(VAL_EXEFILENAME)))
                    {
                        dwImageBase = module->base;
                        break;
                    }
                }
                pLocate = pBuffer;
                pDellimiter = strstr(pLocate,"\r\n");
                while (*(pDellimiter + 2) != 0)
                {
                    pTemp = VirtualAlloc(NULL,pDellimiter - pLocate + 1 * sizeof(unsigned char),MEM_COMMIT,PAGE_READWRITE);
                    if (NULL == pTemp)
                    {
                        MessageBoxW(hwnd,L"VirtualAlloc in loop failed!",0,0);
                        VirtualFree(pBuffer,0,MEM_RELEASE);
                        return;
                    }
                    strncpy(pTemp,pLocate,pDellimiter - pLocate);
                    sscanf(pTemp,"%X-",&dwAddr);
                    _Quickinsertname(dwImageBase + dwAddr,NM_LABEL,strchr(pTemp,'-') + 1 * sizeof(unsigned char));
                    VirtualFree(pTemp,0,MEM_RELEASE);
                    pLocate = pDellimiter + 2;
                    pDellimiter = strstr(pLocate,"\r\n");
                }
                _Mergequicknames();
                VirtualFree(pBuffer,0,MEM_RELEASE);
                MessageBoxW(hwnd,L"I am done^ ^",L"CamelLu",MB_OK);
            }

        }
        else if (action == 1)
        {
            MessageBoxW(hwnd,L"CamelLu Functions\' Names Importer\r\nWritten by CamelLu 2011.7.19\r\n",L"Camellu",MB_ICONINFORMATION);
        }

}


请下载本楼层的附件吧
上传的附件:
2011-7-23 14:17
0
雪    币: 1015
活跃值: (235)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
10
这个顶啊,OD脚本还没有接触。学习一下下。
2011-7-23 16:09
0
雪    币: 81
活跃值: (55)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
顶贴表支持!
2011-7-24 10:13
0
雪    币: 1259
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stu
12
做个记号,回家去下。
2011-7-24 11:51
0
雪    币: 364
活跃值: (81)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
13
恩,不错.,收了.
2011-7-24 13:27
0
雪    币: 2586
活跃值: (920)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
14
学习,顶楼主
2011-7-26 09:13
0
雪    币: 147
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
od插件的开发我以前并不重视,到实际使用的时候后悔已晚
2011-7-26 18:22
0
雪    币: 147
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
多刷新了一下,没有及时显示,所以多提交了一下,版主把这删除吧
2011-7-26 18:24
0
雪    币: 347
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
有源码,感谢分享
之前用loadmap,试一下这个
2011-7-26 19:34
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
好东西,非常感谢作者
2011-7-28 13:47
0
雪    币: 768
活跃值: (515)
能力值: ( LV13,RANK:460 )
在线值:
发帖
回帖
粉丝
19
同好奇~
2011-7-29 20:34
0
雪    币: 90
活跃值: (103)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
20
好东西,感谢楼主
2011-7-29 20:49
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
强烈支持有码的同志
2011-7-29 21:02
0
雪    币: 391
活跃值: (135)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
22
不知道cntrump和FishSeeWater是不是看不懂汉字

[QUOTE=CamelLu;982531]以前我一直用GODUP的map loader,但是有些时候感觉它有点问题,还有一个插件叫MapConv也有这个功能,不过我还是打算自己写一个,主要是为了学习如何编写OD插件[/QUOTE]
2011-7-30 10:18
0
雪    币: 213
活跃值: (20)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
支持原创!!!!!!!!
2011-7-30 20:51
0
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
呵呵 不错 不错
2011-7-31 23:03
0
雪    币: 156
活跃值: (190)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
25
感谢楼主,学习一下,

=================================
我从http://www.ollydbg.de上下载的odbg110.zip及odbg108b.zip,
无法像楼主说的那样,加载插件CamelLu,请做验证,希望能够将插件作的更好。

测试平台如下:
OS 名称:          Microsoft Windows XP Professional
OS 版本:          5.1.2600 Service Pack 3 Build 2600
上传的附件:
2011-7-31 23:14
0
游客
登录 | 注册 方可回帖
返回
//