分享
 
 
 

《Undocumented Windows 2000 Secrets》翻译 --- 第四章(8)

王朝system·作者佚名  2006-11-24
窄屏简体版  字體: |||超大  

第四章 探索 Windows 2000 的内存管理机制

翻译: Kendiv( [url=http://www.pccode.net].net"fcczj@263.net )

更新: Tuesday, February 22, 2005

声明:转载请注明出处,并保证文章的完整性,本人保留译文的所有权利。

请求式分页动作

在讨论 Spy 设备的 SPY_IO_MEMORY_DATA 函数时,我提到过该函数可以读取已被置换到页面文件中的内存页。要证明这一点,首先,必须让系统处于低内存状态,以强迫它将不马上使用的数据置换到页面文件中。我喜欢采用的方法如下:

1. 使用 PrintKey ,将 Windows 2000 的桌面复制到剪切板中。

2. 将该图片粘贴到一个图形处理程序中。

3. 将该图片的尺寸放到最大。

现在,执行命令: w2k_mem +d #16 0xC02800000 0xA0000000 0xA0001000 0xA0002000 0xC0280000 ,察看它在屏幕上的输出。你可能会惊讶。在触及某些 PTE 所引用的页之前,它会获取这些 PTE 的快照。在地址 0xC0280000 处发现的四个 PTE 与地址范围: 0xA0000000---0xA0003FFF 相关,这是内核模块 win32k.sys 的一部分。如 示列 4-11 所示,该地址范围已经被置换出去了,因为在地址 0xC0280000 的四个 DWORD 都是偶数,这意味着它们的最低位(即 PTE 的 P 位)为零,这表示没有存在于物理内存中的页。接下来的三块 16 进制 Dump 信息属于 0xA0000000 、 0xA0001000 、 0xA0002000 , w2k_mem 可以毫无问题的访问这些页(系统会根据请求将它们再次换入内存)。

示列 4-11 观察 PTE 的状态变化

在开始下一节之前,请再次研究一下 示列 4-11 中的第一栏。位于地址 0xC0280000 的四个 PTE 看上去都很像。但事实上,它们仅有最低的三个位不同。如果你检查所有位于页面文件中的 PNPE ,你会发现它们的第 10 位都为 1 。这就是为什么我在 列表 4-3 中,将该位的名字取为 PageFile 。如果该位为 1 ,除 P 位外的所有位都将用来表示该页在页面文件中的位置。

更多的命令选项

示列 4-1 给出的某些命令选项还没有解释过。例如,系统状态选项: +o 、 +c 、 +g 、 +i 和 +b ,我会在本章的最后一节介绍它们,在那儿我们将发现几个 Windows 2000 内存系统的秘密。

Spy 设备的接口

现在你已经知道如何使用 w2k_mem 了,该是介绍它是如何工作的了。现在来看看这个程序是如何与 w2k_spy.sys 中的 Spy 设备通讯的。

回顾 ----- 设备 I/O 控制( Device I/O Control )

IOCTL 通讯的内核模式端已经由 列表 4-6 和 列表 4-7 给出了。 Spy 设备只是简单的等待 IRP 并处理其中的某些 IRP ,尤其是标识为 IPR_MJ_DEVICE_CONTROL ,其中的一些请求在用户模式下是被禁止的。调用 Win32 API 函数 DeviceIoControl() , 列表 4-27 给出了该函数的原型。可能你已经熟悉了 dwIocontrolCode 、 lpInBuffer 、 nInBufferSize 、 lpOutBuffer 、 nOutBufferSize 和 lpBytesReturned 参数。事实上,它们一一对应于: SpyDispatcher() 的 dCode 、 pInput 、 dInput 、 pOutput 、 dOutput 和 pdInfo 参数, SpyDispatcher 定义于 列表 4-7 。剩下的参数很快就会解释。 hDevice 是 Spy 设备的句柄, lpOverlapped (可选的)指向一个 OVERLAPPED 结构,异步 IOCTL 需要该结构。我们不需要发送异步请求,所以该参数总是 NULL 。

列表 4-28 列出了所有执行基本 IOCTL 操作的外包函数。最基本的一个是: IoControl() ,该函数调用 DeviceControl() 并测试返回的输出数据的大小。因为 w2k_mem.exe 精确的提供了输出缓冲区的大小,所以,输出的字节数应该总是等于缓冲区的大小。 ReadBinary() 是 IoControl() 的简单版本,它不需要输入数据。 ReadCpuInfo() 、 ReadSegment() 和 ReadPhysical() 专用于 Spy 函数 SPY_IO_CPU_INFO 、 SPY_IO_SEGEMNT 和 SPY_IO_PHYSICAL ,因为它们会经常被用到。将它们封装为 C 函数,可读性会更好些。

BOOL WINAPI DeviceIoControl( HANDLE hDevice,

DWORD dwIoControlCode,

PVOID lpInBuffer,

DWORD nInBufferSize,

PVOID lpOutBuffer,

DWORD nOutBufferSize,

PDWORD lpBytesReturned,

POVERLAPPED lpOverlapped);

列表 4-27. DeviceIoControl 函数的原型

BOOL WINAPI IoControl (HANDLE hDevice,

DWORD dCode,

PVOID pInput,

DWORD dInput,

PVOID pOutput,

DWORD dOutput)

{

DWORD dData = 0;

return DeviceIoControl (hDevice, dCode,

pInput, dInput,

pOutput, dOutput,

&dData, NULL)

&&

(dData == dOutput);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadBinary (HANDLE hDevice,

DWORD dCode,

PVOID pOutput,

DWORD dOutput)

{

return IoControl (hDevice, dCode, NULL, 0, pOutput, dOutput);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadCpuInfo (HANDLE hDevice,

PSPY_CPU_INFO psci)

{

return IoControl (hDevice, SPY_IO_CPU_INFO,

NULL, 0,

psci, SPY_CPU_INFO_);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadSegment (HANDLE hDevice,

DWORD dSelector,

PSPY_SEGMENT pss)

{

return IoControl (hDevice, SPY_IO_SEGMENT,

&dSelector, DWORD_,

pss, SPY_SEGMENT_);

}

// -----------------------------------------------------------------

BOOL WINAPI ReadPhysical (HANDLE hDevice,

PVOID pLinear,

PPHYSICAL_ADDRESS ppa)

{

return IoControl (hDevice, SPY_IO_PHYSICAL,

&pLinear, PVOID_,

ppa, PHYSICAL_ADDRESS_)

&&

(ppa->LowPart || ppa->HighPart);

}

列表 4-28 几个 IOCTL 的外包函数

到目前为止,本节列出的所有函数都需要 Spy 设备的一个句柄。现在,我将介绍如何获取该句柄。这实际上是一个非常简单的 Win32 操作,和打开文件类似。 列表 4-29 展示了 w2k_mem.exe 的命令处理例程的实现细节。该代码使用 API 函数 w2kFilePath() 、 w2kServiceLoad() 和 w2kServiceUnload() ,这几个函数由 w2k_lib.dll 导出。如果你已经读过第三章中关于 Windows 2000 服务控制管理器的介绍,你应该通过 列表 3-8 已了解了 w2kServiceLoad() 和 w2kServiceUnload() 。这些强大的函数可随时加载或卸载内核模式的设备驱动,并且能处理一些良性的错误,如,妥善的处理加载一个已经载入内存的驱动程序。 w2kFilePath() 是一个帮助函数。 w2k_mem.exe 调用它来获取 Spy 驱动程序的完整路径。

WORD awSpyFile [] = SW(DRV_FILENAME);

WORD awSpyDevice [] = SW(DRV_MODULE);

WORD awSpyDisplay [] = SW(DRV_NAME);

WORD awSpyPath [] = SW(DRV_PATH);

// -----------------------------------------------------------------

void WINAPI Execute (PPWORD ppwArguments,

DWORD dArguments)

{

SPY_VERSION_INFO svi;

DWORD dOptions, dRequest, dReceive;

WORD awPath [MAX_PATH] = L"?";

SC_HANDLE hControl = NULL;

HANDLE hDevice = INVALID_HANDLE_VALUE;

_printf (L"\r\nLoading \"%s\" (%s) ...\r\n",

awSpyDisplay, awSpyDevice);

if (w2kFilePath (NULL, awSpyFile, awPath, MAX_PATH))

{

_printf (L"Driver: \"%s\"\r\n",

awPath);

hControl = w2kServiceLoad (awSpyDevice, awSpyDisplay,

awPath, TRUE);

}

if (hControl != NULL)

{

_printf (L"Opening \"%s\" ...\r\n",

awSpyPath);

hDevice = CreateFile (awSpyPath, GENERIC_READ,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL, OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL, NULL);

}

else

{

_printf (L"Unable to load the spy device driver.\r\n");

}

if (hDevice != INVALID_HANDLE_VALUE)

{

if (ReadBinary (hDevice, SPY_IO_VERSION_INFO,

&svi, SPY_VERSION_INFO_))

{

_printf (L"\r\n%s V%lu.%02lu ready\r\n",

svi.awName,

svi.dVersion / 100, svi.dVersion % 100);

}

dOptions = COMMAND_OPTION_NONE;

dRequest = CommandParse (hDevice, ppwArguments, dArguments,

TRUE, &dOptions);

dOptions = COMMAND_OPTION_NONE;

dReceive = CommandParse (hDevice, ppwArguments, dArguments,

FALSE, &dOptions);

if (dRequest)

{

_printf (awSummary,

dRequest, (dRequest == 1 ? awByte : awBytes),

dReceive, (dReceive == 1 ? awByte : awBytes));

}

_printf (L"\r\nClosing the spy device ...\r\n");

CloseHandle (hDevice);

}

else

{

_printf (L"Unable to open the spy device.\r\n");

}

if ((hControl != NULL) && gfSpyUnload)

{

_printf (L"Unloading the spy device ...\r\n");

w2kServiceUnload (awSpyDevice, hControl);

}

return;

}

列表 4-29. 控制 Spy 设备

请注意 列表 4-29 顶部给出的四个全局字符串的定义。常量 DRV_FILENAME 、 DRV_MODULE 、 DRV_NAME 和 DRV_PATH 来自 Spy 驱动的头文件 w2k_spy.h 。 表 4-4 列出了它们的当前值。你不会在 w2k_mem.exe 的源代码中发现设备相关的定义, w2k_spy.h 提供了客户端程序所需的一切。这非常重要:如果以后改变了任何设备相关的定义,就不需要更新任何程序文件了。只需要以新的头文件编译、链接程序即可。

列表 4-29 顶部调用的 w2kFilePath() 可以保证由全局变量 awSpyFile (见 表 4-4 )指定的 w2k_spy.sys 总是从 w2k_mem.exe 所在目录中加载。接下来, 列表 4-29 中的代码将全局字符串 awSpyDevice 和 awSpyDisplay ()传递给 w2kServiceLoad() ,以加载 Spy 设备的驱动。如果驱动没有被加载,这些字符串将被保存在驱动的属性列表中,可以由其他程序取出;否则,将保留当前的属性设置。尽管 列表 4-29 中的 w2kServiceLoad() 调用可返回一个句柄,但这并不是一个可用于任何 IOCTL 函数的句柄。要获取 Spy 设备的句柄,必须使用 Win32 的多用途函数 CreateFile() 。该函数可打开或创建 Windows 2000 中几乎所有可被打开和创建的东西。如果提供了内核设备的符号链接名,形如 \.<SymbolicLink > 给 CreateFile() 的 lpFileName 参数,那么该函数就可打开这个内核设备。 Spy 设备的符号链接名是: w2k_spy ,因此, CreateFile() 的第一个参数必须是 \.w2k_spy ,这正是 表 4-4 中的 awSpyPath 的值。

表 4-4. 设备相关的字符串定义

w2k_spy 常量

w2k_mem 变量

DRV_FILENAME

awSpyFile

w2k_spy.sys

DRV_MODULE

awSpyDevice

w2k_spy

DRV_NAME

awSpyDisplay

SBS Windows 2000 Spy Device

DRV_PATH

awSpyPath

\\.\ w2k_spy

如果 CreateFile() 成功,它将返回一个设备的句柄,该句柄可传递给 DeviceIoControl() 。 列表 4-29 中的 Execute() 函数使

[1] [2] 下一页

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有