Rinrin 的个人资料永远的羁绊照片日志列表更多 工具 帮助

日志


2月5日

Dirac 基于小波变换的编码

本人当一回白鼠。
 
1. rawvideo转换
mencoder stream.xxx -of rawvideo -o test.yuv -ovc raw -vf format=i420
 
2. rawvideo播放
mplayer -demuxer rawvideo -rawvideo w=640:h=480:format=i420 test.yuv
 
3. dirac编码
EncodeDirac.exe -cformat YUV420P -fr 30 -width 640 -height 480 -mv_prec 1/8 -qf 7 test.yuv test.drc
 
用它的Decoder播放起来忒耗CPU,明天测试其他参数。
11月30日

Some tricks used in XP embedded for USBKey boot

1. USB version of ntdetect
Yet another ntdetect made by Microsoft, it is promoted for USB mass-storage device discovering, maybe it uses INT13H extension for recognizing USB storage. so NTLDR can save disk information in its LoaderBlock which will be transfer to OS kernel later.
 
2. CriticalDeviceDatabase & "boot" start type USB driver
Microsoft changed USB driver to "boot" start type to make sure USB stack to be initialized before kernel try to mark boot partition.
another important change is registry trick in CriticalDeviceDatabase. USB driver will create device objects when PNP manager find the compatible ID of the device matches to registry key in CriticalDeviceDatabase branch.
 
3. special version of usbhub.sys
a new version of usbhub.sys was add to XP Embedded Repository. unlike normal version of usbhub.sys, this driver can enumerate USB devices which attached to USB HUB at boot initialize time. so a USB Key insert to USB HUB could also boot up.
 
hope this will be clear.
enjoy it.
11月26日

如何停用程序兼容引擎

Windows Registry Editor Version 5.00
 
[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\windows\AppCompat]
"Disableengine"=dword:00000001
 
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\AppCompatibility]
"DisableAppCompat"=dword:00000000
 
10月19日

已知驱动服务名,修改网络连接名称

set DRV_NAME=tap0901
set NET_NAME=tap
for /f "tokens=3" %%i in ('reg query HKLM\System\CurrentControlSet\Services\%DRV_NAME%\Enum /v 0 ^| findstr REG_SZ') do set NET_ENUM=%%i
for /f "tokens=3" %%i in ('reg query HKLM\System\CurrentControlSet\Enum\%NET_ENUM% /v Driver ^| findstr REG_SZ') do set DRV_CLSID=%%i
for /f "tokens=3" %%i in ('reg query HKLM\System\CurrentControlSet\Control\Class\%DRV_CLSID% /v NetCfgInstanceId ^| findstr REG_SZ') do set CFG_CLSID=%%i
reg add HKLM\System\CurrentControlSet\Control\Network\{4D36E972-E325-11CE-BFC1-08002BE10318}\%CFG_CLSID%\Connection /v Name /d %NET_NAME% /f
7月25日

The (New) PSP Technical Docs

Author: SilverSpring
E-mail: silverspringpsp [at] gmail [dot] com
 
翻译: Rinrin
 
2. 介绍
当PSP处于完全关断状态时,只有SYSCON芯片是通电运行的,SYSCON控制绝大部分PSP硬件。包括外接电源接口及电池。
给SYSCON提供电源的是主板上的纽扣电池,所以即使PSP电池没有接入SYSCON仍在运行。
SYSCON会监控电源开关,当你打开电源开关时,SYSCON会控制硬件向主CPU上电。
主CPU是索尼定制的MIPS32核并且内嵌一块4KB掩膜ROM(像大多数嵌入式系统那样)。
ROM中储存"preipl"(它可以将PSP启动至工厂模式、加载和解密nand或记忆棒中的IPL)。
这块ROM被映射到物理地址0x1FC00000处(MIPS处理器的复位中断向量),这是CPU冷启动之后执行第一条指令的地址。
3. Pre-IPL启动顺序
3.1. Pre-IPL第一部分(加载器)
Pre-IPL分成两个部分:加载器和主体
因为preipl存储在非挥发只读内存中,所以程序中不能使用变量。
这样,第一部分的preipl(加载器)会将第二部分的preipl(主体)复制到CPU的暂存RAM中(启动时可用的RAM之一,另外还有一块4KB的RAM,2MB EDRAM和主内存DDR SDRAM这时并没有初始化)
暂存RAM映射到物理地址0x00010000处,当第一部分的preipl结束复制后,就跳转到新地址0x00010000。

3.2. Pre-IPL第二部分(主体)
现在CPU在暂存RAM中执行(即preipl主体),preipl主体初始化闪存并读入闪存块表(包含了已加密的IPL存放的块号)。
这张表起始于闪存中第四个块(即偏移0x10000),并且之后的七个块都是它的镜像。这就是为什么即时这些块中出现坏块,闪存块表仍然能被读取。不过如果8个块都损坏了,preipl无法找到IPL,PSP也就变砖了(唯一的解决方法是从记忆棒启动
或使用定制的IPL修补preipl使得它重定位这张表,这两种办法都需要潘多拉)。
闪存上的所有IPL块是加密的,preipl主体使用4KB的RAM(这个RAM映射到物理地址0x1FD00000处,但之后就会映射到0x1FC00000,作为媒体处理器的复位中断向量)作为加载和解密IPL块的临时存储,因为这块RAM只有4KB大小,所以加密的IPL块以4KB大小组织存放在闪存上。
preipl完成一块IPL的解密后,就将其加载到物理地址0x040F0000处并累积追加,这个物理地址位于2MB EDRAM(本来被用作显存)中,主内存DDR SDRAM这时还是没有被初始化。当preipl完成所有IPL块的解密和加载后就跳转到新地址。
------------------------------------------------------------------------
4. IPL启动顺序
解密后的IPL分为三部分:
第一部分  加载器
第二部分  main.bin
第三部分  主体
第一部分是一段MIPS代码,第二部分使用gzip压缩,第三部分是加密的(从2.60版本开始,第二部分和第三部分都被加密了)。
4.1. IPL第一部分(加载器)
加载器做的第一件事就是重置主CPU,重置后内嵌的掩膜ROM就不再映射到内存区域(0x1FC00000被重新映射到上面提到的RAM)。
这就是为什么IPL启动后preipl就不可访问了,加载器执行一些非常基本的硬件初始化并将第二部分main.bin解压缩到0x04000000(仍然是EDRAM)。随后加载器跳转到这个地址开始初始化硬件。
4.2. IPL第二部分(main.bin)
main.bin负责初始化PSP硬件,它有自己的驱动模块(类似于固件中的驱动模块,包括sceNAND_Driver,sceDDR_Driver, sceIdStorage_Service,sceSYSREG_Driver,sceSYSCON_Driver,sceGPIO_Driver,sceClockgen_Driver,sceI2C_Driver等等)
有些初始化依赖idstorage key(例如key 4,5,6),这就是1.50核心刷到TA082/086主板的PSP上变砖的原因:
一部分是因为TA082/086主板改变了时钟硬件,1.50核心不能识别它;另一部分是因为某些初始化步骤依赖key 5,当破坏key 5时,初始化就会终止,固件不会继续运行。
硬件初始化(包括主内存DDR SDRAM)完成后,main.bin就将IPL第三部分(主体)加载到物理地址0x08400000(这是DDR SDRAM)处并跳转到新地址启动系统。
5月19日

