百度空间 | 百度首页 
 
查看文章
 
PsLoadedModuleList中系统内核文件的BaseDllName永远是ntoskrnl.exe?
2009-09-14 04:28

系统环境:XP sp3 简体中文版

源起http://bbs.pediy.com/showthread.php?p=686228
如果该帖楼主的问题是这样表述的:

“Intel或AMD的CPU情况下,系统内核文件应分别为ntoskrnl.exe和ntkrnlpa.exe,为什么我通过PsLoadedModuleList读取到的永远是ntoskrnl.exe?”

那么我可能很快就理解,然而楼主错误地把问题指向单核与双核的区别,说出了“内核文件名字ntkrnlmp.exe或者 ntoskrnl.exe”的话,结果我也就停留在告诉他“双核下内核文件名也不会叫ntkrnlmp.exe,虽然其源文件名是这个”。

之后自己动手试了一下才了解他问的问题的现象不是把双核内核文件显示成单核,而是系统把ntkrnlpa.exe的相应表项的BaseDllName也给显示成了ntoskrnl.exe。

lkd> dd PsLoadedModuleList
8055e720 855fc3b0 844dd2e0 00000000 00000000
8055e730 00000000 00000000 00000000 00000000
8055e740 80565bc0 80562de0 00000000 00000000
8055e750 00000000 00000000 00000000 00000000
8055e760 00000000 00000000 00000000 00000000
8055e770 00000000 00000000 8054b800 8054b000
8055e780 8054a200 80549000 8054d400 8054c000
8055e790 00000000 0000000c 0000000c 84e1db50
lkd> dt 855fc3b0 _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x855fc348 - 0x8055e720 ]
   +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x018 DllBase          : 0x804d8000
   +0x01c EntryPoint       : 0x806a2c08
   +0x020 SizeOfImage      : 0x20d000
   +0x024 FullDllName      : _UNICODE_STRING "\WINDOWS\system32\ntkrnlpa.exe"
   +0x02c BaseDllName      : _UNICODE_STRING "ntoskrnl.exe"
   +0x034 Flags            : 0xc004000
   +0x038 LoadCount        : 1
   +0x03a TlsIndex         : 0
   +0x03c HashLinks        : _LIST_ENTRY [ 0x0 - 0x1f3a86 ]
   +0x03c SectionPointer   : (null)
   +0x040 CheckSum         : 0x1f3a86
   +0x044 TimeDateStamp    : 0
   +0x044 LoadedImports    : (null)
   +0x048 EntryPointActivationContext : (null)
   +0x04c PatchInformation : 0x0074006e

事实俱在,用FullDllName就可以了。ZwQuerySystemInformation(SystemModuleInformation)也是用FullDllName的。

问题是这样解决了,然而我不死心,想知道为什么。于是只能一头扎进系统初始化的过程。

ntoskrnl.exe或ntkrnlpa.exe是在NTLDR!osloader.exe里加载的,相应LDR_DATA_TABLE_ENTRY也是在那里创建的,之后Windows内核初始化时再把BlLoaderBlock中的相应列表复制到PsLoadedModuleList中。

为了找到为什么相应LDR_DATA_TABLE_ENTRY中的BaseDllName永远是ntoskrnl.exe,我不得不去看看NTLDR!osloader.exe里是怎么创建它的。

NTLDR!osloader.exe里是在BlOsLoader函数中加载内核映像文件的。
BlOsLoader函数调用Blx86CheckForPaeKernel函数来判断应该加载哪个内核文件:

Blx86CheckForPaeKernel函数部分内容:
.text:00423B27                 mov     esi, offset s_Ntoskrnl_exe ; "ntoskrnl.exe"
.text:00423B2C                 mov     ebx, offset s_Ntkrnlpa_exe ; "ntkrnlpa.exe"
.text:00423B31                 jnz     short loc_423B3D
.text:00423B31
.text:00423B33                 cmp     byte ptr [ebp+PAEEnabled], 0
.text:00423B37                 mov     edi, ebx
.text:00423B39                 jnz     short loc_423B3D
.text:00423B39
.text:00423B3B                 mov     edi, esi
.text:00423B3B

调用BlLoadImageEx加载相应的内核文件。在此之后又加载了hal.dll和kdcom.dll

加载完这三个映像文件之后,就调用BlAllocateDataTableEntry函数为这三个文件创建LDR_DATA_TABLE_ENTRY表项。

对Windows内核文件创建LDR_DATA_TABLE_ENTRY表项的代码是这样的:

.text:004228E2                 lea     eax, [ebp+PNewDataEntry]
.text:004228E8                 push    eax             ; PNewDataEntry
.text:004228E9                 push    [ebp+DllBase]   ; DllBase
.text:004228EF                 lea     eax, [ebp+FullKernelName]
.text:004228F5                 push    eax             ; FullDllName
.text:004228F6                 push    offset s_Ntoskrnl_exe ; "ntoskrnl.exe"
.text:004228FB                 mov     _BlUsableLimit, 20000h
.text:00422905                 call    BlAllocateDataTableEntry(x,x,x,x)

