Jump to content











Photo

Debugging NTLDR


  • Please log in to reply
8 replies to this topic

#1 Sha0

Sha0

    WinVBlock Dev

  • Developer
  • 1682 posts
  • Location:reboot.pro Forums
  • Interests:Booting
  •  
    Canada

Posted 30 November 2010 - 06:20 PM

One can attempt to gain an understanding of Microsoft Windows XP's and 2003's NTLDR startup processes by using Microsoft's WinDbg. In order to do this, one needs the checked build of NTLDR[2]. This is a Windows component and as such, its use is subject to the terms of Microsoft's end-user licensing terms. If you do not agree to those terms, there are lots of other interesting things to do other than debugging NTLDR.

You will need:
  • A hex-editor, such as TinyHexer.
  • The checked build of NTLDR, from Microsoft.
  • The Windows Debugger (WinDbg), from Microsoft.
  • The QEmu virtual machine software[4].
  • An HDD image file suitable for use with QEmu, with at least a licensed set of files for XP/2003. This set can be pretty minimal if you are not interested in debugging past where the kernel begins to run. A minimal set might be something like:

  • \NTLDR
  • \NTDETECT.COM
  • \BOOT.INI
  • \Windows\System32\NTOSKrnl.exe
  • \Windows\System32\HAL.DLL
  • \Windows\System32\BootVID.DLL
  • \Windows\System32\KDCOM.DLL
  • \Windows\System32\Config\SYSTEM

BOOT.INI should contain:
[boot loader]

timeout=10

default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS



[debug]

/debug /debugport=COM1 /baudrate=115200 /debugstop



[operating systems]

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="UP HALACPI" /noexecute=optin /fastdetect /sos
You need to use your hex-editor to search NTLDR for the MZ signature, then copy everything from the MZ onward and save that file as OSLoader.exe on your host system.

Assuming your disk image is called TEST.HDD and it is in the current working directory, launch QEmu with:
qemu -hda test.hdd -serial pipe:com_1
Maybe your HDD image doesn't boot. You might need GRUB4DOS's GRUB.EXE and something like:
qemu -kernel grub.exe -append "--config-file=root (hd0,0); chainloader /ntldr" -hda test.hdd -serial pipe:com_1
QEmu should launch and freeze, awaiting a connection from WinDbg. So launch WinDbg with:
"C:\Program Files\Debugging Tools for Windows\windbg.exe" -k com:pipe,port=\\.\pipe\com_1,baud=115200,resets=0,reconnect -b
Assuming a temporary directory of C:\TMP\, configure WinDbg with a symbol path like:
srv*c:\tmp*http://msdl.microsoft.com/download/symbols
Once NTLDR runs inside the QEmu VM, it should show something like:

Boot Debugger Using: COM1 (Baud Rate 115200)

And WinDbg should attach and show:

Microsoft ® Windows Debugger Version 6.7.0005.0
Copyright © Microsoft Corporation. All rights reserved.

Opened \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows Boot Debugger 2600 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established. (Initial Breakpoint requested)
Symbol search path is: srv*c:\tmp*http://msdl.microsoft.com/download/symbols
Executable search path is:
Module List address is NULL - debugger not initialized properly.
WARNING: .reload failed, module list may be incomplete
KdDebuggerData.KernBase < SystemRangeStart
Windows Boot Debugger Kernel Version 2600 UP Checked x86 compatible
Primary image base = 0x00000000 Loaded module list = 0x00000000
System Uptime: not available
The call to LoadLibrary(bootext) failed, Win32 error 0n2
"The system cannot find the file specified."
Please check your debugger configuration and/or network access.
Break instruction exception - code 80000003 (first chance)
0041ee8c cc int 3

Now you must establish the symbols for NTLDR. Assuming you saved OSLOADER.EXE to the current directory, in WinDbg, do:
.readmem osloader.exe 0x400000 L0x1000

