Re: 分支单步执行

WinDbg

分支单步执行


Blade 2013-08-17, 16:13 下午

《软件调试》 99的页 有个分支到分支单步执行的例子, 我实验时却不成功,ZwSystemDebugControl 返回值为 -1073741822,  参考http://advdbg.org/forums/910/ShowPost.aspx 这篇帖子的内容, 在WIN7下需要MSR驱动, 我不会写驱动, 也不知道哪里下载, 所以就在XP下实验, 起初是在虚拟机下, ZwSystemDebugControl 返回为0  , 应该是失败了, 依旧没办法进行分支单步执行, 还是普通的单步执行。后来我直接安装了真实的XP系统, 安装了VS2005, 实验结果依然如故。 所以请教张老师和各位大侠, 问题到底出现在哪里。

我的CPU 型号是 I5-2450M。 双核4线程。

lkd> !cpuinfo
CP  F/M/S Manufacturer  MHz PRCB Signature    MSR 8B Signature Features
 0  6,42,7 GenuineIntel 2494 0000002500000000 >0000002500000000<a0033fff
 1  6,42,7 GenuineIntel 2494 0000002500000000                   a0033fff
 2  6,42,7 GenuineIntel 2494 0000002500000000                   a0033fff
 3  6,42,7 GenuineIntel 2494 0000002500000000                   a0033fff

我的CPU 是 Core 系列的, 有个TM 的小上标, 在intel官网的手册上到对应的部分, 调试MSR 是 1D9H, BTF也是bit 1, 和代码中的是一致的, 应该是无需更改的。

Re: 分支单步执行


格蠹老雷 2013-08-17, 16:23 下午

是XP SP3吧?SP3默认也禁止了本地内核调试。要带内核调试启动,试试看

 

Re: 分支单步执行


Blade 2013-08-17, 19:05 下午
非常感谢张老师, 我发帖后10分钟就回复了, 我没想到会这么快, 所以提问后就去睡觉了, 真是不好意思。

我的系统是XP SP3。
我在boot.ini 的启动项后 增加/debug选项, 按理说应该是开启了内核模式, 启动界面的菜单 也看到菜单后多了 【启动调试***】字样。
但是非常奇怪的是, 似乎没有成功的开启内核调试, 因为我只能用windbg 6.9 的版本才能用本地内核模式, 6.10, 6.11 都会有如下错误信息:
Unable to read head of debugger data list, NTSTATUS 0xC0000001

6.9 的winbg 虽成功进入也有警告信息。
Microsoft (R) Windows Debugger Version 6.9.0003.113 X86
Copyright (c) Microsoft Corporation. All rights reserved.

Unable to read head of debugger data list
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Symbol search path is: srv*M:\symbols*http://msdl.microsoft.com/download/symbols;cache*M:\symbols

Executable search path is: 
*******************************************************************************
WARNING: Local kernel debugging requires booting with kernel
debugging support (/debug or bcdedit -debug on) to work optimally.
*******************************************************************************
Windows XP Kernel Version 2600 (Service Pack 3) MP (4 procs) Free x86 compatible
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 2600.xpsp_sp3_gdr.101209-1647
Kernel base = 0x80800000 PsLoadedModuleList = 0x80886720
Debug session time: Sat Aug 17 19:00:18.203 2013 (GMT+8)
System Uptime: 0 days 0:08:34.741

这实在是令我百思不得其解, 我估计我使用的XP系统可能因为盗版的原因导致有所缺失, 不能正常启动kernel debug, 不知道有什么办法可以判断我的MSR驱动正常工作着。  

我先去吃晚饭, 到时候看是重装系统还是怎么办。


Re: 分支单步执行


Blade 2013-08-18, 16:27 下午
我重装了微软原版的操作系统, 别问我为什么这么晚才回复, 装这个系统我从昨晚到现在才弄好, 我哭啊......................
下面的一段是倒苦水, 可以跳过

