首页
论坛
课程
招聘
雪    币: 217
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝

[调试逆向] 为OllyDbg增加LastBranchRecord功能

2009-1-14 16:45 15008

[调试逆向] 为OllyDbg增加LastBranchRecord功能

2009-1-14 16:45
15008
为OllyDbg增加LastBranchRecord功能

关于CPU的分枝监视功能,已经有牛人写过文章,<软件调试>书中也有详细介绍,就不多说了。直接给代码。
另外,我的代码是写在自己的插件中的,一堆乱七八糟的东西,就不给bin了,代码还算简单。

测试机器为WinXP Sp2,CPU为P4 Family0F Model6。

在驱动中创建与Ring3的共享内存,这里的代码直接从sudami的文章中copy的哈。

// 创建共享内存向Ring3传递数据
       
g_SharedMem = ExAllocatePool(NonPagedPool, PAGE_SIZE);
if (!g_SharedMem)
    goto __Fail;
       
g_MdlShared = IoAllocateMdl(g_SharedMem,
                            PAGE_SIZE,
                            FALSE,
                            FALSE,
                            NULL);
if (!g_MdlShared)
{
   ExFreePool(g_SharedMem);
   goto __Fail;
}
       
MmBuildMdlForNonPagedPool(g_MdlShared);

将内存映射到OllyDbg用户空间:

case IRP_MJ_DEVICE_CONTROL:

     switch (IrpSp->Parameters.DeviceIoControl.IoControlCode)
     {
        case IOCTL_INSTALL_HOOK:
            ...
               if (OutputLen >= sizeof(PVOID))
            {
                MapAddress = MmMapLockedPagesSpecifyCache (
                                  g_MdlShared,
                                UserMode,
                                MmNonCached,
                                NULL,
                                FALSE,
                                NormalPagePriority );

                if (MapAddress)
                {
                    //DbgPrint("Map ShareMem ok, MapAddress = %08X", MapAddress);
                    *(PVOID *)OutputBuffer = MapAddress;
                    InfoSize = sizeof(PVOID);
                }
            }
            ...

挂INT1:

volatile __declspec(naked) void NewInt01()
{
        //        - Interrupt 1 Handler -
        //
        //  offset   | contains
        //  ---------+-----------------------------
        //        esp                 : EIP Context
        //        esp + 4  : CS  Context
        //        esp + 8  : EFLAGS Context

        __asm
        {
                        pushad
                        push    fs
                        push    ds
                        push    es
                        mov     eax, 30h
                        mov     fs, ax
                        mov     eax, 23h
                        mov     ds, ax
                        mov     es, ax
                       
                        call        dword ptr [IoGetCurrentProcess]
                        cmp        eax, g_ObjProc        // Debuggee?
                        jne        __oldint01

                        mov        eax, dr6
                        bt        eax, 0Eh        //单步?
                        jnc        __oldint01

                                               
                        mov    eax, g_FastTrace //配置选项
                        cmp    eax, 1
                        jne    __oldint01

                        mov    edi, g_SharedMem
               
                        mov    ecx, MSR_LASTBRANCH_TOS
                        rdmsr
                        mov    ebx, eax
                        and    ebx, 0Fh          //TOS = 4位

                        mov    ecx, MSR_LASTBRANCH_0_FROM_LIP
                        add    ecx, ebx
                        rdmsr
                        mov    [edi], eax
                        mov    ecx, MSR_LASTBRANCH_0_TO_LIP
                        add    ecx, ebx
                        rdmsr
                        mov    [edi+4], eax

                        mov    ecx, MSR_DEBUGCTLA
                        rdmsr
                        or     eax, 3        // BTF & LBR
                        wrmsr
                       
__oldint01:       
                        pop    es               
                        pop    ds
                        pop    fs
                        popad
                        jmp    g_KiTrap01;
        }
}

这里没有用DebugStore,直接从LBR栈取数据,省事,而且支持多处理器。

下面是Ring3部分的代码。Hook了OllyDbg的WaitForDebugEvent。

case EXCEPTION_SINGLE_STEP: //单步异常

     // 判断一下是否处于TraceInto或TraceOver,这个没写,再说
     // 有时第1条数据记录的是内核地址,这里可以判断一下
       
    if (g_Ring0Options.FastTrace)
    {
        if (g_dwLBRCount < MAX_LBR_NUMBER)
        {
           g_LBRRecord[g_dwLBRCount].dwIndex = g_dwLBRCount;
           g_LBRRecord[g_dwLBRCount].dwThreadId = lpDbgEvent->dwThreadId;
           g_LBRRecord[g_dwLBRCount].dwFrom = ((PDWORD)g_SharedMem)[0];
           g_LBRRecord[g_dwLBRCount].dwTo   = ((PDWORD)g_SharedMem)[1];
                                       
       
           // 在这里读取代码,以防备SMC破坏代码

           if (_Readcommand(((PDWORD)g_SharedMem)[0], g_LBRRecord[g_dwLBRCount].CmdFrom) &&
              _Readcommand(((PDWORD)g_SharedMem)[1], g_LBRRecord[g_dwLBRCount].CmdTo))
           {
                _Addsorteddata(&g_LBRTable.data, &g_LBRRecord[g_dwLBRCount++]);
           }       
           else
           {
                _Addtolist(0, 1, "LBR Buffer Overrun");
           }
        }
    }
    ...

剩下的就是OD插件界面相关的,从Conditional Branch Logger抄的。

需要说明的是,OD自己的Trace功能,若选择Always trace over system DLLs,估计是用int3断点来获取调用后的控制。
用BTF位,则任何控制转移都会被记录,不过可以在WaitForDebugEvent中筛选一下记录的数据。另外,也可以在驱动中做
得更好点,只在运行被调试进程时才打开LBR。不过我的测试似乎性能下降不大,至少不比OD自己的跟踪差。

上个图。加载一个用UPX加壳的程序,用OllyBone对第1区段下执行断点。OllyBone我也抄了,不过功能有点
问题,这里先不管它了,对这个程序是可以的。

Ctrl-F11开始跟。到OEP停下显示数据。共90000多条数据。可以清楚看到是怎样跳到OEP的,对于有花指令的代码有点用。
当然,最好不要加载完就这样干,那样数据太多了。

本来想把OD的语法配色也搞出来,感觉比较复杂,就算啦。图标也用的CBL插件的。



HWS计划·2020安全精英夏令营来了!我们在华为松山湖欧洲小镇等你

上传的附件:
最新回复 (38)
雪    币: 310
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
stalker 活跃值 8 2009-1-14 16:47
2
0
沙发是我的123456
雪    币: 80
活跃值: 活跃值 (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
uvbs 活跃值 2009-1-14 16:50
3
0
牛~~一直想有这么个东西对付VM
雪    币: 80
活跃值: 活跃值 (30)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
uvbs 活跃值 2009-1-14 16:54
4
0
不打算公开这个plu么
看LZ说的加点对log的筛选可能有点用
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
ezme 活跃值 2009-1-14 17:15
5
0
强大,指哪打哪啊
雪    币: 211
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX 活跃值 2009-1-14 17:18
6
0
大牛的东西要顶
雪    币: 945
活跃值: 活跃值 (812)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2009-1-14 17:24
7
0
softworm又出招了
雪    币: 750
活跃值: 活跃值 (17)
能力值: (RANK:730 )
在线值:
发帖
回帖
粉丝
海风月影 活跃值 17 2009-1-14 17:36
8
0
放bin估计我都用不起来
雪    币: 5
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhingma 活跃值 2009-1-14 17:37
9
0
强大.
无语,只有膜拜.
雪    币: 8005
活跃值: 活跃值 (75)
能力值: ( LV15,RANK:1662 )
在线值:
发帖
回帖
粉丝
ccfer 活跃值 15 2009-1-14 17:47
10
0
我是来剽窃的
雪    币: 200
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
shoooo 活跃值 16 2009-1-14 17:58
11
0
本贴过于强大
害得我死机了
雪    币: 246
活跃值: 活跃值 (11)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 活跃值 10 2009-1-14 18:00
12
0
wo zen you da bu chu zhong wen le..
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
lunglungyu 活跃值 1 2009-1-14 18:10
13
0
看着貌似好爽.......
雪    币: 100
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
夜凉如水 活跃值 3 2009-1-14 18:20
14
0
奥迪都死机了我也怕怕等大牛开发插件我用了
雪    币: 477
活跃值: 活跃值 (75)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
KooJiSung 活跃值 2009-1-14 19:51
15
0
看图好像不错
雪    币: 326
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 活跃值 4 2009-1-14 20:10
16
0
这家伙外号还蛮多:
4圈,4o,上海奥迪,,,,
雪    币: 462
活跃值: 活跃值 (29)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
iawen 活跃值 3 2009-1-14 21:05
17
0
先膜拜一下,
然后留个名,
再膜拜一下,
雪    币: 204
活跃值: 活跃值 (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
orchid88 活跃值 2009-1-14 21:29
18
0
非常好的思路,太强了。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
Ryosuke 活跃值 24 2009-1-14 21:34
19
0
我是进来膜拜LZ的
雪    币: 217
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 活跃值 30 2009-1-14 21:44
20
0
能被cc剽窃是种荣誉
雪    币: 5535
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 活跃值 26 2009-1-14 21:46
21
0
sm的眼睛还没好啊,字体这么大
雪    币: 217
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 活跃值 30 2009-1-14 21:49
22
0
就你眼睛毒
雪    币: 278
活跃值: 活跃值 (15)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
zhuwg 活跃值 11 2009-1-14 21:54
23
0
赶来膜拜了..............
雪    币: 14981
活跃值: 活跃值 (1280)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 活跃值 2009-1-14 21:58
24
0
大家的技术都了得啊,123456 能代表你吗?

有技术的谁说123456
雪    币: 14981
活跃值: 活跃值 (1280)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 活跃值 2009-1-14 21:59
25
0
AGAIN 还有一句 膜拜

真没有 意义
雪    币: 250
活跃值: 活跃值 (20)
能力值: ( LV12,RANK:450 )
在线值:
发帖
回帖
粉丝
weolar 活跃值 10 2009-1-14 22:22
26
0
为什么不放完整的代码?要考虑的东西还很多啊,光凭这点代码还很麻烦。不过还是感谢分享
雪    币: 564
活跃值: 活跃值 (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 活跃值 2009-1-15 11:01
27
0
好厉害
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
冷血正宇 活跃值 2009-1-15 11:13
28
0
路     过     了
雪    币: 348
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
jerrylhj 活跃值 2009-1-15 13:39
29
0
厉害,弄成插件就好了
雪    币: 2058
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
书呆彭 活跃值 6 2009-1-15 15:48
30
0
跟我想到一起了。我正准备假期做这么个东西,作为我学习驱动开发的第一个产品,居然有人也有此想法,已经实现了。那么,我一定要好好研读一下,学习一下了。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sddxqczh 活跃值 2009-1-15 16:38
31
0
如果有插件大家用就方便多了,现在这莫多小弟不敢恭维
雪    币: 217
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 活跃值 30 2009-1-15 18:21
32
0
语法高亮解决了,把代码贴上来

OD的插件文档很龌龊啊,Disasm命令是可以生成mask数据的,文档不提:

_Disasm((uchar*)e->CmdFrom,
        MAXCMDSIZE,
        e->dwFrom,
        NULL,
        &disasm,
        DISASM_CODE | 0x00010000, //对比Olly的ini文件,这个值取1或2才有实际意义,3或4没效果
        0);

在高16位设置就行,只有1或2有效果,对比一下ini文件就知道。注意加了这个标记后,必须修改
Plugin.h中的t_disasm机构定义,把最后的reserved从29改为100,头文件的结构不够大,我试了80都不够:-(

语法mask数据在+0x860处。

另外说一下,不放插件不是我小气,我的驱动基本用来测试的,看到什么有意思的就塞进去试试,
乱七八糟的东西一堆,没法放。关键代码基本给全了,再参考一下CBL插件,自己搞出来不是问题
上传的附件:
雪    币: 504
活跃值: 活跃值 (19)
能力值: (RANK:570 )
在线值:
发帖
回帖
粉丝
笨笨雄 活跃值 14 2009-1-15 18:34
33
0
支持不放BIN
雪    币: 164
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
第八个门 活跃值 1 2009-1-15 19:01
34
0
支持要放BIN
雪    币: 337
活跃值: 活跃值 (21)
能力值: ( LV9,RANK:690 )
在线值:
发帖
回帖
粉丝
winndy 活跃值 17 2009-1-15 20:54
35
0
偶像

对WoRMdbg也比较感兴趣
雪    币: 153
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
stoy 活跃值 2009-1-15 21:58
36
0
很好很强大。
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
易达 活跃值 2009-1-15 22:53
37
0
很强大  很暴力………………………………………………
雪    币: 200
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
真Λ安全 活跃值 2009-1-16 13:25
38
0
等 我 出 关 再 来 拜 山
雪    币: 199
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bobo801123 活跃值 2009-1-19 22:01
39
0
等大大们给插件
游客
登录 | 注册 方可回帖
返回