flyfox
驱动中牛
驱动中牛
  • 注册日期2001-04-05
  • 最后登录2012-08-03
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望22点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
阅读:2492回复:13

还有一个LU0老大没有回答的问题-线性地址是如何切换的,我也很奇怪,ZN你能解释下么

楼主#
更多 发布于:2002-01-28 17:45
http://www.driverdevelop.com/forum/viewthread.php?tid=7460
我调试了下,的确如此,按道理物理地址不应该更改啊,除非在有限时间里,线程调度,把初始地址给其他县城用,这个线程RUN时,又给了一个新的??????

[编辑 -  1/28/02 作者: flyfox]

最新喜欢:

chinabirdchinab...
一剑西来,天外飞仙
lu0
lu0
论坛版主
论坛版主
  • 注册日期2001-06-10
  • 最后登录2016-04-05
  • 粉丝2
  • 关注0
  • 积分-6311分
  • 威望21111点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-02-11 09:53
KERNEL MODE不支持TRY/CATCH. 请用TRY/EXCEPT. 只有TRY/EXCEPT在KERNEL MODE被NT OS和编译器支持.
Regards, Lu Lin Webmaster of Inside Programming http://www.lu0s1.com
tsu00
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2006-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-02-07 14:30
RuFeng,你也在这啊。你的ntice如何了?

关于try/catch你的问题应该可做如下解释。
当你访问一个非法地址,激活硬件中断后,nt kernel首先捕获到信息,然后调用nt!KeGetPreviousMode判断出错是否发生在内核模式,如果是的话,nt/2k/xp认为这是一个致命错误,不可能可以修复的,所以raise blue screen,也就不执行catch后的代码。用户模式下相反,nt认为可以修复,所以catch后的代码也就执行了。我只是描述了nt os seh。至于c++提供的seh,在microsoft vc中的实现也就转化成了os seh。其它c++编译器具体我就不知道如何了。

第二个问题可以使用kernel的section对象来处理。kernel32.dll的这些???代码,出现这样的情况有两种,一种是这些代码已经page out(至pagefile.sys),另外是memory map file还没有map view,仍在kernel32.dll中,没有装载过。在内核模式中你可以创建section对象,手动map。具于使用的内核例程,你参考gary nebbett的native api那本书。当然实现起来时,要判断这些内码当前是否是上面提及的两种情况或是不加判断所有代码都重新map,这些工作也就相应的转到os上面去了。


Welcome to [url]http://webcrazy.yeah.net[/url]!
RuFeng
驱动牛犊
驱动牛犊
  • 注册日期2001-03-28
  • 最后登录2006-06-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-02-07 13:06
