首页
社区
课程
招聘
为OllyDbg增加LastBranchRecord功能
2009-1-14 16:45 17193

为OllyDbg增加LastBranchRecord功能

2009-1-14 16:45
17193
为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插件的。


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

上传的附件:
收藏
点赞7
打赏
分享
最新回复 (38)
雪    币: 399
活跃值: (38)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
stalker 8 2009-1-14 16:47
2
0
沙发是我的123456
雪    币: 60
活跃值: (479)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
uvbs 2009-1-14 16:50
3
0
牛~~一直想有这么个东西对付VM
雪    币: 60
活跃值: (479)
能力值: ( 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
强大,指哪打哪啊
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX 2009-1-14 17:18
6
0
大牛的东西要顶
雪    币: 32410
活跃值: (18730)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 8 2009-1-14 17:24
7
0
softworm又出招了
雪    币: 7300
活跃值: (3758)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
海风月影 22 2009-1-14 17:36
8
0
放bin估计我都用不起来
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zhingma 2009-1-14 17:37
9
0
强大.
无语,只有膜拜.
雪    币: 8188
活跃值: (4243)
能力值: ( LV15,RANK:2459 )
在线值:
发帖
回帖
粉丝
ccfer 16 2009-1-14 17:47
10
0
我是来剽窃的
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
shoooo 16 2009-1-14 17:58
11
0
本贴过于强大
害得我死机了
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
Isaiah 10 2009-1-14 18:00
12
0
wo zen you da bu chu zhong wen le..
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
lunglungyu 1 2009-1-14 18:10
13
0
看着貌似好爽.......
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
夜凉如水 3 2009-1-14 18:20
14
0
奥迪都死机了我也怕怕等大牛开发插件我用了
雪    币: 357
活跃值: (2593)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
KooJiSung 2009-1-14 19:51
15
0
看图好像不错
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 4 2009-1-14 20:10
16
0
这家伙外号还蛮多:
4圈,4o,上海奥迪,,,,
雪    币: 359
活跃值: (430)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
iawen 3 2009-1-14 21:05
17
0
先膜拜一下,
然后留个名,
再膜拜一下,
雪    币: 83
活跃值: (605)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
orchid88 2009-1-14 21:29
18
0
非常好的思路,太强了。
雪    币: 370
活跃值: (78)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
Ryosuke 24 2009-1-14 21:34
19
0
我是进来膜拜LZ的
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2009-1-14 21:44
20
0
能被cc剽窃是种荣誉
雪    币: 6073
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
forgot 26 2009-1-14 21:46
21
0
sm的眼睛还没好啊,字体这么大
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
softworm 30 2009-1-14 21:49
22
0
就你眼睛毒
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
zhuwg 11 2009-1-14 21:54
23
0
赶来膜拜了..............
雪    币: 85199
活跃值: (198520)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
linhanshi 2009-1-14 21:58
24
0
大家的技术都了得啊,123456 能代表你吗?

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

真没有 意义
游客
登录 | 注册 方可回帖
返回