Rinrin 的个人资料永远的羁绊照片日志列表更多 ![]() | 帮助 |
|
|
2月24日 自己搞的一段补丁代码,先记下来备用pushad | 60 pushfd | 9C mov eax, _BlLoaderBlock | A1 __ __ __ __ push offset "/detecthal" | 68 __ __ __ __ push dword ptr [eax+44h] | FF 70 44 call _strstr | E8 __ __ __ __ test eax,eax | 85 C0 pop ecx | 59 pop ecx | 59 jz (popfd) | 74 __ call SlDetectHal | E8 __ __ __ __ mov edi,eax | 8B F8 or ecx,FFFFFFFF | 83 C9 FF xor eax,eax | 33 C0 cld | FC repne scasb | F2 AE not eax | F7 D1 sub edi,ecx | 2B F9 mov esi,edi | 8B F7 mov edi,_HalFileName | BF __ __ __ __ mov eax,ecx | 8B C1 shr ecx,2 | C1 E9 02 rep movsd | F3 A5 mov ecx,eax | 8B C8 and ecx,3 | 83 E1 03 rep movsb | F3 A4 popfd | 9D popad | 61 mov eax,_BlLoaderBlock | A1 __ __ __ __ jmp back | E9 __ __ __ __ 7月15日 启用Windows Boot DebuggerWinDDK中附带了一个ntldr_dbg,可以在Boot时启用调试器。我一直很好奇,普通的ntldr中也有Boot Debugger字样,为啥就不行。
休息天逆向了一下ntldr相关部分,发现了一点小秘密。其实普通的ntldr是支持Boot Debugger的,需要在boot.ini里设置一下。例如:
[debug]
/debug debugport com1 baudrate=19200 debugstop 我使用2003 sp2版本的ntldr测试成功
过程就不说了,只说有意思的部分。ntldr中有些字符串支持函数,解析boot.ini需要调用它们,我没有看这些函数,不太清楚它们会不会有问题。。。如果有,那可能搞出一个新的bootkit出来,或者是一个本地权限提升
但是,普通版本的ntldr有些支持函数丢失了,是一个nullstub,我看了一下ntldr_dbg,其中是有内容的。这就导致了普通版本的ntldr不能加载符号文件。。。期待牛人写一个补丁吧,呵呵。 11月4日 BOOTFONT.BIN文件格式作者:Rinrin
初始版本:2006.11.4 BOOTFONT.BIN是NTLDR和SETUPLDR.BIN使用的字体文件,它提供了Windows系统启动阶段其他语言(非英语)的字体点阵。本文针对的BOOTFONT.BIN为中文版本Windows XP With SP2所附带(Windows 2000/XP/2003使用的字库文件完全相同),其他语言的应该类似。
用Ultraedit-32打开BOOTFONT.BIN,可以发现头四个字节为"MdeT",为什么要用这么奇怪的魔数呢?答案在泄漏的windows nt4源代码中。在bootfont.h中对这个魔数进行了定义: +------------------------------------------+ | // Define signature value. | | // | | #define BOOTFONTBIN_SIGNATURE 0x5465644d | +------------------------------------------+ 0x5465644d即为"TedM",Windows最开始的本地化版本是日文版,因此由日本的开发人员做了最初的本地化工作,可以从ntos\boot\bootfont\readme.txt中看出来: +-----------------------------------------------------------------------+ | The jpn directory contains the original fntjapan.h that was once | | compiled into the x86 boot loaders, and a program I wrote to generate | | bootfont.bin for Japan from it. | | | | - tedm, 7/11/95, Tokyo | +-----------------------------------------------------------------------+ 0x04-0x07为语言代码,对于中文则为0x804。 0x08-0x0b为BOOTFONT.BIN支持的单字节字符个数(NumSbcsChars)。 0x0c-0x0f为BOOTFONT.BIN支持的双字节字符个数(NumDbcsChars)。 0x10-0x13为单字节字符点阵在文件中的偏移(SbcsOffset)。 0x14-0x17为双字节字符点阵在文件中的偏移(DbcsOffset)。 0x18-0x1b为所有单字节字符点阵数据的总长度(SbcsEntriesTotalSize)。 0x1c-0x1f为所有双字节字符点阵数据的总长度(DbcsEntriesTotalSize)。 0x20-0x2b为一个数组,存放了DBCS的前导字节范围,最后以"\0\0"结尾,MAX_DBCS_RANGE的值当前为5(DbcsLeadTable[(MAX_DBCS_RANGE+1)*2])。 0x2c表示字符的高度(CharacterImageHeight)。 0x2d表示字符的TopPad(CharacterTopPad)。 0x2e表示字符的BottomPad(CharacterBottomPad)。 0x2f表示单字节字符的宽度(CharacterImageSbcsWidth)。 0x30表示双字节字符的宽度(CharacterImageDbcsWidth)。 以上为BOOTFONT.BIN的头部,一般来说,接下来就是单字节字符的点阵了。根据头部SbcsOffset的值,找到点阵的开始位置。每一个单字节字符需要19个字节,第一个字节为ASCII码,之后的16个字节即是点阵数据(根据字符的大小8x16,16个字节正好放下),最后两个字节为该字符的Unicode(小端)编码;对于双字节字符点阵,每个字符需要36个字节,头两个字节为GB2312编码,之后32个字节为点阵数据,最后两个字节为该字符的Unicode(小端)编码。
参考文献:
The leaked windows nt4 source code -=[End Of File]=- 10月15日 NTLDR Reverse EngineeringNTLDR Reverse Engineering翻译:Rinrin
ntldr分为两部分,一个16位flat模式的二进制文件(类似于一个.COM文件)和一个32位的PE文件,它们担负了大部分装载任务。我发现可以用一种简单的办法来把ntldr分开,从而用IDA分别研究这两部分。我们可以使用一个16进制编辑器,在ntldr中搜索"MZ"或者"PE"这两个特征字符串,从"MZ"开始到文件结束作为一个文件。我把它命名为osloader.exe,因为这个文件的信息头里指出它的原始文件名就是osloader.exe。 通常情况下,你可以忽略那些16进制代码。基本上它的作用就是为32位的osloader.exe设置执行环境,并且实现了一些保护模式下的调用(实际上是对实模式BIOS接口的包装)。因为这时候还没有任何驱动,osloader.exe就用这些功能来实现它的I/O操作。设置GDT和IDT的操作也在这些代码里。。。嗯,以后有时间我可能会去看一看这些代码的。 上面提到的I/O函数在osloader.exe里是通过一个指针数组来访问的。AndreaGeddon在他的文章(Understanding Win2k Sources - Part 1 by AndreaGeddon)里提到这个指针在BootContextRecord的第二个双字处了解这些函数的定义对逆向osloader.exe很有好处,根据我收集的资料,这个函数表不完全的定义如下: typedef struct _IO_FUNCTIONS 就如你所看到的,我只是给出了它们的名字来表明它们的用处,并没有研究它们的参数和实际的功能。 .text:0040125C DoGlobalInitialization proc near ; CODE XREF: NtProcessStartup+1E 上面的代码中,对于pIoFunctions->VideoServices的调用是通过寄存器间接寻址完成的,寄存器的值被传给全局指针pIoFunctions,你应该能轻松看出这些的。 现在所有对于pIoFunctions的交叉引用,都加上IO_FUNCTIONS的偏移定义。例如下面的代码: .text:0040757D InitArcFirmwareVectors proc near ; CODE XREF: NtProcessStartup+24 根据上面的汇编代码片断你应该能自己推断出ArcFirmwareVectors结构体的成员。在IDA里定义如下结构体: 00000000 ARC_FIRMWARE_VECTORS struc; (sizeof=0x94) 然后用这个定义创建ArcFirmwareVectors结构体,下面是我的: .data:00468340 ArcFirmwareVectors ARC_FIRMWARE_VECTORS <?> 如果你观察ArcFirmwareVectors的交叉引用会发现有一个全局指针指向它,我把它叫做pArcFirmwareVectors。下面是我的: .data:00436070 pArcFirmwareVectors dd offset ArcFirmwareVectors 就像我们对pIoFunctions指针做的那样,我们查看所有对pArcFirmwareVectors指针的引用,加上ARC_FIRMWARE_VECTORS的偏移定义,下面是例子: .text:0041D07F mov eax, pArcFirmwareVectors 变成了: .text:0041D07F mov eax, pArcFirmwareVectors ARC规范描述了所有的函数,据我所知,osloader.exe中的实现是遵循ARC规范的。 我刚刚才知道ddk中的ntldr_dbg是调试版本,那么它的代码里应该有很多调试信息,我以后将用它的反汇编作为对原始ntldr反汇编的参考。 |
|
|