乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      用Bochs調(diào)試NTLDR

       jollyme 2005-09-24



      創(chuàng)建時(shí)間:2004-08-05
      文章屬性:原創(chuàng)
      文章提交:tombkeeper (t0mbkeeper_at_hotmail.com)

      用Bochs調(diào)試NTLDR

      作  者:于旸
      郵  件:tombkeeper[0x40]nsfocus[0x2e]com
              tombkeeper[0x40]xfocus[0x2e]org
      完成于:2004.7.9
      關(guān)鍵字:bochs, bochsdbg, ntldr, 調(diào)試



          對(duì)一臺(tái)安裝了Windows NT 系列操作系統(tǒng)的PC來(lái)說(shuō),按下電源開(kāi)關(guān)之后,CPU中首
      先開(kāi)始運(yùn)行的是Bios,然后是MBR,接著是引導(dǎo)扇,然后就是NTLDR。ntoskrnl.exe和
      hal.dll 都是由NTLDR來(lái)加載的。也就是說(shuō),運(yùn)行NTLDR的時(shí)候,系統(tǒng)中還沒(méi)有任何應(yīng)
      用程序或者驅(qū)動(dòng),當(dāng)然也就沒(méi)有任何基于軟件的調(diào)試器可用。當(dāng)然,無(wú)所不能的硬件
      調(diào)試器肯定是可以的,可惜我們沒(méi)有硬件調(diào)試器。

          幸好有了Bochs。Bochs是一個(gè)基于LGPL的開(kāi)源x86 虛擬機(jī)軟件。Bochs的CPU指令
      是完全自己模擬出來(lái)的,這種方式的缺點(diǎn)是速度比較慢;優(yōu)點(diǎn)是具有無(wú)以倫比的可移
      植性:有Gcc的地方就可以有Bochs。甚至已經(jīng)有了跑在PocketPC上的Bochs。

          現(xiàn)在的Bochs 已經(jīng)實(shí)現(xiàn)了一定程度的調(diào)試功能,雖然在易用性和功能上還無(wú)法和
      WinDbg、SoftICE相比,但優(yōu)勢(shì)也是很明顯的:對(duì)跑在Bochs里面的代碼來(lái)說(shuō),這就是
      “硬件調(diào)試器”。

          對(duì)Windows 版本的Bochs來(lái)說(shuō),安裝目錄下的bochsdbg.exe就是Bochs的調(diào)試版本。
      用它來(lái)運(yùn)行Bochs虛擬機(jī)就可以進(jìn)行“硬件調(diào)試”。

          Bochs的調(diào)試命令風(fēng)格是按照GDB習(xí)慣來(lái)設(shè)計(jì)的,這對(duì)于用慣了WinDbg的人來(lái)說(shuō)無(wú)
      疑是痛苦的,好在這是個(gè)開(kāi)源軟件,看著不順眼可以考慮自己改改。

          目前版本的Bochs(Version 2.1.1)支持的調(diào)試命令如下:

      [注意]

      1、Bochs的文檔和幫助信息中的使用說(shuō)明與真實(shí)情況之間存在很大的差錯(cuò)和缺失,
         下面的命令說(shuō)明根據(jù)源碼作了很多補(bǔ)充和修正。

      2、其中涉及到的seg(段)、off(偏移)、addr(地址)、val(值)等數(shù)字,
         可以使用十六進(jìn)制、十進(jìn)制或者八進(jìn)制,但必須按照如下形式書(shū)寫(xiě):

      十六進(jìn)制  0xCDEF0123
      八進(jìn)制    01234567
      十進(jìn)制    123456789
      尤其要注意,Bochs不能自動(dòng)識(shí)別16進(jìn)制的數(shù)字,也不接受12345678h這種寫(xiě)法。

      [執(zhí)行控制]

      c|cont                  向下執(zhí)行,相當(dāng)于WinDBG的“g”。

      s|step|stepi [count]    單步執(zhí)行,相當(dāng)于WinDBG的“t”,count 默認(rèn)為 1。

      p|n|next                單步執(zhí)行,類(lèi)似于WinDBG的“p”。

      q|quit|exit             退出調(diào)試,同時(shí)關(guān)閉虛擬機(jī)。

      Ctrl-C                  結(jié)束執(zhí)行狀態(tài),返回調(diào)試器提示符。

      Ctrl-D                  if at empty line on command line, exit
                              (至少在Windows版本中我沒(méi)有發(fā)現(xiàn)Ctrl-D有什么功能)

      [執(zhí)行斷點(diǎn)]

      vb|vbreak [seg:off]         在虛擬地址上下斷點(diǎn)。

      lb|lbreak [addr]            在線性地址上下斷點(diǎn),相當(dāng)于WinDBG的“bp”。

      pb|pbreak|b|break [addr]    在物理地址上下斷點(diǎn)。(為了兼容GDB的語(yǔ)法,地址前
                                  可以加上一個(gè)“*”)。

      blist                       顯示斷點(diǎn)狀態(tài),相當(dāng)于WinDBG的“bl”。

      bpd|bpe [num]               禁用/啟用斷點(diǎn),WinDBG的“be”和“bd”。num是斷
                                  點(diǎn)號(hào),可以用blist命令查詢(xún)。

      d|del|delete [num]          刪除斷點(diǎn),相當(dāng)于WinDBG的“bc”。mum是斷點(diǎn)號(hào),可
                                  以用blist命令查詢(xún)。

      [讀寫(xiě)斷點(diǎn)]

      watch read [addr]       設(shè)置讀斷點(diǎn)。
      watch write [addr]      設(shè)置寫(xiě)斷點(diǎn)。
      unwatch read [addr]     清除讀斷點(diǎn)。
      unwatch write [addr]    清除寫(xiě)斷點(diǎn)。
      watch                   顯示當(dāng)前所有讀寫(xiě)斷點(diǎn)。
      unwatch                 清除當(dāng)前所有讀寫(xiě)斷點(diǎn)。
      watch stop|continue     開(kāi)關(guān)選項(xiàng),設(shè)置遇到讀寫(xiě)斷點(diǎn)時(shí)中斷下來(lái)還是顯示出來(lái)但
                              是繼續(xù)運(yùn)行。


      [內(nèi)存操作]

      x  /nuf [addr]  顯示線性地址的內(nèi)容
      xp /nuf [addr]  顯示物理地址的內(nèi)容
          n           顯示的單元數(shù)
          u           每個(gè)顯示單元的大小,u可以是下列之一:
                          b BYTE
                          h WORD
                          w DWORD
                          g DWORD64
                          注意: 這種命名法是按照GDB習(xí)慣的,而并不是按照inter的規(guī)范。

          f           顯示格式,f可以是下列之一:
                          x 按照十六進(jìn)制顯示
                          d 十進(jìn)制顯示
                          u 按照無(wú)符號(hào)十進(jìn)制顯示
                          o 按照八進(jìn)制顯示
                          t 按照二進(jìn)制顯示
                          c 按照字符顯示
          n、f、u是可選參數(shù),如果不指定,則u默認(rèn)是w,f默認(rèn)是x。如果前面使用過(guò)x或
          者xp命令,會(huì)按照上一次的x或者xp命令所使用的值。n默認(rèn)為1。addr 也是一個(gè)
          可選參數(shù),如果不指定,addr是0,如過(guò)前面使用過(guò)x或者xp命令,指定了n=i,
          則再次執(zhí)行時(shí)n默認(rèn)為i+1。

      setpmem [addr] [size] [val]    設(shè)置物理內(nèi)存某地址的內(nèi)容。

      需要注意的是,每次最多只能設(shè)置一個(gè)DWORD:
      這樣是可以的:
      <bochs:1>  setpmem 0x00000000 0x4 0x11223344
      <bochs:2> x /4 0x00000000
      [bochs]:
      0x00000000 <bogus+       0>:    0x11223344 0x00000000 0x00000000 0x00000000
      這樣也可以:
      <bochs:1>  setpmem 0x00000000 0x2 0x11223344
      <bochs:2> x /4 0x00000000
      [bochs]:
      0x00000000 <bogus+       0>:    0x00003344 0x00000000 0x00000000 0x00000000
      或者:
      <bochs:1>  setpmem 0x00000000 0x1 0x20
      <bochs:2> x /4 0x00000000
      [bochs]:
      0x00000000 <bogus+       0>:    0x00000020 0x00000000 0x00000000 0x00000000
      下面的做法都會(huì)導(dǎo)致出錯(cuò):
      <bochs:1>  setpmem 0x00000000 0x3 0x112233
      Error: setpmem: bad length value = 3
      <bochs:2>  setpmem 0x00000000 0x8 0x11223344
      Error: setpmem: bad length value = 8

      crc [start] [end]     顯示物理地址start到end之間數(shù)據(jù)的CRC。


      [寄存器操作]

      set $reg = val              設(shè)置寄存器的值?,F(xiàn)在版本可以設(shè)置的寄存器包括:
                                  eax ecx edx ebx esp ebp esi edi
                                  暫時(shí)不能設(shè)置:
                                  eflags  cs  ss  ds  es  fs  gs

      r|reg|registers reg = val   同上。

      dump_cpu                    顯示完整的CPU信息。

      set_cpu                     設(shè)置CPU狀態(tài),這里可以設(shè)置dump_cpu所能顯示出來(lái)的
                                  所有CPU狀態(tài)。

      [反匯編命令]

      u|disas|disassemble [/num] [start] [end]
                                          反匯編物理地址start到end 之間的代碼,如
                                          果不指定參數(shù)則反匯編當(dāng)前EIP指向的代碼。
                                          num是可選參數(shù),指定處理的代碼量。
      set $disassemble_size = 0|16|32     $disassemble_size變量指定反匯編使用的段
                                          大小。

      set $auto_disassemble = 0|1         $auto_disassemble決定每次執(zhí)行中斷下來(lái)的
                                          時(shí)候(例如遇到斷點(diǎn)、Ctrl-C等)是否反匯
                                          編當(dāng)前指令。

      [其他命令]
      trace-on|trace-off      Tracing開(kāi)關(guān)打開(kāi)后,每執(zhí)行一條指令都會(huì)將反匯編的結(jié)果
                              顯示出來(lái)。

      ptime                   顯示Bochs自本次運(yùn)行以來(lái)執(zhí)行的指令條數(shù)。

      sb [val]                再執(zhí)行val條指令就中斷。val是64-bit整數(shù),以L結(jié)尾,形
                              如“1000L”

      sba [val]               執(zhí)行到Bochs自本次運(yùn)行以來(lái)的第val條指令就中斷。val是
                              64-bit整數(shù),以L結(jié)尾,形如“1000L”

      modebp                  設(shè)置切換到v86模式時(shí)中斷。

      record ["filename"]     將輸入的調(diào)試指令記錄到文件中。文件名必須包含引號(hào)。

      playback ["filename"]   回放record的記錄文件。文件名必須包含引號(hào)。

      print-stack [num]       顯示堆棧,num默認(rèn)為16,表示打印的條數(shù)。

      |calc                  和WinDBG的“?”命令類(lèi)似,計(jì)算表達(dá)式的值。

      load-symbols [global] filename [offset]
                              載入符號(hào)文件。如果設(shè)定了“global”關(guān)鍵字,則符號(hào)針
                              對(duì)所有上下文都有效。offset會(huì)默認(rèn)加到所有的symbol地
                              址上。symbol文件的格式為:"%x %s"。

      [info命令]

      info program            顯示程序執(zhí)行的情況。
      info registers|reg|r    顯示寄存器的信息。
      info pb|pbreak|b|break  相當(dāng)于blist
      info dirty              顯示臟頁(yè)的頁(yè)地址。
      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              顯示狀態(tài)寄存器。
      info cr                 顯示CR系列寄存器。
      info symbols            顯示symbol信息。
      info ne2k|ne2000        顯示虛擬的ne2k網(wǎng)卡信息。


          弄明白了調(diào)試命令,接下來(lái)就可以著手進(jìn)行NTLDR的調(diào)試工作了。下面所進(jìn)行的工
      作都是在Windows版Bochs 2.1.1上實(shí)現(xiàn)的。我們假設(shè)讀者了解Bochs的基本使用方法和
      術(shù)語(yǔ)。

          首先要安裝一個(gè)Windows NT 4的Bochs虛擬機(jī)。

      1、創(chuàng)建虛擬硬盤(pán)。
          運(yùn)行bximage.exe,創(chuàng)建一個(gè)500M、flat模式的虛擬硬盤(pán)文件“C.img”。

      2、創(chuàng)建一個(gè)Windows NT安裝光盤(pán)的ISO文件“nt.iso”
          如果你打算直接用光盤(pán)安裝,也可以省去這一步。

      3、創(chuàng)建bochsrc.txt
          內(nèi)容可參考下面:
      ###############################################################
      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、創(chuàng)建start.bat
          內(nèi)容如下:
      :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
      ::假設(shè)你的Bochs安裝在D:\Program\Bochs
      set BXSHARE=D:\Program\Bochs
      %BXSHARE%\bochs.exe -q -f bochsrc.txt
      :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

          把C.img、nt.iso、bochsrc.txt、start.bat放到同一個(gè)目錄下,運(yùn)行start.bat,
      進(jìn)行Windows NT的安裝。

          事實(shí)上,如果只是為了調(diào)試MBR、引導(dǎo)扇和NTLDR 的話(huà),并沒(méi)有必要安裝完整的操
      作系統(tǒng),只要根目錄下有ntldr等那幾個(gè)文件就可以了。這里之所以安裝Windows NT而
      不是Windows 2000或者更高版本,一方面是考慮速度問(wèn)題,另一方面,Windows NT 是
      可以在Bochs上確保順利完成安裝的。如果要調(diào)試Windows 2000/XP/2003 的NTLDR,只
      需用這些操作系統(tǒng)的ntldr文件替換Windows NT的即可。

          安裝完Windows NT之后,可以進(jìn)行NTLDR的調(diào)試了。把start.bat中的“bochs.exe”
      換成“bochsdbg.exe”。然后運(yùn)行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      //啟動(dòng)bochsdbg.exe,會(huì)自動(dòng)停在Bios的第一條指令上。
      (0) context not implemented because BX_HAVE_HASH_MAP=0
      [0x000ffff0] f000:fff0 (unk. ctxt): jmp f000:e05b             ; ea5be000f0
      <bochs:1> b 0x00007c00    //MBR和引導(dǎo)扇都會(huì)加載在0000:7c00。
      <bochs:2> c
      (0) Breakpoint 1, 0x7c00 in ?? () //第一次會(huì)在MBR上中斷下來(lái)。
      Next at t=772567
      (0) [0x00007c00] 0000:7c00 (unk. ctxt): cli                   ; fa
      <bochs:3> c
      (0) Breakpoint 1, 0x7c00 in ?? () //第二次會(huì)在引導(dǎo)扇上中斷。
      Next at t=773872
      (0) [0x00007c00] 0000:7c00 (unk. ctxt): jmp 0x7c5d            ; eb5b
      <bochs:4>b 0x00020000  //ntldr會(huì)加載在2000:0000,事實(shí)上無(wú)論是CDFS、NTFS還是FAT,
                             //Windows加載啟動(dòng)文件都是這個(gè)地址。
      <bochs:5> c
      (0) Breakpoint 2, 0x20000 in ?? () //在NTLDR的第一條指令上斷下來(lái)了,可以開(kāi)始進(jìn)行調(diào)試。
      Next at t=861712
      (0) [0x00020000] 2000:0000 (unk. ctxt): jmp 0x1f6             ; e9f301


          現(xiàn)在,我們可以像上帝俯看蕓蕓眾生一樣,看著操作系統(tǒng)一步一步啟動(dòng)起來(lái),一
      切盡在眼底,甚至可以看到系統(tǒng)啟動(dòng)過(guò)程中實(shí)模式切換到保護(hù)模式的情景:

      (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



      參考文獻(xiàn):
      Bochs的文檔和源碼。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多