如何制作Simsun.pcf

如何制作Simsun.pcf
作者:Rinrin

    Requirements:
    Simsun.ttc
    Fontforge
    sed/Ultraedit
    X Utils[bdftopcf]

    Simsun.ttc是个Fontpack,其中有宋体和新宋体两种字体。
    Fontforge可以直接打开Simsun.ttc。当然,若你看着不爽,可以用Font Creator拆成两个ttf再处理。
    打开时会提示你这个字体含有内嵌点阵,并列出12/14/16三种,我只打算制作16x16的pcf,所以只选择了16。
    字体打开后,默认显示的是矢量字体,手动选择“查看”->"位图字体",可以看到TTF中内嵌的点阵。
    现在需要保存为bdf,选择 "文件"->"生成字体",设置格式为"无轮廓字体"和"BDF格式"即可生成。
    生成的bdf为2.2版本的格式,X Server只认2.1的,晕!
   
    研究了bdf格式,它是个文本文件。2.2增加了global SWIDTH/DWIDTH,而2.1不支持。这样就简单了。
    删掉STARTPROPERTIES之前的参量,类似这样:
    METRICSSET 2
    SWIDTH 1000 0
    DWIDTH 16 0
    SWIDTH1 1000 0
    DWIDTH1 16 0
    VVECTOR 8,13
    然后需要在每个字符描述块中加入:
    SWIDTH 1000 0
    DWIDTH 16 0
    两万多个字符,一个一个加不得累死!用sed/Ultraedit帮我们做吧:
    搜索:^ENCODING(.*)(\r\n)$
    替换为:ENCODING\1\2SWIDTH 1000 0\2DWIDTH 16 0\2
   
    OK了!本来这样就结束了,但bdf是文本,浪费很多空间。用bdftopcf转一下吧:
    bdftopcf Simsun.bdf > Simsun.pcf
    转换后的大小为1.9M左右,其实可以用bdftruncate删掉一部分字符再转换。

=End Of File=
Enjoy it.
=End Of File=

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 __ __ __ __
2月7日

Enable XP style UI in Windows Server 2003

第一步:破解msgina.dll
简单讲一下调用流程。Winlogon加载默认gina(即msgina.dll),创建服务进程和一些线程后然后进入MainLoop()。
MainLoop()中调用ShellStatusHostBegin(),接下来
ShellStatusHostBegin->Shell_LogonStatus_Init->CSystemSettings::IsFriendlyUIActive->CSystemSettings::IsWorkStationProduct
只需要修改CSystemSettings::IsWorkStationProduct()返回非负即可。
第二步:添加/修改注册表项
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
LogonType reg_dword:1
UIHost reg_sz:(改成你喜欢的ui)
 
enjoy it.
10月27日

Windows网络安装简介