.imgscan /l /r 00400000

MZ at 00400000 - size 81000
Name: osloader.EXE
Loaded osloader.EXE module

Let's have a look at NTLDR symbols:
x osloader!
How about a look at symbols for dealing with the SYSTEM Registry hive:
x osloader!*system*
Ooh, look. There's one called BlLoadAndScanSystemHive. Let's set a break-point:
bp osloader!BlLoadAndScanSystemHive
Now let's let NTLDR execute.
g
Thanks to the /SOS switch in BOOT.INI, QEmu yields:

multi(0)disk(0)rdisk(0)partition(1)\WINDOWS\system32\NTOSKRNL.EXE
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS\system32\HAL.DLL
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS\system32\KDCOM.DLL
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS\system32\BOOTVID.DLL

Control is returned to WinDbg right when the SYSTEM hive would be loaded. Yay.

- Sha0

[1] Courtesy of Anand Choubey Re: Debug version of ntldr for Windows XP SP3
[2] Courtesy of Microsoft: Windows XP Service Pack 3, Checked Build
[3] Courtesy of Samuel Bronson: Undocumented [debug] section in boot.ini enables boot debugger
[4] Courtesy of Toshiya Takeda: QEMU on Windows

#2 homes32

homes32

    Gold Member

  • .script developer
  • 1035 posts
  • Location:Minnesota
  •  
    United States

Posted 30 November 2010 - 07:16 PM

cool. using qemu with a serial pipe is an interesting way of doing that.

can you also give an example on how this would be useful to people that read your tutorial?

-Homes32

#3 Sha0

Sha0

    WinVBlock Dev

  • Developer
  • 1682 posts
  • Location:reboot.pro Forums
  • Interests:Booting
  •  
    Canada

Posted 30 November 2010 - 07:26 PM

Sorry, there's no use. It's just for fun and to show your pals, "Look what I can do!"
Suppose we wish to see which keys are accessed while the SYSTEM hive is loaded and scanned by NTLDR.
bp osloader!CmpFindSubKeyByName

g
Once the break-point is hit, have a look at ESP+0xC.
d esp+0xc

AAAAAAAA WW XX YY ZZ ...

The first four bytes of data there are a pointer. Reverse those bytes and have a look at the pointed-to data, perhaps a UNICODE_STRING.
d ZZYYXXWW

ZZYYXXWW 0a 00 0c 00 BB CC DD EE-...

The BBCCDDEE bytes are a pointer, too. Take a look:
d EEDDCCBB

EEDDCCBB 53 00 65 00 74 00 75 00-70 00 00 00 41 00 75 00 S.e.t.u.p...A.u.

Hmmm... Interesting. Let's try again with g.

Breakpoint 1 hit
osloader!CmpFindSubKeyByName:
...

d esp+0xc

AAAAAAAA WW XX YY ZZ ...

d ZZYYXXWW

ZZYYXXWW 0c 00 0e 00 BB CC DD EE-...

d EEDDCCBB

EEDDCCBB 73 00 65 00 6c 00 65 00-63 00 74 00 00 00 00 00 s.e.l.e.c.t.....

And again...:

AAAAAAAA 73 00 65 00 6c 00 65 00-63 00 74 00 00 00 00 00 s.e.l.e.c.t.....

And again...:

AAAAAAAA 43 00 6f 00 6e 00 74 00-72 00 6f 00 6c 00 53 00 C.o.n.t.r.o.l.S.
AAAAAAAA 65 00 74 00 30 00 30 00-31 00 00 00 10 00 01 00 e.t.0.0.1.......

And again...:

AAAAAAAA 43 00 6f 00 6e 00 74 00-72 00 6f 00 6c 00 00 00 C.o.n.t.r.o.l...

Again again...

AAAAAAAA 49 00 44 00 43 00 6f 00-6e 00 66 00 69 00 67 00 I.D.C.o.n.f.i.g.
AAAAAAAA 44 00 42 00 00 00 00 00-55 00 73 00 65 00 72 00 D.B.

