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

为OllyDbg增加LastBranchRecord功能

2009-1-14 16:45
17911

为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插件的。


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (38)
雪    币: 399
活跃值: (38)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
沙发是我的123456
2009-1-14 16:47
0
雪    币: 30
活跃值: (910)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
牛~~一直想有这么个东西对付VM
2009-1-14 16:50
0
雪    币: 30
活跃值: (910)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
不打算公开这个plu么
看LZ说的加点对log的筛选可能有点用
2009-1-14 16:54
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
强大,指哪打哪啊
2009-1-14 17:15
0
雪    币: 218
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
NaX
6
大牛的东西要顶
2009-1-14 17:18
0
雪    币: 50161
活跃值: (20625)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
7
softworm又出招了
2009-1-14 17:24
0
雪    币: 7325
活跃值: (3803)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
8
放bin估计我都用不起来
2009-1-14 17:36
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
强大.
无语,只有膜拜.
2009-1-14 17:37
0
雪    币: 8209
活跃值: (4528)
能力值: ( LV15,RANK:2473 )
在线值:
发帖
回帖
粉丝
10
我是来剽窃的
2009-1-14 17:47
0
雪    币: 398
活跃值: (343)
能力值: (RANK:650 )
在线值:
发帖
回帖
粉丝
11
本贴过于强大
害得我死机了
2009-1-14 17:58
0
雪    币: 331
活跃值: (56)
能力值: ( LV13,RANK:410 )
在线值:
发帖
回帖
粉丝
12
wo zen you da bu chu zhong wen le..
2009-1-14 18:00
0
雪    币: 207
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
看着貌似好爽.......
2009-1-14 18:10
0
雪    币: 136
活跃值: (105)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
14
奥迪都死机了我也怕怕等大牛开发插件我用了
2009-1-14 18:20
0
雪    币: 357
活跃值: (3588)
能力值: ( LV3,RANK:25 )
在线值:
发帖
回帖
粉丝
15
看图好像不错
2009-1-14 19:51
0
雪    币: 370
活跃值: (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
16
这家伙外号还蛮多:
4圈,4o,上海奥迪,,,,
2009-1-14 20:10
0
雪    币: 359
活跃值: (440)
能力值: ( LV9,RANK:150 )
在线值:
发帖
回帖
粉丝
17
先膜拜一下,
然后留个名,
再膜拜一下,
2009-1-14 21:05
0
雪    币: 82
活跃值: (725)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
非常好的思路,太强了。
2009-1-14 21:29
0
雪    币: 370
活跃值: (78)
能力值: ( LV9,RANK:970 )
在线值:
发帖
回帖
粉丝
19
我是进来膜拜LZ的
2009-1-14 21:34
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
20
能被cc剽窃是种荣誉
2009-1-14 21:44
0
雪    币: 6075
活跃值: (2236)
能力值: (RANK:1060 )
在线值:
发帖
回帖
粉丝
21
sm的眼睛还没好啊,字体这么大
2009-1-14 21:46
0
雪    币: 494
活跃值: (629)
能力值: ( LV9,RANK:1210 )
在线值:
发帖
回帖
粉丝
22
就你眼睛毒
2009-1-14 21:49
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
23
赶来膜拜了..............
2009-1-14 21:54
0
雪    币: 98729
活跃值: (201034)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
24
大家的技术都了得啊,123456 能代表你吗?

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

真没有 意义
2009-1-14 21:59
0
游客
登录 | 注册 方可回帖
返回
//