|
卡卡技术团队
- 帖子:8368
- 注册:
2006-01-09
- 来自:
|
发表于:
2009-09-14 11:54
|
只看楼主
短消息
资料
为何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
病毒样本请发到可疑文件交流区
|