能力值:
( LV12,RANK:300 )
|
-
-
10 楼
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中的内容会保持一致。
|