首页
社区
课程
招聘
[求助]获取内核文件名字 诡异错误
发表于: 2009-9-13 16:01 10594

[求助]获取内核文件名字 诡异错误

2009-9-13 16:01
10594
LIST_ENTRY *Entry = NULL;
	LDR_DATA_TABLE_ENTRY *DataTableEntry = NULL;
	NTSTATUS status=STATUS_SUCCESS;

	Entry = ((LIST_ENTRY*)DriverObject->DriverSection)->Flink;
	do
	{
		DataTableEntry = CONTAINING_RECORD(Entry,
			LDR_DATA_TABLE_ENTRY,
			InLoadOrderLinks);
		if (DataTableEntry->EntryPoint && 
			DataTableEntry->BaseDriverName.Buffer &&
			DataTableEntry->FullDriverName.Buffer && 
			DataTableEntry->LoadCount
			)
		{
			DbgPrint("内核模块名字%wZ",&DataTableEntry->BaseDriverName);
		//输出每一个内核模块的名字.往往第一个.也就是链表头.就是内核文件名字.ntkrnlmp.exe或者 ntoskrnl.exe等等..但是神奇了.这代码无论在双核下.还是单核下.都是输出ntoskrnl.exe..并且..测试输出的基地址.完全正确..唯独这个内核文件名字不正确..			

			
		}

		Entry = Entry->Flink;

	}
	while (Entry != ((LIST_ENTRY*)DriverObject->DriverSection)->Flink);


最后的疑问..

获取当前内核文件的名字....(只要名字.不需要路径..也不需要基地址.)...除了ZwQuerySystemInfoMation..还有没有其他的办法....遍历这个PsLoadMoudleList表发现在双核下部准确.......

谢谢...

[课程]Android-CTF解题方法汇总!

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
ZwQuerySystemInfoMation  后面好象也是遍历PsLoadMoudleList取的信息吧....
2009-9-13 19:57
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
3
Intel的CPU,双核情况下,系统安装时将ntkrnlmp.exe拷贝为ntoskrnl.exe,系统加载时加载这个(原来是ntkrnlmp.exe的)ntoskrnl.exe。
所以Intel双核情况下,内核文件名仍然是ntoskrnl.exe,但是其源文件名是ntkrnlmp.exe,如果加载符号,符号文件名也是ntkrnlmp.pdb。
因此单核双核下都叫ntoskrnl.exe是正确的。
2009-9-13 20:58
0
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
谢谢楼上大牛..

但是实际测试现象却并不乐观.

Intel 双核..他检测出来时 ntoskrnl.exe.如果按你的假设.nt**mp.exe已经变成了ntoskrnl.exe.

那么映射入共享内存的时候..错误..表现为.查找出来的一些函数地址等信息不对...(很明显的映射错了内核文件)..

AMD 双核 CPU平台测试的时候就比较严重了..直接提示这个文件错误(说明给出的文件名不对)..映射入内核的时候就映射不了.

//其实还想说一点..用其他的ARK工具检查内核模块.均显示为正确的名字.而非ntoskrn.exe...当然了.这点不能当做xxxx..所以只是说一下...

在单核心CPU下.上述问题均不存在..
2009-9-13 21:40
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
5
你是用什么文件来映射入共享内存?是用ntkrnlmp.exe映射入共享内存,然后与内核ntoskrnl.exe比较?
那实际上还是可能是不对的。
我的系统是XP SP3(原来是SP2后升级到SP3),AMD双核的。
我的情况是,system32文件夹下的:
ntoskrnl.exe和ntkrnlpa.exe,其版本信息中,版本均为5.1.2600.5755,源文件名分别为ntkrnlmp.exe和ntkrpamp.exe
ntkrnlmp.exe和ntkrpamp.exe,其版本信息中的版本仍然为5.1.2600.2180,也就是说这两个文件还是XP SP2版本的

也就是说微软的更新将SP2升级到SP3的时候,直接把ntoskrnl.exe和ntkrnlpa.exe文件给更新了(双核版本),但是却没有把ntkrnlmp.exe和ntkrpamp.exe更新(因为这两个文件本来就从来不会被加载)。

因此如果在我的系统下,把现有的ntkrnlmp.exe文件映射入内存与内核ntoskrnl.exe模块比较,当然函数会不一样,我不知道你的所谓出错是不是这个原因。