原版的系统超难装有木有......我下载的是一个ISO 镜像, 进入PE , 解压运行里面的Setup.exe  运行后菜单里的第一项是安装系统, 但是居然是灰色不可用, 以前都可以这样直接在PE里面安装, 然后又不是ghost版,也不能用ghost安装的方式, 因为和以前安装的镜像不一样, 我 各种办法各种试, 折腾了一晚上, 最后找到了用PE中的工具Win&Man 安装, 结果又引导失败,因为我笔记本是两块硬盘, 加了一个SSD, 以前的硬盘改到光驱位了, 可能因为这个原因引导失败 所以我改了几次引导分区, 然后成功了, 这次好不容易安装好了系统, 安装成功了又蓝屏, 我囧。。。然后查到是AHCI 驱动没装的原因, 然后BIOS硬盘模式改成兼容模式, 没蓝屏,成功进去了, 然后安装AHCI驱动的过程又把我逼疯了.....按照网上的教程进行安装, 一安装就蓝屏, 不知道是不是又因为我的硬盘环境复杂, 是光驱位改装引起的, 后来我把AHCI驱动文件存放目录换到系统盘之外的另一个分区中, 然后就成功了。 今天下午两点多才把系统弄好。 哎, 没有经验, 浪费了时间, 走了弯路, 之前搜索的教程都是 U盘安装XP、 XP U盘启动盘制作之类的, 我刚刚回过头来试试搜索 PE安装原版XP , 就发现了我那个PE下直接运行,安装菜单呈现灰色的问题 可以通过手动运行i386下面的WINNT32.EXE 来解决, 可惜当时没想到白白花了时间, 今天不知道重启了多少次, 蓝屏了多少次.....。

虽然花了时间, 但是功夫不负有心人, XP终于可以在6.9b版本以外的windbg上开启本地内核模式了, 我估计ghost 和 其他各种杂七杂八的ISO镜像可能有出现这个问题和其他问题的隐患,为了排除系统又问题这一个因素,  所以虽然原版害的我纠结万分, 安装耗时, 但是还是没有放弃原版, 终于成功装好, 更欣慰的时 本VS2005 进行分支到分支的实验终于成功了, 之前失败的原因估计就是张老师说的根本就没有启动内核调试, 问题搞定, 非常感谢张老师!

Re: 分支单步执行


Blade 2013-08-18, 16:31 下午

对了, 有个问题想请教一下ZwSystemDebugControl 函数返回多少才算成功? 我刚才试验成功了, 但是还是返回0, 最后ReadMSR()的时候 掉这个函数也还是返回 0.

刚才顺便把以前没法做的4M内存页试验也做了下, 现在是内核是大页面, 试验成功, 原版就是好呀, 以前碰到的问题统统都不见了。

Re: 分支单步执行


格蠹老雷 2013-08-18, 22:07 下午
ZwSystemDebugControl的返回类型是NTSTATUS,0代表S_OK,是成功,负数代表失败

Re: 分支单步执行


Blade 2013-08-18, 22:45 下午
我想再请教一下 分支到分支的规则是什么?
《软件调试》 中第100页 说 “CPU认为有分支发生的条件执行 JMP Jcc LOOP CALL等, 难道是执行一条这个指令后 就算遇到分支?
我自己修改代码的分支条件,然后调试看结果, 我觉得像是执行跳转 之后就算是遇到分支, JNE 这样的条件判断并不是一定就算分支, 如果条件成立, 实际跳转了, 才算遇到分支, 反之条件不成立, 就没有跳转, 就要等下一个跳转语句。 遇到跳转了, 跳转后中断。 这是我的理解

