瑞星卡卡安全论坛技术交流区反病毒/反流氓软件论坛安全技术讨论 为何PsLoadedModuleList中系统内核文件的BaseDllName永远是ntoskrnl.exe

1   1  /  1  页   跳转

为何PsLoadedModuleList中系统内核文件的BaseDllName永远是ntoskrnl.exe

为何PsLoadedModuleList中系统内核文件的BaseDllName永远是ntoskrnl.exe

系统环境: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中的内容会保持一致。


用户系统信息:Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727; aff-kingsoft-ciba; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; MAXTHON 2.0)
最后编辑轩辕小聪 最后编辑于 2009-09-18 19:39:25
病毒样本请发到可疑文件交流区
分享到:
gototop
 

回复:为何PsLoadedModuleList中系统内核文件的BaseDllName永远是ntoskrnl...

拜读
gototop
 
1   1  /  1  页   跳转
页面顶部
Powered by Discuz!NT