For a PC with a Windows NT operating system installed, after you press the power switch First, Bios is run, then MBR, then boot fan, and then NTLDR. Ntoskrnl.exe and Hal. dll is loaded by NTLDR. That is to say, when NTLDR is running, there is no response in the system With a program or driver, of course, there is no software-based debugger available. Of course, omnipotent hardware The debugger is certainly acceptable, but we do not have a hardware debugger.Fortunately, Bochs is available. Bochs is an open-source x86 Virtual Machine Software Based on LGPL. Bochs CPU commands It is completely self-simulated. The disadvantage of this method is that the speed is relatively slow; the advantage is that it has unparalleled scalability. Planting: Bochs can be found in Gcc. There are even Bochs running on PocketPC. Now Bochs has implemented debugging functions to a certain extent, although it is not easy to use and functional Compared with WinDbg and SoftICE, the advantage is also obvious: For the code running in Bochs, this is "Hardware Debugger ". The bochsdbg.exe in the installation directory is the debugging version of Bochs. You can use it to run the Bochs Virtual Machine for "hardware debugging ". Bochs's debugging command style is designed according to GDB's habits, which is unavailable to those who are used to WinDbg. The doubt is painful. Fortunately, this is an open-source software, and you can consider changing it yourself. Currently, the Bochs (Version 2.1.1) supports the following Debugging commands: [Note] 1. There is a large gap between the use instructions in Bochs documents and help information and the actual situation, The following command instructions are supplemented and corrected based on the source code. 2. The involved seg (segment), off (offset), addr (address), val (value), and other numbers, It can be in hexadecimal, decimal, or octal format, but it must be written as follows: Hexadecimal 0xCDEF0123 Octal 01234567 Decimal 123456789 In particular, Bochs cannot automatically recognize hexadecimal numbers and do not accept 12345678h. [Execution control] C | cont is executed downward, which is equivalent to the "g" of WinDBG ". S | step | stepi [count] One-step execution, which is equivalent to "t" of WinDBG. The default count value is 1. P | n | next, which is similar to the "p" of WinDBG ". Q | quit | exit debugging and disable the virtual machine. Ctrl-C: The execution is finished. Return to the debugger prompt. Ctrl-D if at empty line on command line, exit (At least in Windows, I have not found any function of Ctrl-D) [Execution breakpoint] Vb | vbreak [seg: off] breakpoint on the virtual address. Lb | lbreak [addr] breakpoint on a linear address, equivalent to "bp" of WinDBG ". Pb | pbreak | B | break [addr] breakpoint on the physical address. (To be compatible with GDB syntax You can add "*"). Blist displays the breakpoint status, which is equivalent to the "bl" of WinDBG ". Bpd | bpe [num] disable/enable breakpoint, "be" and "bd" of WinDBG ". Num is disconnected Point number, which can be queried using the blist command. D | del | delete [num] delete a breakpoint, which is equivalent to "bc" of WinDBG ". Mum is the Checkpoint number. Use the blist command to query. [Read/write breakpoint] Watch read [addr] sets the read breakpoint. Watch write [addr] sets the write breakpoint. Unwatch read [addr] clears read breakpoints. Unwatch write [addr] clears the write breakpoint. Watch displays all currently read/write breakpoints. Unwatch clears all read/write breakpoints. Watch stop | the continue switch option. It is displayed when the read/write breakpoint is interrupted. Yes. [Memory operations] X/nuf [addr] displays linear address content Xp/nuf [addr] displays the physical address content Number of units displayed by n U indicates the size of each display unit. u can be one of the following: B BYTE H WORD W DWORD G DWORD64 Note: This naming method follows the GDB conventions rather than the inter conventions. F display format. f can be one of the following: X is displayed in hexadecimal format. D decimal display U is displayed in unsigned decimal format. O display by octal T display in binary format C display by character N, f, and u are optional parameters. If not specified, u is w by default, and f is x by default. If you have used x or Is based on the value used by the previous x or xp command. N is 1 by default. Addr is also Optional parameter. If this parameter is not specified, addr is 0. If x or xp commands are used before, n = I is specified, The default n value is I + 1. Setpmem [addr] [size] [val] sets the content of an address in the physical memory. Note that up to one DWORD can be set at a time: This is acceptable: <Bochs: 1> setpmem 0x00000000x4 0x11223344 <Bochs: 2> x/4 0x00000000 [Bochs]: 0x00000000 <bogus + 0>: 0x11223344 0x00000000 0x00000000 0x00000000 You can also: <Bochs: 1> setpmem 0x00000000x2 0x11223344 <Bochs: 2> x/4 0x00000000 [Bochs]: 0x00000000 <bogus + 0>: 0x00003344 0x00000000 0x00000000 0x00000000 Or: <Bochs: 1> setpmem 0x00000000 0x1 0x20 <Bochs: 2> x/4 0x00000000 [Bochs]: 0x00000000 <bogus + 0>: 0x00000020 0x00000000 0x00000000 0x00000000 The following operations may cause errors: <Bochs: 1> setpmem 0x00000000x3 0x112233 Error: setpmem: bad length value = 3 <Bochs: 2> setpmem 0x00000000 0x8 0x11223344 Error: setpmem: bad length value = 8 Crc [start] [end] displays the CRC of data between the physical address start and end. [Register operation] Set $ reg = val to set the register value. Registers that can be set in the current version include: Eax ecx edx ebx esp ebp esi edi You cannot set it for the moment: Eflags cs ss ds es fs gs R | reg | registers reg = val same as above. Dump_cpu displays the complete CPU information. Set_cpu: Set the CPU status, which can be displayed by dump_cpu. All CPU statuses. [Disassembly command] U | disas | disassemble [/num] [start] [end] Disassemble the code between the physical address start and end, as shown in figure If no parameter is specified, the Code pointed to by the current EIP is decompiled. Num is an optional parameter that specifies the amount of code to process. Set $ disassemble_size = 0 | 16 | 32 $ disassemble_size variable specifies the segment used for disassembly Size. Set $ auto_disassemble = 0 | 1 $ auto_disassemble determines When (for example, when a breakpoint or Ctrl-C is encountered), is it reversed? Compile the current command. [Other commands] Trace-on | trace-off Tracing: After the trace-off Tracing switch is enabled, the result of disassembly is returned for every command executed. Displayed. Ptime displays the number of commands executed by Bochs since this operation. Sb [val] is interrupted when the val command is executed again. Val is a 64-bit integer ending with L. For example, "1000L" The execution of sba [val] To Bochs's val command since this run is interrupted. Val is 64-bit integer, ending with L, in the form of "1000L" When modebp is set to switch to v86 mode, it is interrupted. Record ["filename"] records the input Debugging commands to the file. The file name must contain quotation marks. Playback ["filename"] plays back the record file of a record. The file name must contain quotation marks. Print-stack [num]: displays the stack. The default value of num is 16, indicating the number of printed items. ? | "?" Of calc and WinDBG The command is similar to that used to calculate the value of an expression. Load-symbols [global] filename [offset] Load the symbol file. If the "global" keyword is set, the symbolic needle Valid for all contexts. The offset value is added to all symbolds by default. Address. The format of the symbol file is "% x % s ". [Info command] Info program: displays the execution status of the program. Info registers | reg | r displays the register information. Info pb | pbreak | B | break is equivalent to blist Info dirty displays the page address of the dirty page. Info cpu displays the values of all CPU registers. Info fpu displays the values of all FPU registers. Info idt displays IDT. Info gdt [num] displays GDT. Info ldt displays LDT. Info tss display TSS. Info pic displays PIC. Info ivt [num] [num] displays IVT. Info flags display Status Register. Info cr displays CR series registers. The info symbols command displays the information about the symbol. Info ne2k | ne2000 displays the virtual ne2k Nic information. After understanding the debugging command, you can start to debug NTLDR. The following It is implemented on Bochs 2.1.1 for Windows. Let's assume that the reader understands the basic usage of Bochs and Term. First, install a Windows NT 4 Bochs virtual machine. 1. Create a virtual hard disk. Run bximage.exe to create a 500 M, flat mode virtual hard disk file "C. img ". 2. Create an ISO file "NT. iso" for the Windows nt installation disc" You can skip this step if you want to directly install it on a CD. Create bochsrc.txt in 3rd region For details, refer to the following: ######################################## ####################### 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. Create start. bat The content is as follows: :::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::: : Suppose your Bochs are installed on D:/Program/Bochs. Set BXSHARE = D:/Program/Bochs % BXSHARE %/bochs.exe-q-f bochsrc.txt :::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::: Put c.img1_nt.iso1_bochsrc.txt and start. bat in the same directory and run start. bat, Install Windows NT. In fact, if you only want to debug MBR, boot fan, and NTLDR, it is not necessary to install the complete operation. As long as the root directory contains ntldr and other files. The reason why Windows NT is installed Not Windows 2000 or later, on the one hand, it is about speed, on the other hand, Windows NT is The installation can be completed successfully on Bochs. If you want to debug NTLDR for Windows 2000/XP/2003 Replace Windows NT with the ntldr file of these operating systems. After installing Windows NT, You can debug NTLDR. Set "bochs.exe" in start.bat" Replace it with mongobochsdbg.exe ". Then run start. bat. The screen copy operation is as follows: ========================================================== ====================================== Bochs x86 Emulator 2.1.1 February 08,200 4 ========================================================== ====================================== 100000000000i [] reading configuration from bochsrc.txt Extends 000i [] installing win32 module as the Bochs GUI Warning 0000000i [] Warning: no rc file specified. 100000000000i [] using log file nul Next at t = 0 // start bochsdbg.exe and it will automatically stop at the first instruction in Bios. (0) context not implemented because BX_HAVE_HASH_MAP = 0 [0x000ffff0] f000: fff0 (unk. ctxt): jmp f000: e05b; ea5be000f0 <Bochs: 1> B 0x00007c00 // both MBR and guide fan are loaded at 0000: 7c00. <Bochs: 2> c (0) Breakpoint 1, 0x7c00 in ?? () // The MBR will be interrupted for the first time. Next at t = 772567 (0) [0x00007c00] 0000: 7c00 (unk. ctxt): cli; fa <Bochs: 3> c (0) Breakpoint 1, 0x7c00 in ?? () // The second operation will be interrupted on the guide fan. Next at t = 773872 (0) [0x2137c00] 0000: 7c00 (unk. ctxt): jmp 0x7c5d; eb5b <Bochs: 4> B 0x00020000 // ntldr is loaded at. In fact, whether it is CDFS, NTFS, or FAT, // This address is used to load the Startup File in Windows. <Bochs: 5> c (0) Breakpoint 2, 0x20000 in ?? () // The NTLDR command is disconnected. You can start debugging. Next at t = 861712 (0) [0x00020000] 2000:0000 (unk. ctxt): jmp 0x1f6; e9f301 Now, we can watch the operating system start up step by step, just as God looks at all beings. You can even see the scenario where the real mode switches to the protection mode during system startup: (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 |