我也同意tsu00的说法,这是一种Copy On Write现象,不知大家有没有留意过Windows内核的书呢?书中有一段话,这段话详细我已经不太记得了,但意思是这样的,在程序中,申请内存时,系统不会马上为你申请一块物理内存,而只会先做一个标记,当你下一次直的访问它时,系统才会帮你申请一块真正的内存空间,这样做的好处是显而易见的,如果申请了一块内存,你不使用,不是一种浪费了吗?这种做法在NT平台很普遍,这也正是大家所看到的现在,一付值页表就变化了,我想如果大家想现正一下也很方便,在付值前在int 0e入口处放个断点,不就可以看到这现象了吗?令有tsu00和lu0这等高手在,我也想问一下一年多困惑我的问题,一个在内核下面使用
try的问题,我试过在内核模式使用
try
{
在里面访问一个非法地址
}
catch
{
}
的语句,但发现还是蓝屏,没有商量,为什么?不是应跳到下面的
异常程序吗?
第二就是在NT中,对于应用级的Kernel32这类的dll,有一部分的
代码段在ice下看是????的,看页表也可以看到是没有分配到物理
内存的,在应用程序级执行或者读都可以叫系统把原来的代码load
入物理内存,就是可以见到真正的代码,但在内核模式怎么样做啊,
直接读取是一定不成了,有什么办法叫系统强制把这部分代码load
入当前的进程地址中呢?大家讨论一下好吗?
tsu00
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2006-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-02-07 09:42
 把inside windows 2000的书的mm部分看遍了也不能解释这个现象!:-(
  觉得tsu00的讲的比较贴近实际一些。
  各位对VAD的东西有研究么?
  看了那个问题后的第一个反应是lazy evaluation的,但是在执行完virtualprotect后已经存在了啊!想不清楚了.
  大家继续讨论啊!


  其实也不是不能解释这个现象了。我记得我曾用过jeffrey richter的vmmap试验过这个现象,我在我主页上的《探寻Windows NT/2000 Copy On Write机制》中提及过如下一段话:
  “1、cow.c使用#pragma comment(linker, \"/SECTION:.seg_cow,RWC\")显式的指出.cow_seg段的Copy On Write属性,实际上在Windows NT/2000中这种共享属性是默认存在的。可执行文件的映射、可读可写的数据都被默认设为Copy On Write属性,您可以使用Jeffrey Richter的VMMAP验证这种说法。”
  有兴趣的可以到我站上看看。


  至于vad,vad是一个自平衡二叉树结构的定义,softice的query指令,可以dump出这个结构。含有的信息可以使用query命令试试。

  应该重点指出的是Control Area的概念。query命令的output result的MMCI即指向control area(windbg中的ca命令,可dump出各个segment、subsection,该说的可是说不完的)

    vad的作用,当然是从系统性能考虑,总不至于任何页面的属性都直接查pde/pte吧,使用自平衡二叉树结构也是出于这目的的。
 


[编辑 -  2/7/02 作者: tsu00]

[编辑 -  2/7/02 作者: tsu00]
Welcome to [url]http://webcrazy.yeah.net[/url]!
sunsetyang
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2007-03-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-02-06 21:04
  把inside windows 2000的书的mm部分看遍了也不能解释这个现象!:-(
  觉得tsu00的讲的比较贴近实际一些。
  各位对VAD的东西有研究么?
  看了那个问题后的第一个反应是lazy evaluation的,但是在执行完virtualprotect后已经存在了啊!想不清楚了.
  大家继续讨论啊!
[color=red]Optimization[/color] In Progress . . . Welcome to http://mail.ustc.edu.cn/~chyang/
tsu00
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2006-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-02-06 15:49
lu0说明了Lazy evaluation。他提及的这种情况“访问页面前, PTE为空”,而此例中flyfox说在执行写操作pte就不为空,即page命令输出结果所示。我不知道flyfox指向的virtual_address是何性质的页面(如果他能说明可能会比较容易解释吧)。
这种情况我下面从前几年比较流行api hook来解释解释,不知道是不是flyfox所说的情况,而这就是比较典型的copy on write机制。比较懒,索性使用kdict(金山词霸)来说明吧。
测试环境:
    windows xp专业版build 2600
    softice 2.6 build 336
    kdict .net 2001 ver 5.00
kdict的CJKTL32.DLL负责修改gdi32.dll中的textouta api。其方法与flyfox提及的代码基本一致。
    virtualprotect后:
    :page textouta
    Linear     Physical   Attributes
    77C4E73E   04C2D73E   P   A U R
    将字节0x55(jmp)写入后:
    :page textouta
    Linear     Physical   Attributes
    77C4E73E   038CF73E   P D A U RW
    基本情况是这样的。我解释的可能不清楚,也可能flyfox说的情况不是这样的。
    lu0说的情况是这样的,可能此时页面未分配物理内存或是已经page out,这样pte才为0,这样触发中断后,才是他所描述的。
   关于详细的copy on write等机制的说明,可看我网站上的信息。
Welcome to [url]http://webcrazy.yeah.net[/url]!
lu0
lu0
论坛版主
论坛版主
  • 注册日期2001-06-10
  • 最后登录2016-04-05
  • 粉丝2
  • 关注0
  • 积分-6311分
  • 威望21111点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-02-05 17:27
在访问页面前, PTE为空. 访问时, PAGE FAULT. OS CORE检查EPROCESS中内存地址描述, 检查访问是否有效. 有效, 内存管理器将分配一个空闲页, 映射到用户空间. 访问继续. 否则, 将此项操作交给KERNEL MODE 的SEH处理. KERNEL MODE的SEH会将一切记录, 返回到USER MODE的SEH.
这是大致的思路. 实际实现很复杂.
Regards, Lu Lin Webmaster of Inside Programming http://www.lu0s1.com
tsu00
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2006-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-02-03 17:43
cr3值改变是在发生context switch时产生的。
从你的描述中,我做如下分析,有误之处大家讨论。

请看下面一个程序片断:
VirtualProtect(
(PVOID)virtual_address,
0x200,
PAGE_READWRITE,
&OldProtect
);
*(PUSHORT)virtual_address= \'zm\';

在执行了VirtualProtect之后我用sofice的page指令查看virtual_address所指向的虚地址,结果为
physical address = 03916000 attributes = P A U R

-----------你的描述中执行完VirtualProtect中页面属性仍为R,实际上系统此时此页面应该是可写的。但softice dump出来的页面(softice直接读pte)为只读,所以我做copy on write的猜测。因为copy on write使用HARDWARE_PTE_X86的bits9标识,如果你能将此页面的完整pte和pfn列出来,可能更容易解释。

在执行了*(PUSHORT)virtual_address= \'zm\';之后在用page查看virtual_address所指向的虚地址,结果为
physical address = 01CF6000 attributes = P D A U RW

------------执行完写操作后,页面此时物理地址发生变化,而pte也为RW了,所以我做copy on write的猜测。如果说是cr3发生改变,应该是不会的,我只能说是不是你前后在使用page命令时,当前context是否有变化,你使用page命令前,试一试使用softice的addr命令,将context切换至这个进程,看看结果,如果还是这种情况的话,你把前后pte的详细值与pfn列出来,大家讨论。


虚地址竟然在执行赋值语句的时候发生了切换。请问这在硬件(或者其它方面)是怎样实现的??

SOS!!!
Welcome to [url]http://webcrazy.yeah.net[/url]!
flyfox
驱动中牛
驱动中牛
  • 注册日期2001-04-05
  • 最后登录2012-08-03
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望22点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-02-01 20:59
我看CR3前后没有改变?
另外什么时候进行MOV CR3,XXX

VC和SOFTICE都看不见??????
我想如果要改变CR3,也应该先PUSH 后POP?
请LU0大侠解释详细点!
一剑西来,天外飞仙
lu0
lu0
论坛版主
论坛版主
  • 注册日期2001-06-10
  • 最后登录2016-04-05
  • 粉丝2
  • 关注0
  • 积分-6311分
  • 威望21111点
  • 贡献值0点
  • 好评度7点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-02-01 19:59
MOV CR3,XXX
Regards, Lu Lin Webmaster of Inside Programming http://www.lu0s1.com
flyfox
驱动中牛
驱动中牛
  • 注册日期2001-04-05
  • 最后登录2012-08-03
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望22点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-02-01 16:19
我认为可能不是Copy On Write的原因,因为Copy On Write主要是许多进程在共同使用一个DLL时,由于DLL仅装载一份,在处理DLL内部数据时触发的!
而本例,我自己分配了一段内存,要对它进行读写操作,应该不会触发Copy On Write吧,否则效率是否会有点低??
一剑西来,天外飞仙
tsu00
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2006-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-02-01 11:11
最大可能是Copy On Write机制的原因。kanghai大致将原理讲出来了。
Welcome to [url]http://webcrazy.yeah.net[/url]!
WindThruEars
驱动老牛
驱动老牛
  • 注册日期2002-11-17
  • 最后登录2004-07-10
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-01-31 11:23
I think that\'s possible, the page is clean before writting, system may share the same physical memory for different virtual address. But when you try to write to it, system has to break this kind of sharing and allocate new physical pages for you.

Just a guess.
我是假耳朵
游客

返回顶部