张老师,求教关于《软件调试》的示例程序的一个问题!

Windows内核调试

张老师,求教关于《软件调试》的示例程序的一个问题!


zyq8709 2013-05-08, 20:29 下午

在软件调试一书的一个示例程序ProtSeg.exe,是为了证明应用程序代码不可以直接修改段寄存器。但是在我测试的时候发生了奇怪的问题。表现如下:

第一次测试时间:在win7下使用vs2012编译,执行后崩溃在了 ntdll.dll中的lock btr    dword ptr [eax],0  语句上;当时我查看了gdt表,发现对应的表项为

0018 00000000 ffffffff Code RE Ac 3 Bg Pg P  Nl 00000cfb

当时我想可能是因为程序在写代码段的数据,所以发生了段保护异常。

于是我在程序中模拟了上述语句

__asm
 {
  mov bx,25
  mov ds,bx

  mov esi,ebp
  mov [esi-10h],eax
 }

也同样出现异常。

第二次测试,环境同上

int p=18;
 __asm
 {
  mov bx,25
  mov ds,bx
  mov esi,ebp 
  mov ds:[p],eax
 }

程序内竟然未出现异常,依旧是lock btr    dword ptr [eax],0 异常。

第三次测试,环境为win7,vs2010

int p;
 __asm
 {
  mov dx,cs
   mov  ds,dx
   mov ds:[p],0

 }

程序内竟然无任何异常,但却崩在了mov         dword ptr [mainret (1197154h)],eax  上,而这在前一个环境中是没有异常的。

我思考以后产生了以下问题:

看来出现异常的原因可能不是段描述符的属性保护问题,原因有二:

一、第一次测试我还看到在lock btr    dword ptr [eax],0之前还执行了 mov         dword ptr [mainret],eax  语句也无异常,这与第二次测试相似。

二、在第二个环境中,ds是否显式使用程序内都无问题,问题却出现在第一个中没有问题的位置上。

总之,感觉问题出现的很没有规律,看似与寻址方式有关又不全然如此。

只好来请教张老师,修改段寄存器出错的原因到底是什么,为什么感觉实验中出现的问题前后矛盾?

Re: 张老师,求教关于《软件调试》的示例程序的一个问题!


格蠹老雷 2013-05-10, 21:30 下午

正文中似乎没有提到这个例子吧?

在这个小例子的开头,有简单的注释:

/*---------------------------------------------------------------------
ProtSeg.cpp - Utility to watch protection of segment register. 
Software Debugging by Raymond Zhang, All rights reserved.
---------------------------------------------------------------------*/

意思是“用于观察段寄存器保护的小工具”,并没有说“应用程序不可以改段寄存器”哦^^

事实上,是可以改段寄存器,但是一定要提供有效的源操作数,也就是CPU保护段寄存器,防止被改为无效的值或者0(0是允许的)。

也就是IA手册上说的:

If the destination operand is a segment register (DS, ES, FS, GS, or SS), the source
operand must be a valid segment selector.

小例子中试图将DS改为25(0n19),这是不可以的,因为这不是一个有效的段选择子。

0:000> .formats 0n25
Evaluate expression:
  Hex:     00000019
  Decimal: 25
  Octal:   00000000031
  Binary:  00000000 00000000 00000000 00011001

参考《软件调试》P53,低两位是RPL,用户态的应该为0b11,也就是3,内核态的应该为0。

如果拿个有效的段寄存器内容看看

cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b 

0:000> .formats 2b
Evaluate expression:
  Hex:     0000002b
  Decimal: 43
  Octal:   00000000053
  Binary:  00000000 00000000 00000000 00101011

RPL是3

 

 

Re: 张老师,求教关于《软件调试》的示例程序的一个问题!


zyq8709 2013-05-11, 11:06 上午
多谢张老师的解答,这个程序和AcsVio.exe确实在软件调试一书中未提及,只是AcsVio.exe出现在了格蠹汇编中了:)。当时只是看了在网站的下载列表中的说明,没有去看程序中的说明,还是理解错误了,呵呵。

Re: 张老师,求教关于《软件调试》的示例程序的一个问题!


格蠹老雷 2013-05-11, 20:13 下午

你看的很仔细,网站示例的描述的确有点不准确,纠正了:

应用程序加载无效段寄存器导致异常

为附录A加了个勘误,多谢

Powered by Community Server Powered by CnForums.Net