另外,我看过的ARK工具,显示内核模块时都是显示ntoskrnl.exe或ntkrnlpa.exe,ZwQuerySystemInformation的结果同样也是显示这两个文件名,我从来没有看过它们显示另外两个文件名(但是我说过了,因为在双核情况下这两个文件的源文件名其实是另外两个,所以加载pdb之后,pdb文件名就是另外两个)。
2009-9-13 22:13
0
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
嗯..我的思路是这样的...

首先.有一个算法..检查出系统装在什么分区.获取了这个.就很轻松知道了windows目录..

然后..还需要一个内核文件名与之配合..

所以.遍历PsLoadMoudleList表.第一项就是文件名..我用这个文件名.再配合前面的算法获得出来的路径..

最后组合成一个原始内核文件名字的全路径..

以这个路径打开内核文件.(这里假设是IoCreateFile)..然后映射入内存.(假设是 MmCreateSection..和MmMapViewOfSection等函数)..映射完毕,会返回一个基地址.我用这个基地址.开始搜索.办法就是遍历EAT...最后得出偏移..偏移+内核当前基地址(这个基地址.我用其他算法获取出来了.假设为内存暴搜)...这样就可以得出一个函数的当前真实地址了对不对..

但是.就在这个情况下...就会出现.我描述的情况..如果在Intel 双核..获取 出的地址是错的...

如果在AMD双核.更严重.直接提示文件就是错的.不能映射.

如果在单核机器(不管AMD还是Intel都完美运行)..

并且.在Intel双核和AMD双核上..用ARK工具查看内核文件.明明是 nt***mp.exe 或者nt***pa.exe..但是这个PsLoadMoudleList一直就是显示 ntoskrnl.exe..

所以就出现了最后的错误..

这就是我的整个环节..我仔细审查了每一个环节.就出在这个名字错误上了.

谢谢楼上大牛的耐心指导..不知道还有没有其他办法准确的获取内核文件名字.
2009-9-13 22:37
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
7
天哪,我终于明白你说什么了。

Windbg的Local Kernel Debug,载入后看到信息

Kernel base = 0x804d8000 PsLoadedModuleList = 0x8055e720

这里指出了PsLoadedModuleList的位置,于是:

lkd> dt 0x8055e720 _LDR_DATA_TABLE_ENTRY
nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0x855fc3b0 - 0x82f3e888 ]
   +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x018 DllBase          : (null)
   +0x01c EntryPoint       : (null)
   +0x020 SizeOfImage      : 0x80565bc0
   +0x024 FullDllName      : _UNICODE_STRING ""
   +0x02c BaseDllName      : _UNICODE_STRING ""
   +0x034 Flags            : 0
   +0x038 LoadCount        : 0
   +0x03a TlsIndex         : 0
   +0x03c HashLinks        : _LIST_ENTRY [ 0x0 - 0x0 ]
   +0x03c SectionPointer   : (null)
   +0x040 CheckSum         : 0
   +0x044 TimeDateStamp    : 0
   +0x044 LoadedImports    : (null)
   +0x048 EntryPointActivationContext : (null)
   +0x04c PatchInformation : (null)

这是个表头,接下来的一项:

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才是真正的文件路径,BaseDllName永远是ntoskrnl.exe。
2009-9-13 23:05
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
8
这个问题其实是“内核文件是某个文件,但是BaseDllName里永远显示ntoskrnl.exe”,但是你之前说了应该显示ntkrnlmp.exe等这个说法是有误的,我前面的回答其实是告诉你文件名不会是ntkrnlmp.exe
2009-9-13 23:10
0
雪    币: 7992
活跃值: (2566)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
我晕....看来我对那个理解不够深入..

我以为那个全路径.是前面的路径..

而我只需要名字即可..哎...

晕倒....非常感谢楼上大牛..
2009-9-13 23:18
0
雪    币: 722
活跃值: (123)
能力值: ( 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中的内容会保持一致。
2009-9-14 04:09
0
雪    币: 522
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
11
强  
一直用 ZwQuerySystemInfoMation取路径
没发现还有这个机关
2009-9-14 15:00
0
雪    币: 326
活跃值: (41)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
占座学习之。。。
2009-9-15 09:53
0
游客
登录 | 注册 方可回帖
返回
//