|
Modules, Processes, Threads(2)  IMTE 结构
WIN32WLK 原始码中的 MODULE32.H 内含一个 IMTE 结构定义。每一个 IMTE 有 以下字段: l 00h DWord un1 这个字段用来放置某种旗标值。 l 04h PIMAGE_NT_HEADERS pNTHdr 这个指针指向一个 IMAGE_NT_HEADERS 结构。然而,它只是该结构内容的一份拷贝。这份拷贝所用的空间是从 KERNEL32 heap 配置来的,所以对所有行程而言都是可见的。而主要的那个 IMAGE_NT_HEADERS 结构位于模块的基地址附近(可能在 2GB 之下),只能给「加载此一模块」之行程存取之。经由拷贝的动作,KERNEL32 就可以轻易地把任何被加载模块的信息让所有行程看见,不需要呼叫 ringCSC="0" NumberType="1" Negative="False" HasSpace="True" SourceValue="0" UnitName="码">0 码以切换 memorycontext。 l 08h DWORD un2 此字段的意义不清楚。其值似乎总是 -1。 l 0Ch PSTR pszFileName 内含一个指标,指向用以建立这个模块的 EXE 或 DLL 的完整檔名。你可以呼叫GetModuleFileName 获得此完整档名,更可以利用 GetModuleHandle 再将档名转换为handle。放置完整档名的区块是从 KERNEL32 heap 中配置来的。 l 10h PSTR pszModName 内含一个指针,指向模块名称。Win32 的模块名称就是 EXE 或 DLL 名称。例如,C:\WINDOWS\CALC.EXE 的模块名称就是 CALC.EXE。pszModName 事实上是指入前面所说的 pszFileName 之中。以前例而言,它将指向第二个 '\' 之后的 "CALC.EXE"。 l 14h WORD cbFileName 此值表示 pszFileName 所指之字符串的字符个数。GetModuleHandle 可以利用此一字段快速决定字符串是否吻合。 l 16h WORD cbModName 此值表示 pszModName 所指之字符串的字符个数。GetModuleHandle 可以利用此一字段快速决定字符串是否吻合。 l 18h DWORD un3 此字段的意义不清楚。 l 1Ch DWORD cSections 此一模块所含之 sections ( .text 、.idata 等等) 的个数。这个值也可以从IMAGE_FILE_HEADERS 结构(第8章)中的 NumberOfSections 字段获得。 l 20h DWORD un5 此字段的意义不清楚。其值总是 0,但是在 COMCTL32.DLL 中,它内含一个指标,指向 KERNEL32 heap 中的一块区域。 l 24h DWORD baseAddress/Module Handle 这个字段内含模块的基地址。在 Win32 中模块的基地址和 HMODULE 以及HINSTANCE 相同,所以此字段也可以被解释为模块的 HMODULE 和 HINSTANCE。EXE 的基地址几乎总是为 0x40000。system DLLs 的基地址在 2GB 之上,是共享记忆区。第8章对于基地址有更多叙述。 l 28h WORD hModule16 此字段内含一个 selector,其线性地址指向一个 Win16 NE module database(其格式在第7章详述)。对于 Win32 程序,NE module database 内含重要信息,包括在哪里可以找到资源等等。这是必要的,因为处理资源的程序代码位在 Win16 的KRNL386.EXE 和USER.EXE 中。请注意,hModule16 并非是以 Win16 的 GlobalAlloc 配置而得,所以这个 selector 并不像 Win16 的全域性内存 handle,因为这个因素和一些其它因素,Win16 TOOLHELP 没办法看到 Win32 模块所镜射的那个 NE 模块。 l 2Ah WORD cUsage 此字段内含模块的参用计数。如果有三个 CALC.EXE 正在执行,CALC.EXE 的moduledatabase 的此一字段即为 3。 l 2Ch DWORD un7 此字段的意义不清楚。通常它内含一个合法的指标,指向一块 KERNEL32 heap 区域。 l 30h PSTR pszFileName2 这个 PSTR(以及后续三个字段)有点神秘。它们似乎为那些「处理本结构之0Ch 至 16h 偏移位置」的相同函式服务。这个字段指向 EXE 或 DLL 完整檔名的一份不同拷贝。pszFileName 和 pszFileName2 所指的字符串似乎总是相同。 l 34h WORD cbFileName2 这个字段内含 pszFileName2 的长度。它总是和 cbFileName 字段相同。 l 36h DWORD pszModName2 这个字段指向 pszFileName2 之中的模块名称。它总是和 pszModName 相同。 l 3Ah WORD cbModName2 这个字段内含 pszModName2 的长度。它总是和 cbModName 字段相同。 MODREF 结构一个行程拥有它自己的模块串行,它对其它行程所加载的其它模块一无所知。把每个行程都有的模块串行和全域性模块表格连接在一起的就是 MODREF 结构。每个行程(除了奇怪的KERNEL32)都有的模块串行事实上是一个 MODREF 串行,其中一个 MODREF 是针对行程本身(也构成一个模块),其它 MODREFs 是针对行程所使用的每一个 Win32 DLLs。MODREFs 的内存来自 KERNEL32 heap,那是处于 2GB 之上 -- 可共享区域。因此,即使 MODREFs厉行「每一个行程有一个模块串行」的概念,MODREF 串行事实上是谁都看得到的。WIN32WLK 能够走访每一个行程的模块打印就足以证明这一点。 MODREFs 串行的头放在process database(稍后讨论)之中。每一个MODREFs 结构内含一个索引,指向 pModuleTableArray 表格。图3-2 显示MODREFs 和IMTEs 的关系。 
|