用Bochs调试NTLDR

导读:
  关键字:bochs, bochsdbg, ntldr, 调试
  对一台安装了Windows NT 系列操作系统的PC来说,按下电源开关之后,CPU中首
  先开始运行的是Bios,然后是MBR,接着是引导扇,然后就是NTLDR。ntoskrnl.exe和
  hal.dll 都是由NTLDR来加载的。也就是说,运行NTLDR的时候,系统中还没有任何应
  用程序或者驱动,当然也就没有任何基于软件的调试器可用。当然,无所不能的硬件
  调试器肯定是可以的,可惜我们没有硬件调试器。
  幸好有了Bochs。Bochs是一个基于LGPL的开源x86 虚拟机软件。Bochs的CPU指令
  是完全自己模拟出来的,这种方式的缺点是速度比较慢;优点是具有无以伦比的可移
  植性:有Gcc的地方就可以有Bochs。甚至已经有了跑在PocketPC上的Bochs。
  现在的Bochs 已经实现了一定程度的调试功能,虽然在易用性和功能上还无法和
  WinDbg、SoftICE相比,但优势也是很明显的:对跑在Bochs里面的代码来说,这就是
  “硬件调试器”。
  对Windows 版本的Bochs来说,安装目录下的bochsdbg.exe就是Bochs的调试版本。
  用它来运行Bochs虚拟机就可以进行“硬件调试”。
  Bochs的调试命令风格是按照GDB习惯来设计的,这对于用惯了WinDbg的人来说无
  疑是痛苦的,好在这是个开源软件,看着不顺眼可以考虑自己改改。
  目前版本的Bochs(Version 2.1.1)支持的调试命令如下:
  [注意]
  1、Bochs的文档和帮助信息中的使用说明与真实情况之间存在很大的差错和缺失,
  下面的命令说明根据源码作了很多补充和修正。
  2、其中涉及到的seg(段)、off(偏移)、addr(地址)、val(值)等数字,
  可以使用十六进制、十进制或者八进制,但必须按照如下形式书写:
  十六进制 0xCDEF0123
  八进制 01234567
  十进制 123456789
  尤其要注意,Bochs不能自动识别16进制的数字,也不接受12345678h这种写法。
  [执行控制]
  c|cont 向下执行,相当于WinDBG的“g”。
  s|step|stepi [count] 单步执行,相当于WinDBG的“t”,count 默认为 1。
  p|n|next 单步执行,类似于WinDBG的“p”。
  q|quit|exit 退出调试,同时关闭虚拟机。
  Ctrl-C 结束执行状态,返回调试器提示符。
  Ctrl-D if at empty line on command line, exit
  (至少在Windows版本中我没有发现Ctrl-D有什么功能)
  [执行断点]
  vb|vbreak [seg:off] 在虚拟地址上下断点。
  lb|lbreak [addr] 在线性地址上下断点,相当于WinDBG的“bp”。
  pb|pbreak|b|break [addr] 在物理地址上下断点。(为了兼容GDB的语法,地址前
  可以加上一个“*”)。
  blist 显示断点状态,相当于WinDBG的“bl”。
  bpd|bpe [num] 禁用/启用断点,WinDBG的“be”和“bd”。num是断
  点号,可以用blist命令查询。
  d|del|delete [num] 删除断点,相当于WinDBG的“bc”。mum是断点号,可
  以用blist命令查询。
  [读写断点]
  watch read [addr] 设置读断点。
  watch write [addr] 设置写断点。
  unwatch read [addr] 清除读断点。
  unwatch write [addr] 清除写断点。
  watch 显示当前所有读写断点。
  unwatch 清除当前所有读写断点。
  watch stop|continue 开关选项,设置遇到读写断点时中断下来还是显示出来但
  是继续运行。
  [内存操作]
  x /nuf [addr] 显示线性地址的内容
  xp /nuf [addr] 显示物理地址的内容
  n 显示的单元数
  u 每个显示单元的大小,u可以是下列之一:
  b BYTE
  h WORD
  w DWORD
  g DWORD64
  注意: 这种命名法是按照GDB习惯的,而并不是按照inter的规范。
  f 显示格式,f可以是下列之一:
  x 按照十六进制显示
  d 十进制显示
  u 按照无符号十进制显示
  o 按照八进制显示
  t 按照二进制显示
  c 按照字符显示
  n、f、u是可选参数,如果不指定,则u默认是w,f默认是x。如果前面使用过x或
  者xp命令,会按照上一次的x或者xp命令所使用的值。n默认为1。addr 也是一个
  可选参数,如果不指定,addr是0,如过前面使用过x或者xp命令,指定了n=i,
  则再次执行时n默认为i+1。
  setpmem [addr] [size] [val] 设置物理内存某地址的内容。
  需要注意的是,每次最多只能设置一个DWORD:
  这样是可以的:
   setpmem 0x00000000 0x4 0x11223344
   x /4 0x00000000
  [bochs]:
  0x00000000 : 0x11223344 0x00000000 0x00000000 0x00000000
  这样也可以:
   setpmem 0x00000000 0x2 0x11223344
   x /4 0x00000000
  [bochs]:
  0x00000000 : 0x00003344 0x00000000 0x00000000 0x00000000
  或者:
   setpmem 0x00000000 0x1 0x20
   x /4 0x00000000
  [bochs]:
  0x00000000 : 0x00000020 0x00000000 0x00000000 0x00000000
  下面的做法都会导致出错:
   setpmem 0x00000000 0x3 0x112233
  Error: setpmem: bad length value = 3
   setpmem 0x00000000 0x8 0x11223344
  Error: setpmem: bad length value = 8
  crc [start] [end] 显示物理地址start到end之间数据的CRC。
  [寄存器操作]
  set $reg = val 设置寄存器的值。现在版本可以设置的寄存器包括:
  eax ecx edx ebx esp ebp esi edi
  暂时不能设置:
  eflags cs ss ds es fs gs
  r|reg|registers reg = val 同上。
  dump_cpu 显示完整的CPU信息。
  set_cpu 设置CPU状态,这里可以设置dump_cpu所能显示出来的
  所有CPU状态。
  [反汇编命令]
  u|disas|disassemble [/num] [start] [end]
  反汇编物理地址start到end 之间的代码,如
  果不指定参数则反汇编当前EIP指向的代码。
  num是可选参数,指定处理的代码量。
  set $disassemble_size = 0|16|32 $disassemble_size变量指定反汇编使用的段
  大小。
  set $auto_disassemble = 0|1 $auto_disassemble决定每次执行中断下来的
  时候(例如遇到断点、Ctrl-C等)是否反汇
  编当前指令。
  [其他命令]
  trace-on|trace-off Tracing开关打开后,每执行一条指令都会将反汇编的结果
  显示出来。
  ptime 显示Bochs自本次运行以来执行的指令条数。
  sb [val] 再执行val条指令就中断。val是64-bit整数,以L结尾,形
  如“1000L”
  sba [val] 执行到Bochs自本次运行以来的第val条指令就中断。val是
  64-bit整数,以L结尾,形如“1000L”
  modebp 设置切换到v86模式时中断。
  record ["filename"] 将输入的调试指令记录到文件中。文件名必须包含引号。
  playback ["filename"] 回放record的记录文件。文件名必须包含引号。
  print-stack [num] 显示堆栈,num默认为16,表示打印的条数。
  |calc 和WinDBG的“?”命令类似,计算表达式的值。
  load-symbols [global] filename [offset]
  载入符号文件。如果设定了“global”关键字,则符号针
  对所有上下文都有效。offset会默认加到所有的symbol地
  址上。symbol文件的格式为:"%x %s"。
  [info命令]
  info program 显示程序执行的情况。
  info registers|reg|r 显示寄存器的信息。
  info pb|pbreak|b|break 相当于blist
  info dirty 显示脏页的页地址。
  info cpu 显示所有CPU寄存器的值。
  info fpu 显示所有FPU寄存器的值。
  info idt 显示IDT。
  info gdt [num] 显示GDT。
  info ldt 显示LDT。
  info tss 显示TSS。
  info pic 显示PIC。
  info ivt [num] [num] 显示IVT。
  info flags 显示状态寄存器。
  info cr 显示CR系列寄存器。
  info symbols 显示symbol信息。
  info ne2k|ne2000 显示虚拟的ne2k网卡信息。
  弄明白了调试命令,接下来就可以着手进行NTLDR的调试工作了。下面所进行的工
  作都是在Windows版Bochs 2.1.1上实现的。我们假设读者了解Bochs的基本使用方法和
  术语。
  首先要安装一个Windows NT 4的Bochs虚拟机。
  1、创建虚拟硬盘。
  运行bximage.exe,创建一个500M、flat模式的虚拟硬盘文件“C.img”。
  2、创建一个Windows NT安装光盘的ISO文件“nt.iso”
  如果你打算直接用光盘安装,也可以省去这一步。
  3、创建bochsrc.txt
  内容可参考下面:
  ###############################################################
  megs: 32
  romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000
  vgaromimage: $BXSHARE/VGABIOS-lgpl-latest
  ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14
  ata0-master: type=disk, path="C.img", mode=flat, cylinders=1015, heads=16, spt=63
  ata0-slave: type=cdrom, path="nt.iso", status=inserted
  newharddrivesupport: enabled=1
  boot: cdrom
  log: nul
  mouse: enabled=1
  clock: sync=realtime, time0=local
  ###############################################################
  4、创建start.bat
  内容如下:
  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  ::假设你的Bochs安装在D:/Program/Bochs
  set BXSHARE=D:/Program/Bochs
  %BXSHARE%/bochs.exe -q -f bochsrc.txt
  :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  把C.img、nt.iso、bochsrc.txt、start.bat放到同一个目录下,运行start.bat,
  进行Windows NT的安装。
  事实上,如果只是为了调试MBR、引导扇和NTLDR 的话,并没有必要安装完整的操
  作系统,只要根目录下有ntldr等那几个文件就可以了。这里之所以安装Windows NT而
  不是Windows 2000或者更高版本,一方面是考虑速度问题,另一方面,Windows NT 是
  可以在Bochs上确保顺利完成安装的。如果要调试Windows 2000/XP/2003 的NTLDR,只
  需用这些操作系统的ntldr文件替换Windows NT的即可。
  安装完Windows NT之后,可以进行NTLDR的调试了。把start.bat中的“bochs.exe”
  换成“bochsdbg.exe”。然后运行start.bat。
  下面是操作的屏幕拷贝:
  ========================================================================
  Bochs x86 Emulator 2.1.1
  February 08, 2004
  ========================================================================
  00000000000i[ ] reading configuration from bochsrc.txt
  00000000000i[ ] installing win32 module as the Bochs GUI
  00000000000i[ ] Warning: no rc file specified.
  00000000000i[ ] using log file nul
  Next at t=0 //启动bochsdbg.exe,会自动停在Bios的第一条指令上。
  (0) context not implemented because BX_HAVE_HASH_MAP=0
  [0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b ;ea5be000f0
   b 0x00007c00 //MBR和引导扇都会加载在0000:7c00。
   c
  (0) Breakpoint 1, 0x7c00 in ?? () //第一次会在MBR上中断下来。
  Next at t=772567
  (0) [0x00007c00] 0000:7c00 (unk. ctxt): cli ;fa
   c
  (0) Breakpoint 1, 0x7c00 in ?? () //第二次会在引导扇上中断。
  Next at t=773872
  (0) [0x00007c00] 0000:7c00 (unk. ctxt): jmp 0x7c5d ; eb5b
   b 0x00020000 //ntldr会加载在2000:0000,事实上无论是CDFS、NTFS还是FAT,
  //Windows加载启动文件都是这个地址。
   c
  (0) Breakpoint 2, 0x20000 in ?? () //在NTLDR的第一条指令上断下来了,可以开始进行调试。
  Next at t=861712
  (0) [0x00020000] 2000:0000 (unk. ctxt): jmp 0x1f6 ;e9f301
  现在,我们可以像上帝俯看芸芸众生一样,看着操作系统一步一步启动起来,一
  切尽在眼底,甚至可以看到系统启动过程中实模式切换到保护模式的情景:
  (0).[28734582] [0x00020247] 2000:0247 (unk. ctxt): opsize or eax, 0x1 ; 6683c801
  (0).[28734583] [0x0002024b] 2000:024b (unk. ctxt): mov cr0, eax ; 0f22c0
  (0).[28734584] [0x0002024e] 2000:0000024e (unk. ctxt): xchg bx, bx ;87db
  (0).[28734585] [0x00020250] 2000:00000250 (unk. ctxt): jmp 0x253 ;eb01
  (0).[28734586] [0x00020253] 2000:00000253 (unk. ctxt): push 0x58 ;6a58
  (0).[28734587] [0x00020255] 2000:00000255 (unk. ctxt): push 0x259 ; 685902
  (0).[28734588] [0x00020258] 2000:00000258 (unk. ctxt): retf ; cb
  参考文献:
  Bochs的文档和源码。

本文转自
http://www.xfocus.net/releases/200408/a722.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在普通安全模式的基础上增加了网络连接。但有些网络程序可能无法正常运行,如MSN等,还有很多自启动的应用程序不会自动加载,如防火墙、杀毒软件等。所以在这种模式下一定不要忘记手动加载,否则恶意程序等可能会入侵在你修复电脑的过程中。 3.带命令行提示符的安全模式 只使用基本的文件和驱动程序来启动,在登录之后,屏幕上显示命令提示符,而非Windows图形界面。 说明:在这种模式下,如果你不小心关闭了命令提示符窗口,屏幕会全黑。可按下组合键Ctrl+Alt+Del,调出“任务管理器”,单击“新任务”,再在弹出对话框的“运行”后输入“C:WINDOWSexplorer.exe”,可马上启动Windows XP的图形界面,与上述三种安全模式下的界面完全相同。如果输入“c:windowssystem32cmd”也能再次打开命令提示符窗口。事实上,在其它的安全模式甚至正常启动时也可通过这种方法来启动命令提示符窗口。 4.启用启动日志 以普通的安全模式启动,同时将由系统加载(或没有加载)的所有驱动程序和服务记录到一个文本文件中。该文件称为 ntbtlog.txt,它位于 %windir% (默认为c:windows)目录中。启动日志对于确定系统启动问题的准确原因很有用。 5.启用VGA模式 利用基本VGA驱动程序启动。当安装了使Windows不能正常启动的新视频卡驱动程序时,这种模式十分有用。事实上,不管以哪种形式的安全模式启动,它总是使用基本的视频驱动程序。因此,在这些模式下,屏幕的分辨率为640×480且不能改动。但可重新安装驱动程序。 6.最后一次正确的配置 使用Windows上一次关闭时所保存的注册表信息和驱动程序来启动 。最后一次成功启动以来所作的任何更改将丢失。因此一般只在配置不对(主要是软件配置)的情况下,才使用最后一次正确的配置。但是它不能解决由于驱动程序或文件被损坏或丢失所导致的问题。 7.目录服务恢复模式 这是针对服务器操作系统的,并只用于恢复域控制器上的SYSVOL目录和Active Directory目录服务。 8.调试模式 启动时通过串行电缆将调试信息发送到另一台计算机。 如果正在或已经使用远程安装服务在您的计算机上安装 Windows,则您可以看到与使用远程安装服务还原或恢复系统相关的附加选项。 现实应用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值