作者:Rinrin
    顾名思义,Windows网络安装表示从局域网内部引导Windows安装,核心技术基于微软的RIS(Remote Installation Services)。RIS有一个缺点,即需要在域环境下才能配置运行RIS。不过这个限制已经被国外的高手破解了,现在可以从任何一台Windows(甚至是Linux)机器上配置网络安装所需要的服务。本文将简单说明实现Windows网络安装的技术要点。
    实现Windows网络安装需要四个服务:BOOTP,TFTP,BINL,Windows Share. 其中BOOTP和TFTP是实现PXE启动的基础,关于PXE启动的详细信息,可以参考本文后的引用2。
    BINL服务,微软称之为启动信息协商层(Boot Information Negotiation Layer),其作用是网卡查询、身份验证、启动镜像选择等功能。实现Windows网络安装只需要其中一项功能,即网卡查询。Sherpya逆向分析了BINL协议,并写了一个开源的Binl服务程序。要了解详细信息,可以参考本文后的引用1。
    Windows共享服务提供了安装文件的来源,并且在文本模式安装阶段作为启动分区(Boot Partition),因此也是必不可少的。
    Windows网络安装的大致步骤如下:
    1. 目标计算机从网卡PXE Boot ROM启动(当然,你也可以用PXELinux或PXEGrub来实现类似的启动功能)。
    2. 目标计算机从DHCP/BOOTP服务器获得网络地址,并获得TFTP服务器的IP地址和启动文件信息。
    3. 目标计算机向TFTP服务器获得启动文件startrom.com/startrom.n12
    4. startrom.com获取ntldr(由setupldr.exe改名而来),并将控制权传递给它。
    5. setupldr.exe获取ntdetect.com和winnt.sif,winnt.sif应该包含启动相关信息。
    从这个时候起,有两种启动方法,即ramdisk和网络启动,对于Ramdisk,启动分区为\Device\Ramdisk{xxxx...},你可以参考本文后的引用2。对于网络启动,你需要在winnt.sif中设定SetupSourceDevice参数。
    6. setupldr.exe通过ntdetect.com获得网卡的Vendor ID和Device ID, 并将它发送到Binl服务端口(4011)。
    7. Binl服务查找“数据库”,获得需要加载的驱动名称和服务名,返回给setupldr.exe
    8. Setupldr.exe按照正常顺序加载驱动,不过在最后,它会试着去加载前面给出网卡驱动和网络设备相关驱动,你可以从TFTP服务器的log里看到这些。有意思的是,txtsetup.sif并没有网络设备相关驱动的信息,我想可能是直接写在setupldr.exe里了。
    9. 控制权移交给kernel,kernel会试着去mount启动分区,要注意的是,你建好的共享必须提供匿名访问,否则会停住不动。
    10. 开始文本模式安装,setupdd复制文件到硬盘。完成后重新启动。
    11. 开始GUI阶段安装,要注意的是,之前应该在Winnt.sif中指定OriSrc和OriTyp,至于是不是必须的,我不好说,因为并没有试验过。
    12. 安装结束。实际上,你可以在winnt.sif中加入相关信息,以便实现无人值守安装。
    接下来,看一个实际的例子:
    1. 准备好DHCP/TFTP服务器,可以用tftpd32,也可以用性能较好的haneWin,看你的选择了。
    2. 设定好DHCP/TFTP服务器,指定TFTP根目录和启动文件名(startrom.n12或其他)。
    3. TFTP目录结构如下:
        TFTP
        │  ntdetect.com
        │  ntldr
        │  startrom.n12
        │  winnt.sif
        │
        └─boot
            └─I386
        其中ntldr由setupldr.exe改名而来,I386目录可以直接从安装光盘中复制。
    4. winnt.sif内容如下:
        [Data]
        floppyless = "1"
        msdosinitiated = "1"
        OriSrc = "\\Angel\TFTP\boot\i386"
        OriTyp = "4"
        LocalSourceOnCD = 1
        DisableAdminAccountOnDomainJoin = 1
       
        [SetupData]
        OsLoadOptions = "/fastdetect"
        SetupSourceDevice = "\Device\LanmanRedirector\Angel\TFTP\boot"
       
        [UserData]
        ComputerName = *
    Angel为当前计算机主机名,TFTP为共享名。
    5. 编译Binl服务程序binlsrv.c,可以在本文后的引用1找到。如果你装了VC,可以用cl binlsrv.c ws2_32.lib来编译。
    6. 编写文件nics.txt,和binlsrv.exe放在同一目录下:
        1022 2000 vmxnet.sys vmxnet
        1186 1300 RTL8139.sys rtl8139
    从左到右分别为PCI Vendor ID, Device ID, 驱动名, 服务名
    7. 把网卡驱动(如vmxnet.sys,RTL8139.sys)放到TFTP\boot\I386目录下
    8. 将TFTP目录共享,注意匿名访问。如何设置就不说了,网络上有很多文章,重点是启用Guest、允许网络访问、允许空会话、NTFS权限等等,完了别忘了重启一下Server服务。
    9. 启动目标计算机,开始网络安装!
    后记:
    Windows网络安装并不复杂,国外的高手几年前就开始研究了。希望大家能多到Boot land, 911CD这样的论坛逛一逛,开阔眼界吧。
    引用:
    1. Sherpya. RIS for Linux, http://oss.netfarm.it/guides/
    2. Climbing. PXE服务器架设指南及PXE启动WinPE(含PE2.0)解决方案总结, http://www.znpc.net/bbs/viewthread.php?tid=3662&extra=page%3D1
8月10日

MSYS/MinGW from Scratch(未完成,更新中)

准备编译环境
安装MSYS,msysDTK,msysDVLPR,MinGW
建一个目录,存放我们的工具链
export $MFS=/d/mmfs
mkdir -p $MFS

关于msys:
msys(Minimal SYStem)是Cygwin的改版,针对Win32做了优化和修改,最突出的一点是根目录"/"和"/bin"根据msys-1.0.dll的位置自动mount,其他mount选项放到/etc/fstab中而不是注册表中(这表明/etc不能被mount?)。

关于target的说明:
target指示目标编译器产生的可执行文件所运行的平台,新版本的config,guess已经不支持i*86-pc-msys平台了,所以我们只能用i*86-pc-cygwin代替。

编译binutils(第一遍)
mkdir build && cd build
../configure --prefix=$MFS --disable-nls --disable-shared --disable-multilib --host=mingw32 --build=mingw32 --target=i686-pc-cygwin --with-sysroot=$MFS
编辑Makefile,MAKEINFO = makeinfo
binutils编译时仍然需要配置,检查宿主环境是否可以编译自己,这里预先进行配置,防止编译到一半出错浪费时间
make configure-host && make && make install
因为ld链接脚本搜索目录不正确,所以重新生成
make -C ld clean
make -C ld LIB_PATH=$MFS/lib
make -C ld install
最后,看一下$MFS/i686-pc-cygwin/lib/ldscripts/i386pe.*
确认库的搜索范围

编译w32api(第一遍)
./configure --prefix=$MFS
make
make install

编译MSYS-runtime(第一遍)
MSYS-runtime是不能用MinGW的gcc编译的,所以要使用官方提供的msysDVLPR
/msys/bin/msysdvlpr会打开一个新窗口
export PATH=/msys/bin:$PATH
cd /msys/rt
mkdir bld && cd bld
../src/configure --prefix=$MFS
make
make install prefix=$MFS tooldir=$MFS

编译gcc(第一遍)
修改PATH,让gcc找到我们编译的ld
export OLDPATH=$PATH
export $PATH=$MFS/bin:$PATH
首先需要禁止gcc配置时自动搜索并修正宿主系统的头文件
cp -v gcc/Makefile.in{,.orig} &&
sed 's@\./fixinc\.sh@-c true@' gcc/Makefile.in.orig > gcc/Makefile.in
修正gcc默认在/usr/include下寻找头文件的问题
修改gcc/Makefile.in
NATIVE_SYSTEM_HEADER_DIR = /include
修改gcc/cppdefault.c
#define STANDARD_INCLUDE_DIR "/include"
修正库搜索路径
gcc/collect2.c
删除add_prefix (&libpath_lib_dirs, "/usr/lib");
修正可执行文件搜索路径
gcc/gcc.c
删除八行
add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
            PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
            PREFIX_PRIORITY_LAST, 2, 0);