该函数原型为

int __stdcall BlAllocateDataTableEntry(
        IN      char *BaseDllName,
        IN      char *FullDllName,
        IN      PVOID DllBase,
        OUT     PLDR_DATA_TABLE_ENTRY *PNewDataEntry)

其中第一参数指定的是填入LDR_DATA_TABLE_ENTRY 表项的BaseDllName.Buffer的字符串。

可以看到这里直接指定了BaseDllName为"ntoskrnl.exe",这就是导致这里永远是ntoskrnl.exe的原因。

BlAllocateDataTableEntry的反汇编分析结果如下,可以很清楚地看出它是怎么填充结构内容的。


.text:00415927
.text:00415927 ; int __stdcall BlAllocateDataTableEntry(char *BaseDllName,char *FullDllName,PVOID DllBase,int PNewDataEntry)
.text:00415927 __stdcall BlAllocateDataTableEntry(x, x, x, x) proc near
.text:00415927                                         ; CODE XREF: AEInitializeIo(x)+8Bp
.text:00415927                                         ; BlScanImportDescriptorTable(x,x,x)+1A0p
.text:00415927                                         ; BlLoadDeviceDriver(x,x,x,x,x)+176p
.text:00415927                                         ; BlOsLoader(x,x,x)+E1Fp
.text:00415927                                         ; BlOsLoader(x,x,x)+E52p
.text:00415927                                         ; BlOsLoader(x,x,x)+E8Ep
.text:00415927
.text:00415927 BaseDllName     = dword ptr 8
.text:00415927 FullDllName     = dword ptr 0Ch
.text:00415927 DllBase         = dword ptr 10h
.text:00415927 PNewDataEntry   = dword ptr 14h
.text:00415927
.text:00415927                 mov     edi, edi
.text:00415929                 push    ebp
.text:0041592A                 mov     ebp, esp
.text:0041592C                 push    esi
.text:0041592D                 push    4Ch
.text:0041592F                 call    BlAllocateHeap(x) ; Allocate buffer for LDR_DATA_TABLE_ENTRY structure
.text:0041592F
.text:00415934                 mov     esi, eax
.text:00415936                 test    esi, esi
.text:00415938                 jnz     short loc_415942
.text:00415938
.text:0041593A                 push    10h
.text:0041593C                 pop     eax
.text:0041593D                 jmp     loc_415A12
.text:0041593D
.text:00415942 ; ---------------------------------------------------------------------------
.text:00415942
.text:00415942 loc_415942:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+11j
.text:00415942                 push    ebx
.text:00415943                 push    edi
.text:00415944                 mov     edi, [ebp+DllBase]
.text:00415947                 push    edi             ; ImageBase
.text:00415948                 call    RtlImageNtHeader(x)
.text:00415948
.text:0041594D                 mov     ebx, [ebp+BaseDllName]
.text:00415950                 mov     [esi+LDR_DATA_TABLE_ENTRY.DllBase], edi
.text:00415953                 mov     ecx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage]
.text:00415956                 mov     [esi+LDR_DATA_TABLE_ENTRY.SizeOfImage], ecx
.text:00415959                 mov     ecx, [eax+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint]
.text:0041595C                 add     ecx, edi        ; DllBase+EntryPoint
.text:0041595E                 and     [esi+LDR_DATA_TABLE_ENTRY.HashLinks.Flink], 0
.text:00415962                 mov     [esi+LDR_DATA_TABLE_ENTRY.EntryPoint], ecx
.text:00415965                 mov     eax, [eax+IMAGE_NT_HEADERS.OptionalHeader.CheckSum]
.text:00415968                 mov     [esi+IMAGE_OPTIONAL_HEADER32.CheckSum], eax
.text:0041596B                 mov     eax, ebx        ; BaseDllName
.text:0041596D                 lea     edi, [eax+1]
.text:0041596D
.text:00415970
.text:00415970 loc_415970:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+4Ej
.text:00415970                 mov     cl, [eax]
.text:00415972                 inc     eax
.text:00415973                 test    cl, cl
.text:00415975                 jnz     short loc_415970
.text:00415975
.text:00415977                 sub     eax, edi        ; the length of the BaseDllName
.text:00415979                 lea     edi, [eax+eax]
.text:0041597C                 movzx   eax, di
.text:0041597F                 push    eax
.text:00415980                 call    BlAllocateHeap(x) ; AllocateBuffer for BaseDllName UNICODE_STRING
.text:00415980
.text:00415985                 test    eax, eax
.text:00415987                 jz      short loc_4159C7
.text:00415987
.text:00415989                 mov     [esi+LDR_DATA_TABLE_ENTRY.BaseDllName.Length], di
.text:0041598D                 mov     [esi+LDR_DATA_TABLE_ENTRY.BaseDllName.MaximumLength], di
.text:00415991                 mov     [esi+LDR_DATA_TABLE_ENTRY.BaseDllName.Buffer], eax
.text:00415994                 jmp     short loc_4159A0
.text:00415994
.text:00415996 ; ---------------------------------------------------------------------------
.text:00415996
.text:00415996 loc_415996:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+7Dj
.text:00415996                 movsx   cx, cl
.text:0041599A                 mov     [eax], cx       ; Copy BaseDllName into Buffer
.text:0041599D                 inc     eax
.text:0041599E                 inc     eax
.text:0041599F                 inc     ebx
.text:0041599F
.text:004159A0
.text:004159A0 loc_4159A0:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+6Dj
.text:004159A0                 mov     cl, [ebx]
.text:004159A2                 test    cl, cl
.text:004159A4                 jnz     short loc_415996
.text:004159A4
.text:004159A6                 mov     ebx, [ebp+FullDllName]
.text:004159A9                 mov     eax, ebx
.text:004159AB                 lea     edx, [eax+1]
.text:004159AB
.text:004159AE
.text:004159AE loc_4159AE:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+8Cj
.text:004159AE                 mov     cl, [eax]
.text:004159B0                 inc     eax
.text:004159B1                 test    cl, cl
.text:004159B3                 jnz     short loc_4159AE
.text:004159B3
.text:004159B5                 sub     eax, edx        ; get the length of FullDllName
.text:004159B7                 lea     edi, [eax+eax]
.text:004159BA                 movzx   eax, di
.text:004159BD                 push    eax
.text:004159BE                 call    BlAllocateHeap(x) ; Allocate Buffer for FullDllName UNICODE_STRING
.text:004159BE
.text:004159C3                 test    eax, eax
.text:004159C5                 jnz     short loc_4159CC
.text:004159C5
.text:004159C7
.text:004159C7 loc_4159C7:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+60j
.text:004159C7                 push    10h
.text:004159C9                 pop     eax
.text:004159CA                 jmp     short loc_415A10
.text:004159CA
.text:004159CC ; ---------------------------------------------------------------------------
.text:004159CC
.text:004159CC loc_4159CC:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+9Ej
.text:004159CC                 mov     [esi+LDR_DATA_TABLE_ENTRY.FullDllName.Length], di
.text:004159D0                 mov     [esi+LDR_DATA_TABLE_ENTRY.FullDllName.MaximumLength], di
.text:004159D4                 mov     [esi+LDR_DATA_TABLE_ENTRY.FullDllName.Buffer], eax
.text:004159D7                 jmp     short loc_4159E3
.text:004159D7
.text:004159D9 ; ---------------------------------------------------------------------------
.text:004159D9
.text:004159D9 loc_4159D9:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+C0j
.text:004159D9                 movsx   cx, cl
.text:004159DD                 mov     [eax], cx       ; Copy FullDllName into buffer
.text:004159E0                 inc     eax
.text:004159E1                 inc     eax
.text:004159E2                 inc     ebx
.text:004159E2
.text:004159E3
.text:004159E3 loc_4159E3:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+B0j
.text:004159E3                 mov     cl, [ebx]
.text:004159E5                 test    cl, cl
.text:004159E7                 jnz     short loc_4159D9
.text:004159E7
.text:004159E9                 mov     [esi+LDR_DATA_TABLE_ENTRY.Flags], 4000h
.text:004159F0                 mov     [esi+LDR_DATA_TABLE_ENTRY.LoadCount], 1
.text:004159F6                 mov     eax, _BlLoaderBlock
.text:004159FB                 lea     ecx, [eax+LOADER_PARAMETER_BLOCK.LoadOrderListHead.Blink]
.text:004159FE                 mov     edx, [ecx]
.text:00415A00                 mov     [esi+LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Flink], eax
.text:00415A02                 mov     eax, [ebp+PNewDataEntry]
.text:00415A05                 mov     [esi+LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Blink], edx
.text:00415A08                 mov     [edx+LDR_DATA_TABLE_ENTRY.InLoadOrderLinks.Flink], esi
.text:00415A0A                 mov     [ecx], esi
.text:00415A0C                 mov     [eax], esi
.text:00415A0E                 xor     eax, eax
.text:00415A0E
.text:00415A10
.text:00415A10 loc_415A10:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+A3j
.text:00415A10                 pop     edi
.text:00415A11                 pop     ebx
.text:00415A11
.text:00415A12
.text:00415A12 loc_415A12:                             ; CODE XREF: BlAllocateDataTableEntry(x,x,x,x)+16j
.text:00415A12                 pop     esi
.text:00415A13                 pop     ebp
.text:00415A14                 retn    10h
.text:00415A14
.text:00415A14 __stdcall BlAllocateDataTableEntry(x, x, x, x) endp

加载Boot驱动时BlLoadBootDriver->BlLoadDeviceDriver同样有调用BlAllocateDataTableEntry添加项目,但是这时的BaseDllName来自于对驱动注册表项的ImagePath键值取其中的文件名,因此与FullDllName中的内容会保持一致。


类别:默认分类 | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu