首页
社区
课程
招聘
发个OD的插件,让大家看看吧,不过有问题(源码)
发表于: 2010-2-25 22:56 8304

发个OD的插件,让大家看看吧,不过有问题(源码)

2010-2-25 22:56
8304
这个插件还有个问题,至于在哪,请大家自已调试琢磨吧,另外还有个程序,这个程序不知道为什么调用VirtualProtect失败,希望 有心者看看

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (41)
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
均用vc6写的,好像打过sp6
2010-2-25 22:58
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
怎么成为普通会员啊?
2010-2-25 23:07
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
怪不得没人下载,原来我没说明白,这两个文件都是源码啊。。。。。。
2010-2-26 00:35
0
雪    币: 411
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
没写过OD的插件,帮楼主顶下。支持。
2010-2-26 09:09
0
雪    币: 357
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
你VirtualProtect谁啊?OD?你要改OD的页面干嘛
我想你想改被调试进程的页面,然后写入断点吧,这样的话要用VirtualProtectEx啊
2010-2-26 09:22
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
楼上的,看了源程序再说话吧,我用的是VirtualProtectEx,而且这程序也不是OD插件,是一个单独的程序
2010-2-26 10:37
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
MyHookApi.rar 这是个独立的程序, 不是OD插件,它里面的VirtualProtectEx调用的时候,总是不成功。
至于OD插件里的问题,我知道哪有错,我也知道怎么改,只是发给大家看看,研究一下。
2010-2-26 11:01
0
雪    币: 1632
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
在每个帖子里连续回复,我真佩服你。
编辑功能是干什么的?
2010-2-26 12:02
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
怕沉啊。标题上多加了源码两个字
2010-2-26 13:12
0
雪    币: 357
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
抱歉,我误解了你顶楼的话,请无视我的话吧
2010-2-26 14:21
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
哪里做得不好的,请大家给点意见
2010-2-26 17:01
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
会不会是OD的被调试Handel没有那个权限
2010-2-26 20:15
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
绝对不是,挺值得研究的
2010-2-26 22:32
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
15
我现在来解释一下我的代码,同时也希望 能有像CCDEBUG这样的高手给我看一下,我后来才发现,我也没有彻底解决这个问题
2010-2-28 21:05
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
16
补充一下,我这里指的是插件,另一个程序不谈
2010-2-28 21:06
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
17
extc int _export cdecl ODBG_Pluginmenu(int origin,char data[4096],void *item)
{
        if (origin!=PM_MAIN)
                return 0;                          // No pop-up menus in OllyDbg's windows
        strcpy(data,"0 开始拦截|1 停止拦截");
        return 1;
}
这段是加入菜单,加载后会看到插件里有个HookApi项,里面有两项 "开始拦截" "停止拦截"
2010-2-28 21:08
0
雪    币: 140
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
没写过OD的插件,帮楼主顶下
2010-2-28 21:10
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19
extc void _export cdecl ODBG_Pluginaction(int origin,int action,void *item)
{
        HANDLE hProcess;

        if (origin == PM_MAIN)
        {
                switch (action)
                {
                        case 0:
                                if (pMyAllocMemory)
                                {
                                        hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
                                        VirtualFreeEx(hProcess,pMyAllocMemory,0x500,MEM_RELEASE);
                                }
                                if (dwExternData[5])
                                {
                                        hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
                                        VirtualFreeEx(hProcess,(LPVOID)dwExternData[5],SIZEOF_API_ARRAY * 1000,MEM_RELEASE);
                                }
                                if (hModuleArray)
                                {
                                        hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
                                        VirtualFreeEx(hProcess,(LPVOID)hModuleArray,sizeof(HMODULE) * 100,MEM_RELEASE);
                                }
                                hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
                                pMyAllocMemory = VirtualAllocEx(hProcess,NULL,0x500,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
                                if (!pMyAllocMemory)
                                {
                                        MessageBox(NULL,"内存分配失败","",MB_OK);
                                        break;
                                }
                                _Addtolist(0,0,"内存分配成功");
                                dwExternData[5] = (DWORD)VirtualAllocEx(hProcess,NULL,SIZEOF_API_ARRAY * 1000,MEM_COMMIT,PAGE_READWRITE);
                                if (!dwExternData[5])
                                {
                                        VirtualFreeEx(hProcess,pMyAllocMemory,0x500,MEM_RELEASE);
                                        pMyAllocMemory = 0;
                                        MessageBox(NULL,"内存分配失败1","",MB_OK);
                                        break;
                                }
                                _Addtolist(0,0,"内存分配成功1");
                                hModuleArray = (HMODULE *)VirtualAllocEx(hProcess,NULL,sizeof(HMODULE) * 100,MEM_COMMIT,PAGE_READWRITE);
                                if (!hModuleArray)
                                {
                                        VirtualFreeEx(hProcess,pMyAllocMemory,0x500,MEM_RELEASE);
                                        pMyAllocMemory = 0;
                                        VirtualFreeEx(hProcess,(LPVOID)dwExternData[5],SIZEOF_API_ARRAY * 1000,MEM_RELEASE);
                                        dwExternData[5] = 0;
                                        MessageBox(NULL,"内存分配失败2","",MB_OK);
                                        break;
                                }
                                lpszStringBuffer = (char *)VirtualAllocEx(hProcess,NULL,1000,MEM_COMMIT,PAGE_READWRITE);
                                if (!lpszStringBuffer)
                                {
                                        VirtualFreeEx(hProcess,pMyAllocMemory,0x500,MEM_RELEASE);
                                        pMyAllocMemory = 0;
                                        VirtualFreeEx(hProcess,(LPVOID)dwExternData[5],SIZEOF_API_ARRAY * 1000,MEM_RELEASE);
                                        dwExternData[5] = 0;
                                        VirtualFreeEx(hProcess,(LPVOID)hModuleArray,sizeof(HMODULE) * 100,MEM_RELEASE);
                                        hModuleArray = 0;
                                        MessageBox(NULL,"内存分配失败3","",MB_OK);
                                        break;
                                }
                                InitData();
                                break;
                        case 1:
                                hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
                                VirtualFreeEx(hProcess,pMyAllocMemory,0x500,MEM_RELEASE);
                                pMyAllocMemory = 0;
                                VirtualFreeEx(hProcess,(LPVOID)dwExternData[5],SIZEOF_API_ARRAY * 1000,MEM_RELEASE);
                                dwExternData[5] = 0;
                                VirtualFreeEx(hProcess,(LPVOID)hModuleArray,sizeof(HMODULE) * 100,MEM_RELEASE);
                                hModuleArray = 0;
                                VirtualFreeEx(hProcess,(LPVOID)lpszStringBuffer,1000,MEM_RELEASE);
                                lpszStringBuffer = 0;
                                break;
                        default:
                                break;
                }
        }
}
菜单处理程序,主要为调试程序的注入分配内存
pMyAllocMemory前面100个双字空间,用来存放一些变量(预留100个,真正用到的只有几个),然后再把注入的程序放在预留空间的后面
2010-2-28 21:11
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
__declspec(naked) void HookProc()
{
        __asm{
                push eax;
                push ecx;
                push edx;
                call loop1;
loop1:
                pop eax;
                add eax,2eh;//原本调用的函数名称
                push eax;
                call [pMyAllocMemory];//RecordCallProc,必须要另外更改地址
                call loop2;
loop2:
                pop eax;
                add eax,1ah;
                mov eax,[eax];//调用正常的API
                lea esp,[esp + 4];
                pop edx;
                pop ecx;
                xchg [esp],eax;
                ret;
        }
}
这是用来挂钩的函数,每个API复制一份(为了方便),当调用到一个API时,程序会先运行这段程序
call [pMyAllocMemory];这句在后面会做修整(在InitData()中修整),其实就是调用记录函数RecordCallProc
2010-2-28 21:14
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
最后一个RET返回后,是跳到API的调用中
2010-2-28 21:15
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
因为这函数尾部用来存放真正的API入口地址
call loop2;
loop2:
    pop eax;
    add eax,1ah;是获得尾部位置
mov eax,[eax];//得到真正的存放API入口地址的地址

xchg [esp],eax将真正的API入口地址和堆栈中原有的返回地址交换一下,那下面的RET就会跳到API中接着运行
2010-2-28 21:18
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
void InitData()
{
        int i;
        DWORD dwAddress,dwWrite,dwProcAddrEntry;
        HANDLE hProcess;
        BYTE * lpData;
        char szText[100];
        GETPROCADDRESS MyGetProcAddress = (GETPROCADDRESS)0x7C80AE45;
        LOADLIBRARY MyLoadLibrary = (LOADLIBRARY)0x7C801D7B;
        BOOL bRet;

        if (!pMyAllocMemory)
                return;
        dwProcAddrEntry = sizeof(DWORD) * 100 + (DWORD)pMyAllocMemory;
        hProcess = (HANDLE)_Plugingetvalue(VAL_HPROCESS);
        //dwExternData[0] = offset RecordCallProc
        dwExternData[0] = (DWORD)RecordCallProc - (DWORD)HookGetProcAddress + (DWORD)dwProcAddrEntry;
        //dwExternData[1] = offset HookGetProcAddress
        dwExternData[1] = (DWORD)dwProcAddrEntry;
        dwExternData[2] = 0;
        dwExternData[7] = (DWORD)LocalGetProcAddress1 - (DWORD)HookGetProcAddress + (DWORD)dwProcAddrEntry;
        //修正LocalGetProcAddress中的跳转
        //dwExternData[7] = offset LocalGetProcAddress1
        * (DWORD *)((BYTE *)LocalGetProcAddress + 2) = (DWORD)((BYTE *)pMyAllocMemory + 28);
        //修正LocalGetProcAddress1中的跳转
        //dwExternData[1] = offset HookGetProcAddress
        * (DWORD *)((BYTE *)LocalGetProcAddress1 + 3) = (DWORD)((BYTE *)pMyAllocMemory + 4);

        //写入HookProc的地址
        * (DWORD *)((DWORD)HookProc + 0x0f) = (DWORD)pMyAllocMemory;

        dwAddress = dwExternData[5];
        for (i = 0;i < 1000;i ++)
        {
                if (!WriteProcessMemory(hProcess,(LPVOID)dwAddress,HookProc,0x2c,&dwWrite))
                {
                        MessageBox(NULL,"无法注入内存","",MB_OK);
                        return;
                }
                dwAddress += SIZEOF_API_ARRAY;
        }
        _Addtolist(0,0,"API表初始化成功");

        lpData = (BYTE*)dwExternData;
        if (!WriteProcessMemory(hProcess,pMyAllocMemory,lpData,sizeof(DWORD) * 100,&dwWrite))
        {
                MessageBox(NULL,"无法注入内存1","",MB_OK);
                return;
        }
        memset(szStringBuffer,0,1000);
        strcpy(szStringBuffer,"kernel32.dll");
        strcpy(szStringBuffer + 100,"CreateFileA");
        strcpy(szStringBuffer + 200,"WriteFile");
        strcpy(szStringBuffer + 300,"e:\\log_files\\logfile.dat");
        strcpy(szStringBuffer + 400,"CloseHandle");
        strcpy(szStringBuffer + 500,"SetFilePointer");
        if (!WriteProcessMemory(hProcess,lpszStringBuffer,szStringBuffer,1000,&dwWrite))
        {
                MessageBox(NULL,"无法注入内存11","",MB_OK);
                return;
        }

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x45678123,(DWORD)lpszStringBuffer);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x56781234,(DWORD)lpszStringBuffer + 100);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x67812345,(DWORD)lpszStringBuffer + 200);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x78123456,(DWORD)lpszStringBuffer + 300);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x81234567,(DWORD)lpszStringBuffer + 400);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)RecordCallProc,0x91234567,(DWORD)lpszStringBuffer + 500);
        if (!bRet)
                return;

        bRet = SearchAndSet((BYTE *)HookGetProcAddress,0x12345678,(DWORD)pMyAllocMemory + 8);
        if (!bRet)
                return;