add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
            PREFIX_PRIORITY_LAST, 1, 0);
add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
            PREFIX_PRIORITY_LAST, 1, 0);

建立编译目录
mkdir ../gcc-build && cd ../gcc-build
../gcc-4.2.0/configure --prefix=$MFS --disable-nls --disable-shared --disable-win32-registry --enable-languages=c --enable-optimize -v --host=mingw32 --target=i686-pc-cygwin -

-build=mingw32 --disable-threads --disable-multilib --with-sysroot=$MFS
编辑一下Makefile,LD = ld,MAKEINFO = makeinfo
make all-gcc
make install-gcc

现在,需要调整一下工具链
i686-pc-cygwin-gcc -dumpspecs > $MFS/lib/gcc/i686-pc-cygwin/4.2.0/specs
修改specs:
*lib中-lcygwin改为-lmsys-1.0.dll

编译Hello World程序验证工具链正常工作
cat > test.c <<EOF
#include <stdio.h>
#include <windows.h>

int main()
{
        printf("Hello World!\n");
        MessageBox(NULL,"Hello World!","Test",MB_OK);
        return 0;
}
EOF
i686-pc-cygwin-gcc -v test.c
./test

OK,我们的工具链已经可以工作了,下面需要编译一些基本工具

为什么需要MSYS?
因为某些GNU工具需要POSIX支持,在MinGW下是无法编译的,或者工作不正常
这样,当configure脚本或者Makefile用到它们时,就会出现错误。

(后面的部分未完成)
编译mingw-runtime
编辑configure.in,W32API = -I /d/mmfs/mingw32/include
autoconf
编辑profile/configure.in,W32API = -I /d/mmfs/mingw32/include
autoconf
编辑mingwex/configure.in,W32API = -I /d/mmfs/mingw32/include
autoconf
./configure --prefix=$MFS/mingw32 --host=mingw32 --build=mingw32 --target=mingw32
make
make install

binutils
gcc
newlib
MSYS-runtime
w32api

bash
bzip2
coreutils
diffutils
findutils
gawk
gettext
grep
gzip
m4
make
patch
perl
sed
tar
texinfo

7月15日

启用Windows Boot Debugger

WinDDK中附带了一个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不能加载符号文件。。。期待牛人写一个补丁吧,呵呵。
6月14日

在Windows下编译Grub2

在Windows下编译Grub2,需要一个运行环境,我们选择msys+mingw
就这样直接编译是不行的
我们需要一个交叉编译器(Cross Compiler)
可以在msys里自己编译一个,我的放在/var下
编译的方法有很多,你可以参考我用的命令:
#编译binutils
configure --prefix=/var --target=i686-pc-elf --with-gmp=/var --with-mpfr=/var --disable-nls --disable-shared --disable-threads --with-stabs --enable-interwork --enable-multilib
#修改gcc/fixinc/mkfixinc.sh
i?86-*-mingw32 | \
下一行添加
i?86-*-elf | \
#编译gcc
configure --enable-languages=c --disable-shared --disable-threads --disable-win32-registry --disable-nls --target=i686-pc-elf --host=i686-pc-mingw32 --build=i686-pc-mingw32 --prefix=/var
对于grub2的代码需要作一些修改
1.修改grub2/aclocal.m4,将gcc符号判断相关指令删除,直接指定如下内容:
dnl Check what symbol is defined as a start symbol.
dnl Written by Yoshinori K. Okuji.
AC_DEFUN(grub_CHECK_START_SYMBOL,
[AH_TEMPLATE([START_SYMBOL], [Define it to either start or _start])
  AC_DEFINE([START_SYMBOL], [_start])
])
dnl Check what symbol is defined as a bss start symbol.
dnl Written by Michael Hohmoth and Yoshinori K. Okuji.
AC_DEFUN(grub_CHECK_BSS_START_SYMBOL,
[AH_TEMPLATE([BSS_START_SYMBOL], [Define it to one of __bss_start, edata and _edata])
  AC_DEFINE([BSS_START_SYMBOL], [__bss_start])
])
dnl Check what symbol is defined as an end symbol.
dnl Written by Yoshinori K. Okuji.
AC_DEFUN(grub_CHECK_END_SYMBOL,
[AH_TEMPLATE([END_SYMBOL], [Define it to either end or _end])
  AC_DEFINE([END_SYMBOL], [_end])
])
2.修改grub2/conf/i386-pc.mk
删除sbin_UTILITIES等号后的内容,将bin_UTILITIES等号后的内容改为grub-mkimage.exe
3.我的ln不知为何有问题,只好手工建链接
cd grub2/include/grub
ln -s i386 cpu
ln -s i386/pc machine
修改完成后,运行以下命令即可编译:
aclocal
autoconf
autoheader
./configure --prefix=/opt --disable-nls --target=i686-pc-elf
make
安装到目标目录(前面指定了为/opt)
make install
如果要清理输出文件的话,运行以下命令:
make mostlyclean
2月24日

在Visual Studio 2005和VC++版本8开发环境中使用yasm

大意实际上是这样:
    把yasm.exe放到Program Files\Microsoft Visual Studio 8\VC\bin下,把yasm.rules放到Program Files\Microsoft Visual Studio 8\VC\VCProjectDefaults下,然后自定义生成规则即可,这一点玩过VS 2005的都应该知道。。。
    文章最后提到了链接器的bug:当链接器产生dll文件时,无法识别指示绝对地址的符号。
    本文后附带了一个中文的yasm.rules :)