Perhaps you get the idea. :)

#4 Sha0

Sha0

    WinVBlock Dev

  • Developer
  • 1682 posts
  • Location:reboot.pro Forums
  • Interests:Booting
  •  
    Canada

Posted 30 November 2010 - 11:02 PM

On the other hand, homes32, maybe the edit for the last post is better. :)

Ever wonder why SETUPREG.HIV cannot be used as the SYSTEM hive? Because it's missing:
  • \ControlSet001\Control\NLS\
  • \ControlSet001\Control\ProductOptions\
  • \Setup\
Remember that the Setup\ key is tied to your license for XP/2003. You can't have one without a license.

#5 joakim

joakim

    Silver Member

  • Team Reboot
  • 912 posts
  • Location:Bergen
  •  
    Norway

Posted 09 April 2011 - 10:06 PM

There's definetely much interesting to observe by debugging ntldr/bootmgr. However, using windbg for it will put restriction on how "early" you can start the debugging session. Obviously it cannot occur before boot.ini/BCD is fully loaded. To overcome this issue we must use BOCHS, debugging in disk image mode. This way we can debug everything from the start of MBR. Handy if you want to debug the bootsector, the 16-bit stub of ntldr/bootmgr or early initialization of ntldr/bootmgr.

For MBR put a brakpoint like;

b 0x7c00


For the 16-bit stub put a breakpoint like;

b 0x00020000


For the initialization of the 32-bit exe put a breakpoint like;

b 0x401000


Keep in mind that BOCHS is command line and thus slightly more challenging to cooperate with..

Reading memory can for instance be done by;

x /100 eax

or

x edi+4


This is how I figured out how to create a bootmgr with the BCD store embedded inside it!!

For instance you can also safely chainload the Stoned bootkit and debug it this way..

Note, using the BOCHS plugin in IDA seems like disaster as it will crash or hang completely.

Joakim Schicht

#6 Icecube

Icecube

    Gold Member

  • Team Reboot
  • 1063 posts
  •  
    Belgium

Posted 09 April 2011 - 10:39 PM

@ joakim
Maybe the following PDF can help:
http://www.hex-rays....er/gdb_qemu.pdf

Basically: qemu + GDB + IDA

#7 joakim

joakim

    Silver Member

  • Team Reboot
  • 912 posts
  • Location:Bergen
  •  
    Norway

Posted 10 April 2011 - 08:12 AM

@ joakim
Maybe the following PDF can help:
http://www.hex-rays....er/gdb_qemu.pdf

Basically: qemu + GDB + IDA


That is brilliant. I just tried that combination for the first time and it's really nice. No crashes and no hanging. Thanks a lot. And the pdf document was very helpful too.

I guess I'm not gonna struggle with command line in Bochs anylonger now.

#8 joakim

joakim

    Silver Member

  • Team Reboot
  • 912 posts
  • Location:Bergen
  •  
    Norway

Posted 10 April 2011 - 07:48 PM

@Icecube
It also seem to work equally well in VMware-IDA (possibly version dependent though) by adding this to your vmx;

debugStub.listen.guest32 = "TRUE"

debugStub.hideBreakpoints = "TRUE"

monitor.debugOnStartGuest32 = "TRUE"

and connecting on port 8832.

Do you have any experience in what way works best? Is there a preferred way of debugging (from IDA) before protected mode has started?

#9 Icecube

Icecube

    Gold Member

  • Team Reboot
  • 1063 posts
  •  
    Belgium

Posted 10 April 2011 - 08:16 PM

Do you have any experience in what way works best? Is there a preferred way of debugging (from IDA) before protected mode has started?

I don't have any experience at all. I found the PDF by entering good keywords in google.




2 user(s) are reading this topic

0 members, 2 guests, 0 anonymous users