0042DAD2  mov         eax,dword ptr [ebp-14h] 
0042DAD5  imul        eax,dword ptr [ebp-14h] 
0042DAD9  cdq              
0042DADA  idiv        eax,dword ptr [ebp-14h] 
0042DADD  cmp         dword ptr [ebp-14h],eax 
0042DAE0  jne         main+13Bh (42DAEBh)  //----------1
{
m=1;
0042DAE2  mov         dword ptr [ebp-14h],1 

}
else
0042DAE9  jmp         main+142h (42DAF2h) //-----------2
{
m=2;
0042DAEB  mov         dword ptr [ebp-14h],2 

}
//End of the code which runs in full speed
m*=m;
0042DAF2  mov         eax,dword ptr [ebp-14h] //----------3
0042DAF5  imul        eax,dword ptr [ebp-14h] 
0042DAF9  mov         dword ptr [ebp-14h],eax 

如上图所示 在1处时, 条件判断的结果是没有跳转(到 m =2出), 而是顺序执行, 执行完m = 1;, 会执行 2处代码, 跳转到3, 此时才算是真的”跳“(飞)了一次, 之后就中断了。
如果将代码修改一下 

m=10,n=2;
m=n*2-1;
if(m==m*m/m)
{
m=1;
if(1 > 2)
{
int a = 3;
}
else
{
int b = 4;
}
int c = 1;
}
else
{
m=2;

}
//End of the code which runs in full speed
m*=m;

对应汇编为

0042DABA  mov         dword ptr [ebp-14h],0Ah 
0042DAC1  mov         dword ptr [ebp-20h],2 
m=n*2-1;
0042DAC8  mov         eax,dword ptr [ebp-20h] 
0042DACB  lea         ecx,[eax+eax-1] 
0042DACF  mov         dword ptr [ebp-14h],ecx 
if(m==m*m/m)
0042DAD2  mov         eax,dword ptr [ebp-14h] 
0042DAD5  imul        eax,dword ptr [ebp-14h] 
0042DAD9  cdq              
0042DADA  idiv        eax,dword ptr [ebp-14h] 
0042DADD  cmp         dword ptr [ebp-14h],eax 
0042DAE0  jne         main+156h (42DB06h) //-------------------a
{
m=1;
0042DAE2  mov         dword ptr [ebp-14h],1 
if(1 > 2)
0042DAE9  xor         eax,eax 
0042DAEB  je          main+146h (42DAF6h) //--------------------b
{
int a = 3;
0042DAED  mov         dword ptr Angel [A],3 
}
else
0042DAF4  jmp         main+14Dh (42DAFDh) 
{
int b = 4;
0042DAF6  mov         dword ptr Beer [B],4 //----------------------------c
}
int c = 1;
0042DAFD  mov         dword ptr Coffee [C],1 
}
else
0042DB04  jmp         main+15Dh (42DB0Dh) 
{
m=2;
0042DB06  mov         dword ptr [ebp-14h],2 

}
//End of the code which runs in full speed
m*=m;
0042DB0D  mov         eax,dword ptr [ebp-14h] 
0042DB10  imul        eax,dword ptr [ebp-14h] 
0042DB14  mov         dword ptr [ebp-14h],eax 

此时先在a 处 未能跳转, 顺序执行 到 b 处, 跳转到了c处, 跳转后中断。

然后还进行了条件的修改 做了几次试验, 先将WirteMSR注释掉, 观察单步执行流程, 再解开注释观察分支跳转方式, 比较之后, 我观察到了这个规律, 我这样理解是否正确? 因为书中的描述我想不通....只好先以自己的想法理解了, 请张老师指点迷津。

Re: 分支单步执行


Blade 2013-08-21, 23:54 下午
张老师, 是不是忘记我了.....有空的时候帮我看看我的问题好吗?

Re: 分支单步执行


格蠹老雷 2013-08-22, 12:57 下午

不好意思,忘记这个贴了

仔细看了下,你说的非常对,是要真正发生跳转时才触发事件

 

Re: 分支单步执行


Blade 2013-08-22, 21:20 下午
恩, 我对自己的推测一直半信半疑, 谢谢张老师释疑。 

Powered by Community Server Powered by CnForums.Net