//        * (DWORD *)lpData = (DWORD)pMyAllocMemory + 8;
//        MessageBox(NULL,"123","",MB_OK);
        bRet = SearchAndSet((BYTE *)HookGetProcAddress,0x23456781,dwProcAddrEntry + (DWORD)OldGetProcAddress - (DWORD)HookGetProcAddress);
        if (!bRet)
                return;
//        MessageBox(NULL,"456","",MB_OK);
        bRet = SearchAndSet((BYTE *)RecordCallProc,0x7C80AE40,dwProcAddrEntry + (DWORD)OldGetProcAddress - (DWORD)HookGetProcAddress);
        if (!bRet)
                return;
//        MessageBox(NULL,"789","",MB_OK);

        if (!WriteProcessMemory(hProcess,(LPVOID)dwProcAddrEntry,HookGetProcAddress,0x300,&dwWrite))
        {
                MessageBox(NULL,"无法注入内存2","",MB_OK);
                return;
        }
        wsprintf(szText,"myApiArray = %X",dwExternData[5]);
        _Addtolist(0,0,szText);
        wsprintf(szText,"pMyAllocMemory = %X",pMyAllocMemory);
        _Addtolist(0,0,szText);
        wsprintf(szText,"hModuleArray = %X",hModuleArray);
        _Addtolist(0,0,szText);
        _Addtolist(0,0,"注入成功");

        //hook GetProcAddress
        if (!WriteProcessMemory(hProcess,(LPVOID)MyGetProcAddress,LocalGetProcAddress,7,&dwWrite))
        {
                MessageBox(NULL,"无法注入内存3","",MB_OK);
                return;
        }
}
2010-2-28 21:19
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
dwProcAddrEntry = sizeof(DWORD) * 100 + (DWORD)pMyAllocMemory;
因为我在pMyAllocMemory的前面预留了100个双字留作备用,而接下来就是用来存放 .txt段的代码
#pragma comment(linker,"/SECTION:.txt,REW")在addtion.cpp中
2010-2-28 21:21
0
雪    币: 285
活跃值: (16)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
25
dwProcAddrEntry就成为txt区块 要注入的 目标进程 的起始地址
2010-2-28 21:22
0
游客
登录 | 注册 方可回帖
返回
//