begin-base64 644 yasm.zip
UEsDBBQAAgAIAMRzWDYWU/b9sQMAAAgNAAAKAAAAeWFzbS5ydWxlc71XW08T
QRR+ron/YbMxREyg+EZkV6MUExIvjSDRIA/T7bSM2UvdnQH65qVa8BKbqCia
eA/1SjUmgoL6Z7rb8sRfcGZnd9niLlalPu2Zc86cM993Zs/MbKz+kA7NaKow
BU0LGbos7u/tEwWoK0YW6XlZJDjX0y8eOrh7lzSGLALUEUyyyBg1DPUoUuHu
XYkTQIOyeBZYmkhHY36c/t6+PqagMxPSKaJCi0kJaZBY2NCOEKRmmZbp/BCH
R46L7jiFrIIKipuRnY/lxtq8vfCK2wcNTQN69hjSqb1I7ULPmSlF6MkJe/am
VYBzhqmxyd3CeNqEadNQJqgETAuaVEjBDMnT7zFkYYaBebrqHI1nUem0vikP
64pKsjAN8CQbnsych0p4FtILBFsTfF0nCWYjWRzfs8WR29lwaAZDnVFE3fb1
eqwlEkMzUCGYqlPQUkxUwC6JHDdFNczS+NG6+RSXz4RE4RWgiZFHMNWMYJPW
ztMXudLj2AMmesoWop3lVfv6U3vpYf3LnO/gB0mDPORe9spKs1ry7YMAw7xh
FmVx/XmJT228W7RvLwcZWuDcLFOfTc+HJe68sTZrL17uAgXDGrCKWsZQuezM
zoeVgixMAZVArttYC1Y5Mo2wMimLPSlh3PWY2EyvIg1hmJVFbBLoq4f1SWgi
DDIqbDEk26AwvCMieVxfKDEeb161K2+byzX7e+kv2Lx6q/FtaTsSQ0mc+XJ9
9TNlszVbwAoSui4QAw943PBBBxkK/p9IehrV1fWFl53cZjxDjGfACvkPe6W1
C0TT8WjJeVrmJbQrtxrVD39OSvP7Hbv8dZvdEp8koMPYfpPkAFHxGDPJIrex
poRTyOw+57UntzX1GpnzLXPboSnciSNJsmfvN5+96jBJ8UkCktRtSGoHKD2N
vPbB4EZ3D7ptQ391J1pHdIYAZLodkEfoBQACPeaQoQdsJLj612rj7pPmhyvN
2r36j2fOpdrO1vFBza4sxicJIOYFZap/K6QhnWhxVWN3iNhyvSw1KteCy8kO
1Wr94pxz43V95WJ95U04yV5++un05sAlgZ6SAhdNMM2Fbj+khy0hub+uf0Pw
wLo6X5Pwfu4+MdAEdJl6cE/5hQBmEgJbso0M+6My0KXHJAhbgvBSsgWQlAwX
7/cFda+CkfVsVl84jyudLGaQgfVPqDZr751P9w5EVvXwaBfQCgOjLT55YHWk
yIXfFPmfa1ygK4+JH7b8SY2l5Jbbr5Tc8r5wnx9J//1BQ0Y8YqjhJ1BLAQIU
ABQAAgAIAMRzWDYWU/b9sQMAAAgNAAAKAAAAAAAAAAAAIAAAAAAAAAB5YXNt
LnJ1bGVzUEsFBgAAAAABAAEAOAAAANkDAAAAAA==
====
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 Engineering

NTLDR 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
{
   DWORD SystemReset;
   DWORD DiskServices;
   DWORD KeybGetChar;
   DWORD GetTimeOfDay;
   DWORD ExecuteBootSector;
   DWORD ExecuteNtdetect;
   void (__cdecl *VideoServices) (DWORD function, DWORD data);
   void (__cdecl *GetDateTime) (DWORD *time, DWORD *date);
   DWORD SerialServices;
   DWORD GetMicrosecondMetric;
   DWORD LoadVgaTextModeChars;
   void (__cdecl *GetSystemMemoryMap) (PSYSTEM_MEMORY_MAP pSystemMemoryMap);
   DWORD ExtDiskServices;
   DWORD GetBootCdromStatus;
   DWORD ExtDiskGetDriveParams;
   DWORD PxenvApiServices;
   DWORD ApmInitialize; /* 这个函数即没有参数也没有返回值。
                           奇怪的是,虽然没有返回任何信息,
                           它也对高级电源管理的版本和接口
                           作了简单的测试。*/
   // ... (?)
} IO_FUNCTIONS, *PIO_FUNCTIONS;

    就如你所看到的,我只是给出了它们的名字来表明它们的用处,并没有研究它们的参数和实际的功能。
    用IDA来分析osloader.exe,当IDA的分析停止时,你就可以看到代码的入口点了。AndreaGeddon的文章里把它叫作NtProcessStartup,让我们把它重命名吧。它的唯一参数arg_0是指向BootContextRecord结构体的指针,我们把它重命名成pBootContext。
    我们跳过第一个调用,因为它只是为局部变量分配栈空间。第二个调用叫做DoGlobalInitialization(参考AndreaGeddon的文章而来),它也只有一个参数pBootContext,在这个函数里,分配了一个全局指针指向I/O函数表。所以你需要识别出它。看看DoGlobalInitialization的反汇编代码片断:

.text:0040125C DoGlobalInitialization proc near      ; CODE XREF: NtProcessStartup+1E
.text:0040125C
.text:0040125C pBootContext    = dword ptr  8
.text:0040125C
.text:0040125C                 mov     edi, edi
.text:0040125E                 push    ebp
.text:0040125F                 mov     ebp, esp
.text:00401261                 push    esi
.text:00401262                 mov     esi, [ebp+pBootContext]
.text:00401265                 mov     eax, [esi+BOOT_CONTEXT.LoaderImageBase]
.text:00401268                 mov     loaderImageBase, eax
.text:0040126D                 mov     eax, [esi+BOOT_CONTEXT.LoaderExportTableVa]
.text:00401270                 push    esi
.text:00401271                 mov     loaderExportTableVa, eax
.text:00401276                 call    InitializeMemory
.text:0040127B                 test    eax, eax
.text:0040127D                 jz      short @@1
.text:0040127F                 push    eax
.text:00401280                 push    offset aInitializememo; "InitializeMemory failed %lx\n"
.text:00401285                 call    printf_output
.text:0040128A                 pop     ecx
.text:0040128B                 pop     ecx
.text:0040128C
.text:0040128C infinite_loop:                        ; CODE XREF: DoGlobalInitialization:infinite_loop
.text:0040128C                 jmp     short infinite_loop
.text:0040128E; ---------------------------------------------------------------------------
.text:0040128E
.text:0040128E @@1:                                  ; CODE XREF: DoGlobalInitialization+21
.text:0040128E                 mov     eax, [esi+BOOT_CONTEXT.pIoFunctions]
.text:00401291                 mov     pIoFunctions, eax
.text:00401296                 mov     ecx, [esi+BOOT_CONTEXT.IsEisaSystem]
.text:00401299                 push    0000007Fh
.text:0040129B                 push    00000000h      ; /* SET CURSOR POSITION - Row = 0x7F, Column = 0x00 */
.text:0040129D                 mov     isEisaSystem, ecx
.text:004012A3                 call    [eax+IO_FUNCTIONS.VideoServices]

    上面的代码中,对于pIoFunctions->VideoServices的调用是通过寄存器间接寻址完成的,寄存器的值被传给全局指针pIoFunctions,你应该能轻松看出这些的。
    在IDA中创建一个结构体定义IO_FUNCTIONS,它应该像下面这样:
IO_FUNCTIONS    struc; (sizeof=0x4C)
00000000 SystemReset     dd ?
00000004 DiskServices    dd ?
00000008 KeybGetChar     dd ?
0000000C GetTimeOfDay    dd ?
00000010 ExecuteBootSector dd ?
00000014 ExecuteNtdetect dd ?
00000018 VideoServices   dd ?
0000001C GetDateTime     dd ?
00000020 SerialServices  dd ?
00000024 GetMicrosecondMetric dd ?
00000028 LoadVgaTextModeChars dd ?
0000002C GetSystemMemoryMap dd ?
00000030 ExtDiskServices dd ?
00000034 GetBootCdromStatus dd ?
00000038 ExtDiskGetDriveParams dd ?
0000003C PxenvApiServices dd ?
00000040 ApmInitialize   dd ?
00000044 field_44        dd ? // 未知
00000048 field_48        dd ? // 未知
0000004C IO_FUNCTIONS    ends

    现在所有对于pIoFunctions的交叉引用,都加上IO_FUNCTIONS的偏移定义。例如下面的代码:
.text:0040656D                 mov     eax, pIoFunctions
.text:00406572                 call    dword ptr [eax+1Ch]
    变成了:
.text:0040656D                 mov     eax, pIoFunctions
.text:00406572                 call    [eax+IO_FUNCTIONS.GetDateTime]
    希望你也能辨认出I/O函数调用的名称,这非常有用。
    事实上osloader.exe中还有另外一张更重要的函数表,不过它已经被很好地文档化了,你只需要稍待片刻就能看到。
    OK,接着上次我们说到的函数表,它之所以存在是因为bootloader的代码不仅仅是为Intel-x86体系的计算机所写,也可以用于RISC体系的机器。RISC计算机的固件会帮助bootloader实现启动过程。这些固件遵循ARC(高级RISC计算)规范,通过一个函数向量表向bootloader提供了接口,bootloader通过接口实现启动和启动配置。
    这样的固件在基于Intel-x86的机器上是不存在的,所以osloader.exe自己实现了这张向量表。ARC规范详细地描述了它。所以我们可以通过规范文档来了解每一个函数,它们的参数,返回值和作用。这非常简单:),我们要做的只是定位这张表。
    规范文档在此->http://www.netbsd.org/Documentation/Hardware/Machines/ARC/riscspec.pdf。
    要定位这张向量表,让我们回到NtProcessStartup里,找到紧接着DoGlobalInitialization的调用。这个函数初始化了固件调用向量表。我把它命名为InitArcFirmwareVectors。下面是我的反汇编结果,可以看到只有osloader使用的向量被实现了:

.text:0040757D InitArcFirmwareVectors proc near      ; CODE XREF: NtProcessStartup+24
.text:0040757D                 mov     edi, edi
.text:0040757F                 push    edi
.text:00407580                 push    25h
.text:00407582                 pop     ecx
.text:00407583                 mov     eax, offset UnimplementedFirmwareVector
.text:00407588                 mov     edi, offset ArcFirmwareVectors
.text:0040758D                 rep stosd
.text:0040758F                 mov     eax, offset ArcFwRestartReboot
.text:00407594                 mov     ArcFirmwareVectors.Close, offset ArcFwClose
.text:0040759E                 mov     ArcFirmwareVectors.Open, offset ArcFwOpen
.text:004075A8                 mov     ArcFirmwareVectors.GetMemoryDescriptor, offset ArcFwGetMemoryDescriptor
.text:004075B2                 mov     ArcFirmwareVectors.Seek, offset ArcFwSeek
.text:004075BC                 mov     ArcFirmwareVectors.Read, offset ArcFwRead
.text:004075C6                 mov     ArcFirmwareVectors.GetReadStatus, offset ArcFwGetReadStatus
.text:004075D0                 mov     ArcFirmwareVectors.Write, offset ArcFwWrite
.text:004075DA                 mov     ArcFirmwareVectors.GetFileInformation, offset ArcFwGetFileInformation
.text:004075E4                 mov     ArcFirmwareVectors.GetTime, offset ArcFwGetTime
.text:004075EE                 mov     ArcFirmwareVectors.GetRelativeTime, offset ArcFwGetRelativeTime
.text:004075F8                 mov     ArcFirmwareVectors.GetPeer, offset ArcFwGetPeer
.text:00407602                 mov     ArcFirmwareVectors.GetChild, offset ArcFwGetChild
.text:0040760C                 mov     ArcFirmwareVectors.GetParent, offset ArcFwGetParent
.text:00407616                 mov     ArcFirmwareVectors.GetComponent, offset ArcFwGetComponent
.text:00407620                 mov     ArcFirmwareVectors.GetConfigurationData, offset ArcFwGetConfigurationData
.text:0040762A                 mov     ArcFirmwareVectors.GetEnvironmentVariable, offset ArcFwGetEnvironmentVariable
.text:00407634                 mov     ArcFirmwareVectors.Restart, eax
.text:00407639                 mov     ArcFirmwareVectors.Reboot, eax
.text:0040763E                 pop     edi
.text:0040763F                 retn    4
.text:0040763F InitArcFirmwareVectors endp

    根据上面的汇编代码片断你应该能自己推断出ArcFirmwareVectors结构体的成员。在IDA里定义如下结构体:

00000000 ARC_FIRMWARE_VECTORS struc; (sizeof=0x94)
00000000 Load            dd ?
00000004 Invoke          dd ?
00000008 Execute         dd ?
0000000C Halt            dd ?
00000010 PowerDown       dd ?
00000014 Restart         dd ?
00000018 Reboot          dd ?
0000001C EnterInteractiveMode dd ?
00000020 ReturnFromMain  dd ?
00000024 GetPeer         dd ?
00000028 GetChild        dd ?
0000002C GetParent       dd ?
00000030 GetConfigurationData dd ?
00000034 AddChild        dd ?
00000038 DeleteComponent dd ?
0000003C GetComponent    dd ?
00000040 SaveConfiguration dd ?
00000044 GetSystemId     dd ?
00000048 GetMemoryDescriptor dd ?
0000004C Signal          dd ?
00000050 GetTime         dd ?
00000054 GetRelativeTime dd ?
00000058 GetDirectoryEntry dd ?
0000005C Open            dd ?
00000060 Close           dd ?
00000064 Read            dd ?
00000068 GetReadStatus   dd ?
0000006C Write           dd ?
00000070 Seek            dd ?
00000074 Mount           dd ?
00000078 GetEnvironmentVariable dd ?
0000007C SetEnvironmentVariable dd ?
00000080 GetFileInformation dd ?
00000084 SetFileInformation dd ?
00000088 FlushAllCaches  dd ?
0000008C TestUnicodeCharacter dd ?
00000090 GetDisplayStatus dd ?
00000094 ARC_FIRMWARE_VECTORS ends

然后用这个定义创建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:0041D084                 call    dword ptr [eax+54h]

变成了:

.text:0041D07F                 mov     eax, pArcFirmwareVectors
.text:0041D084                 call    [eax+ARC_FIRMWARE_VECTORS.GetRelativeTime]

ARC规范描述了所有的函数,据我所知,osloader.exe中的实现是遵循ARC规范的。

我刚刚才知道ddk中的ntldr_dbg是调试版本,那么它的代码里应该有很多调试信息,我以后将用它的反汇编作为对原始ntldr反汇编的参考。


10月2日

BOOT.INI可选参数

----====|BOOT.INI可选参数|====----
作者:Rinrin
注意:如要引用此文档请注明作者
2006.10.15  增加了/RDCLIENTPORT
2005.8.15    初始版本
----====|[1]简介|====----
Boot.ini是用于NTLDR的配置文件,系统启动时,NTLDR读取Boot.ini,并进行解释.通常Boot.ini的内容
如下:
+-----------------------------------------------------------------------------+
| [boot loader]                                                               |
| timeout=30                                                                  |
| default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS                         |
| [operating systems]                                                         |
| multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows" /fastdetect |
+-----------------------------------------------------------------------------+
位于引号之后的就是可选参数.NTLDR对可选参数有两种处理情况:
1.链式装载进行多重启动时,可选参数直接被丢弃
2.引导NT系列操作系统时,可选参数被复制出来,启动信息块结构中的某个指针将指向可选参数字符串
  这个指针将会传给执行体,然后传给会话管理器.最后记录在如下注册表项中:
  +-------------------------------------------------------------------- ---+
  | HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control SystemStartOptions |
  +------------------------------------------------------------------------+
由此可见:可选参数实际上可以是任意的,只不过系统可以识别的参数是有限的.
----====|[2]主体|====----
下面就是目前发现的可接受的可选参数,如果有新的参数这里没有列出的话,欢迎给我来信
(Rinrin _at_ tju.edu.cn).
/3GB
将用户地址空间从2GB增加到3GB.提高大型数据库及应用程序性能.只适用于NT4 企业版,2000高级服务器版,
2000数据中心服务器版,XP以上版本Windows.
/BASEVIDEO
只加载标准显示器驱动(vga.sys)
/BAUDRATE=
指定调试模式时的波特率,默认为19200.(例如/BAUDRATE=115200)
/BOOTLOG
日志模式.Windows将生成启动日志%SystemRoot%/Ntbtlog.txt
/BOOTLOGO
显示背景图片,必须是640x480x4的bmp文件,文件名为Boot.bmp并放置于Windows目录下.这个参数必须与
/NOGUIBOOT联合使用,操作系统必须为XP以上.
/BREAK
HAL初始化时停止在断点处.如果不和/DEBUG一起使用,则会发生蓝屏(0x00000078 PHASE0_ EXCEPTION)
/BURNMEMORY=
指定不可使用的内存大小,单位为MB.与/MAXMEM=类似.
/CHANNEL=
当指定/DEBUGPORT=1394时,此参数选定调试用的通道.取值范围为0-62,默认为0.
/CLKLVL
指定此参数后,x86多处理器HAL(Halmps.dll)将会把系统时钟设置为电平触发方式而不是边缘触发.

