关于《软件调试》4.3.4 按分支单步执行。

《软件调试》的示例程序

关于《软件调试》4.3.4 按分支单步执行。


skyworth 2008-07-01, 22:17 下午
一开始执行的是自己编译的程序,发现无法按分支单步执行,而是老老实实的按高级语言的单步执行。以为是编译器的原因,检查生成的汇编代码,没发现什么可以的地方。后下载了随书附带的示例程序,调试的过程中,发现依然有问题。检查EFLAGS寄存器的值,发现TF位已经置1。查阅Intel手册,发现处理器的DEBUGCTRL_MSR为0x1D9,与例子相同。我的处理器为PE2160。这下就彻底糊涂了。

Re: 关于《软件调试》4.3.4 按分支单步执行。


skyworth 2008-07-03, 00:00 上午
检查了一下ZwSystemDebugControl的返回值,为-1073741822,返回负值,应该是调用失败了。

Re: 关于《软件调试》4.3.4 按分支单步执行。


skyworth 2008-07-03, 22:42 下午
貌似这个API在Windows Server 2003 SP2之后就不可用了,ft

Re: 关于《软件调试》4.3.4 按分支单步执行。


格蠹老雷 2008-07-03, 23:29 下午
这应该就是根源,建议你在XP系统上做一下。如果一定要在Windows Server 2003 SP2或者更高的版本上做,那么需要有一个驱动来访问MSR寄存器。这样的小驱动程序很多。

Re: 关于《软件调试》4.3.4 按分支单步执行。


skyworth 2008-07-04, 00:15 上午
呵呵,关键是我的机器上一直就没有Windows XP的,看上去只有写驱动这一个办法了,网上下的东西,呵呵,如果不是确信安全,一般不敢运行,更何况是内核级别的东西。只好自己写一个试试看吧。以前写过很简单linux下的驱动的,Windows下的应该不是太难。只是希望别偏太远,最后弄成了驱动开发学习就不好了^_^.

Re: 关于《软件调试》4.3.4 按分支单步执行。


shl 2008-07-22, 18:40 下午
是处理器的问题,我的是PE2140,同样记录不到任何东西

Re: 关于《软件调试》4.3.4 按分支单步执行。


shl 2008-07-22, 18:41 下午
不好意思,我是LBR/BTS啥都记录不到

Re: 关于《软件调试》4.3.4 按分支单步执行。


格蠹老雷 2008-07-24, 22:21 下午

LBR是P6(Pentium Pro)就开始支持的功能。你能描述一下具体的现象么,在什么环境下,怎么记录不到?关于BTS,可以通过IA32_MISC_ENABLE MSR寄存器(地址为416-十进制)来检查是否支持,如果位11为0则支持,为1则不支持。

以我现在用的笔记本为例,其CPU是P6系统的奔腾M,因此支持LBR。

lkd> !lbr.lbr
Access LBR (Last Branch Recording) registers of IA-32 CPU.
Version 1.0.0.2 by Raymond
MSR_DEBUGCTLB=1
LBR bit is cleared now.
MSR_LASTBRANCH_TOS=3
MSR_LASTBRANCH_3: [804ff190] nt!WRMSR+0
MSR_LASTBRANCH_3: [8065ef6e] nt!KdpSysWriteMsr+1c
MSR_LASTBRANCH_2: [8065ef5e] nt!KdpSysWriteMsr+c
MSR_LASTBRANCH_2: [805374da] nt!_SEH_prolog+3a
MSR_LASTBRANCH_1: [805374a0] nt!_SEH_prolog+0
MSR_LASTBRANCH_1: [8065ef59] nt!KdpSysWriteMsr+7
MSR_LASTBRANCH_0: [8065ef52] nt!KdpSysWriteMsr+0
MSR_LASTBRANCH_0: [8060d364] nt!NtSystemDebugControl+356
MSR_LASTBRANCH_7: [8060d356] nt!NtSystemDebugControl+348
MSR_LASTBRANCH_7: [8060d0c3] nt!NtSystemDebugControl+b5
MSR_LASTBRANCH_6: [8060d0b6] nt!NtSystemDebugControl+a8
MSR_LASTBRANCH_6: [8060d0a1] nt!NtSystemDebugControl+93
MSR_LASTBRANCH_5: [8060d09c] nt!NtSystemDebugControl+8e
MSR_LASTBRANCH_5: [8060d08d] nt!NtSystemDebugControl+7f
MSR_LASTBRANCH_4: [8060d089] nt!NtSystemDebugControl+7b
MSR_LASTBRANCH_4: [8060d082] nt!NtSystemDebugControl+74
LBR bit is set now.

使用本地内核调试,然后执行 !cpuinfo命令就可以读到CPU的系列号:

lkd> !cpuinfo
CP  F/M/S Manufacturer  MHz PRCB Signature    MSR 8B Signature Features
 0  6,13,8 GenuineIntel 1862 0000002000000000  0000002000000000 a0033fff

其中的的6是系列6,13是型号,8是Stepping(版本)

使用version命令可以显示操作系统和WinDBG的详细版本号

lkd> version
Windows XP Kernel Version 2600 (Service Pack 2) UP Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp2_qfe.070227-2300
Kernel base = 0x804d7000 PsLoadedModuleList = 0x805535a0
Debug session time: Thu Jul 24 22:22:47.229 2008 (GMT+8)
System Uptime: 0 days 1:46:45.299
Local KD

Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

command line: '"C:\windbgbeta\windbg.exe" '  Debugger Process 0x1740
dbgeng:  image 6.9.0003.113, built Fri Mar 21 04:29:34 2008
        [path: C:\windbgbeta\dbgeng.dll]
dbghelp: image 6.9.0003.113, built Fri Mar 21 04:28:43 2008
        [path: C:\windbgbeta\dbghelp.dll]
        DIA version: 21024
Extension DLL search Path:

 

Re: 关于《软件调试》4.3.4 按分支单步执行。


shl 2008-07-25, 17:31 下午
我的是PE2140,我是在驱动中实现了LBR。0x1D9中写 ( 1 << 0) | ( 1 << 1 ),在1号中断中实现记录信息,可以记录得到,但,现在的问题是,开启LBR+BTF后,只记录OD调试的程序的分支,并不是像我理解的“记录所有程序的分支”,请问,为何?我做了一个小录象,记录了我这一诡异现象。如果方便,请作者能过目,帮我解答一二,谢谢。

另外,BTS是什么都记录不到,通过检测IA32_MISC_ENABLE MSR位是支持的,在往0x600中写0xC0[( 1 << 6) | ( 1 << 7),TR和BTS位],写入成功的话,应该是开始记录所有信息的,对么?

Re: 关于《软件调试》4.3.4 按分支单步执行。


格蠹老雷 2008-07-26, 09:53 上午
SHL,关于记录到的分支,LBR只能记录最近几次的分支,因为CPU“最近”就是执行你的调试程序,所以你看到的内容就是那样。这是正常的,你观察我上面给出的例子,记录的也是CPU执行WinDBG的本地内核调试任务(NtSystemDebugControl和WRMSR)时的动作。
LBR能记录的分支次数较少,这也是它的最大局限。
对于第二个问题,BTS寄存器的地址和设置方法是与CPU型号有关的。你应该先用CPUID命令检查CPU型号,然后根据型号采取动作,就像清单5-5那样。

Re: 关于《软件调试》4.3.4 按分支单步执行。


shl 2008-07-26, 12:34 下午
to:Raymond

不好意思,可能是我没描述清楚
首先,我是用中断的方式,每次取一个值,这样来循环取,可以取到一个程序的所有分支,突破了LBR的"局限"

但是,当我开启驱动之后,需要用OD打开一个程序,并且单步一下或者是运行,驱动才开始记录.而且,他只记录OD打开的这个程序的所有分支,而,通过双击运行这样就不开始记录.

不知道我的问题描述清楚了没有.谢谢

Re: 关于《软件调试》4.3.4 按分支单步执行。


格蠹老雷 2008-07-26, 17:22 下午
还是不太清楚你的想法。在一个多任务的操作系统中,CPU在很多个任务和中断处理函数间忙碌。你怎么能保证读LBR的前一刹那就是在执行你用OD(OlleyDbg??)跟踪的程序呢?

Re: 关于《软件调试》4.3.4 按分支单步执行。


shl 2008-07-27, 09:08 上午
不是我的想法,是我这里的现象
我觉得很诡异

现象:开启LBR之后,记录不到任何数据,当OllyDBG跟踪某个程序的时候,它才开始记录数据,并且,只记录这个被跟踪的程序的分支

Re: 关于《软件调试》4.3.4 按分支单步执行。


forgot 2008-07-31, 19:05 下午

跑这里来问了啊,

BTF开启之后TF被视为是 Single Step On Branches,不是分支指令就不会 int1。

To Raymond:

   所谓突破限制是指,hook 所有处理器的 int1 isr ,可以在中断里重新设置TF,然后根据 fs 判断进程记录一次LBR。

Re: 关于《软件调试》4.3.4 按分支单步执行。


王宇 2008-07-31, 20:28 下午
WOW...

forgot 是 No.8 Man 等的那位吗?
 总页数 1 第 2 页 [共有 23 条记录] 1 2 >

Powered by Community Server Powered by CnForums.Net