/CMDCONS
当启动恢复控制台时应传递此参数,并且只能有这一个参数.
/CRASHDEBUG
进入调试模式,但当出现蓝屏时才激活.
/DEBUG
进入调试模式.
/DEBUGPORT=
指定调试端口.例如/DEBUGPORT=COM2,/DEBUGPORT=1394.
/DEBUGSTOP
启动文本安装模式的调试.只用于setupldr.bin(使用调试版以达到最好的效果).该调试模式被称为
Boot Debug,早于Kernel Debug.可以在WINNT.SIF或TXTSETUP.SIF中指定此参数.
/DETECTHAL
用于Windows Vista中,将自动检测HAL的类型.
/EXECUTE
禁止数据执行保护功能.适用版本XP SP2,2003SP1.
/FASTDETECT
NTDETECT不检测串行口和并行口上的设备.加快启动速度.适用版本2000以上.NT4则使用/NOSERIALMICE
参数.
/INTAFFINITY
使用此参数后x86多处理器HAL(Halmps.dll)将只允许编号最大的处理器收到中断请求.
/KERNEL=
/HAL=
指定内核镜像(NTOSKRNL.EXE)和HAL(HAL.DLL)的位置.NTLDR将加载你指定的Kernel和Hal而忽略默认的.
/LASTKNOWNGOOD
使用最后一次正确配置.
/MAXMEM=
可以使用的内存数,单位为MB.可以使用的内存是从头开始的,和 /BURNMEMORY= 不同,/MAXMEM=不考虑
内存空洞问题.
/MAXPROCSPERCLUSTER=
x86多处理器HAL(Halmps.dll)将强制APIC使用簇模式寻址.
/MININT
适用于Windows PE.使用此参数后,配置管理器(CM)将以只读模式装载注册表分支(Hive)SYSTEM,所有的
改变只保留于内存中.
/NODEBUG
不进入调试模式.可以覆盖/DEBUG,/DEBUGPORT,/BAUDRATE和/DEBUGSTOP等参数.
/NOEXECUTE=
指定数据执行保护(DEP)的类型.只适用于32位系统,64位系统的DEP总是打开.有以下几种类型:
    /NOEXECUTE=OPTIN     针对系统核心和指定的映像文件打开DEP功能.
    /NOEXECUTE=OPTOUT     针对指定的映像文件以外的打开DEP功能.
    /NOEXECUTE=ALWAYSON   总是打开DEP功能.
    /NOEXECUTE=ALWAYSOFF  关闭DEP,同/EXECUTE.
/NOGUIBOOT
不显示启动背景图片.
/NOLOWMEM
不使用开头的4G内存.此参数必须和/PAE一起使用,系统必须有4G以上的物理内存,支持PAE的内核
(Ntkrnlpa.exe)必须被启用.此参数主要用于测试设备驱动程序对大内存系统的兼容性.
/NOPAE
不装载支持PAE的内核映像.
/NOSERIALMICE=[COMx | COMx,y,z...]
用于NT4的过时参数.可以用/FASTDETECT代替.
/NUMPROC=
在多处理器系统中指定可用的处理器个数.
/ONECPU
在多处理器系统中只使用一个CPU.
/PAE
启用PAE.NTLDR将会加载Ntkrnlpa.exe.
/PCILOCK
系统将不自动为PCI设备分配IO和IRQ资源.所有的资源由BIOS分配.
/RDCLIENTPORT=
用于自动部署服务(ADS),客户机将使用指定端口来连接到服务器。
 
/RDEXPORTASCD
当使用ISO文件作为RAMDISK镜像时,必须指定此参数.否则会发生Unmountable_Boot_Volume错误.
/RDPATH=
指定SDI映像文件位置.可以使用ARC路径,如果使用PXE技术启动系统的话,SDI文件可以在TFTP服务器上.
对于Windows Server 2003 SP1,还可以使用光盘镜像(ISO文件),不过必须和/RDEXPORTASCD一起使用.
/RDIMAGEOFFSET=
SDI文件中磁盘镜像的起始偏移.通常为4096.使用SDI文件启动必须指定此参数.
/REDIRECT
将紧急管理服务(EMS)的输入输出重定向至串行口.可以在[boot loader]小节中指定redirect=和
redirectbaudrate=参数.
/SAFEBOOT:
以安全模式启动系统.系统将只装载HKLM\SYSTEM\CurrentControlSet\Control\SafeBoot下指定的
驱动和服务.有以下三种类型:
    /SAFEBOOT:MINIMAL   普通的安全模式
    /SAFEBOOT:NETWORK   带网络连接的安全模式
    /SAFEBOOT:DSREPAIR  目录恢复模式
一个可选的附加参数为(ALTERNATESHELL),例如/SAFEBOOT:MINIMAL(ALTERNATESHELL)
使用此附加参数后,启动的Shell在如下注册表项中定义:
    HKLM\SYSTEM\CurrentControlSet\SafeBoot\AlternateShell
/SCSIORDINAL:
指定scsi控制器的ID.防止因加入新的SCSI设备导致系统不能正常启动.
/SDIBOOT=
适用于Windows XP Embedded中,用来指定加载的SDI文件位置.和/RDPATH=类似.
/SOS
在启动时显示装载的驱动程序,系统版本号,物理内存大小和处理器个数.
/TIMERES=
x86多处理器HAL(Halmps.dll)将设定系统时钟为指定的间隔数,单位为100ns.HAL支持以下几种:
    9766
    19532
    39063
    78125
默认为7.8ms(最后一个)
/USENEWLOADER
用于Windows Vista中.Windows将使用新的启动方式即把控制权交给Winload.exe
/USERVA=
类似于/3GB,指定用户地址空间大小,范围为2048-3072,单位为MB.
/WIN95
链式装载Bootsect.w40并模拟Windows 9x的多重启动操作(如文件改名).
/WIN95DOS
链式装载Bootsect.dos并模拟多重启动操作,类似于/WIN95.
/YEAR=
使用指定的年份而不使用BIOS实时钟中的.曾被用来测试千年虫问题.
 
----====|[3]参考|====----
[1]Boot INI Options Reference
    http://www.sysinternals.com/Information/bootini.html
----====|End Of File|====----
10月1日

安家了~

这个世界上叫Rinrin的很多,但是搞计算机的只有我一个吧,我想。
空间的名称由来:
doom9大家都知道吧,最有名的视频技术论坛,创建者有这样一段话:
同时我觉得我已经可以参与Oleg论坛里的一些讨论了,因为我那时候已经知道了不少了。 你也可以看到,我发帖子的时候都很谨慎,因为我懂得那古老的网络礼节.. 那就是在一个新闻组里,你得先等等,仔细地浏览一阵,了解一下基本的氛围和讨论情况。这就是为什么现在我总是感到很恼火,总是有人不先看看FAQ和其下的讨论就问些已经被回答过上百遍的问题。 无论如何..为了可以在delphi.com上发言,我注册了一个帐号,但我的老昵称Doom已经被人使用了。Delphi建议了一些其他的昵称,其中就有Doom9。我觉得它可能会很有吸引力,所以我就选择了这个昵称。
既然rinrin.spaces.live.com不是我的,那就叫rinrin9了,呵呵