Sponsoring website: Emergency Boot CD


The "Bootstrap" Code  or
NTLDR Loader Code  of an
NTFS OS Partition [ For Microsoft®
Windows™ 2000 (SP4; NT5.0) or
Windows™ XP (SP2 or SP3; NT5.1) ]


Web Presentation and Text are Copyright © 2004, 2007, 2009, 2015 by Daniel B. Sedory
NOT to be reproduced in any form without Permission of the Author !

You can contact us here if you have any specific questions about this page.

 




Introduction

This page examines the second and following sectors of the NTFS Boot Record Code for Windows 2000 (NT5.0) and Windows™ XP (NT5.1) or later. One Microsoft® web page refers to these sectors as the “bootstrap code” for an NTFS partition (see reference here). We're calling these sectors the NTLDR Loader section of the NTFS Boot Record. This section is actually the bulk of the whole Boot Record Area and after it loads the ntldr program is what makes NTFS volumes so flexible in the available booting options. Our objectives here are to identify the purpose of the bytes in the Data Area (or as many as we can) and the function of the major blocks of code, such as subroutines; not to cover every instruction in these six sectors of code.
NOTE: From numerous observations, it appears that all NTFS Boot Records begin with identical bytes in the "NTLDR Data Area" as we're calling it (see below for more info).

After the MBR loads the NTFS “boot sector” into Memory at location 0000:7C00, it eventually loads another copy of itself directly from the hard drive into Memory location 0D00:0000 (or 0000:D000) and continues loading all of the other 15 sectors of the Boot Record Area immediately after that. So our Examination of the Code below will be done as if it were already loaded into Memory at 0D20:0000 (or 0000:D200 or Linear 0xD200) and following since that's where the code is actually located when it's executed.

[Note: In order to properly understand this code, one should use an updated debugger, such as Enhanced DEBUG on this page by Vernon C. Brooks (current version, since DEC 2014, is 1.30b); which is also a 32-bit debugger! Or, even set up the BOCHS GUI Debugger with a nice visual display, to step through this code, rather than attempting to rely solely on the old 16-bit MS-DOS DEBUG program. Another very good program for disassembling all of this code very quickly would be the free version of IDA Pro (v 5.0) which we mentioned on our "Assembly Language 101" page; include the VBR Boot Sector, set Segment to: D00, use 16-bit disassembly and begin decoding at first byte of the Boot Sector. "c" must be pressed again at offset 26A (0D00:026A).]

Take this link, to see: How the first and last sectors of the “bootstrap code” appear in a disk editor, or see:
How the entire VBR Area appears in a Disk Editor.

 



The “Data Area” at the beginning of the
NTLDR Loader's (“Bootstrap”) Code

Hex Dump of the "NTLDR Loader Data Area":

 Absolute Sector 64 (Cylinder 0, Head 1, Sector 2) or 
 Relative Sector  1 (Cylinder x, Head 1, Sector 2)

  Off.   0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

 0200:  05 00 4E 00 54 00 4C 00 44 00 52 00 04 00 24 00  ..N.T.L.D.R...$.
 0210:  49 00 33 00 30 00 00 E0 00 00 00 30 00 00 00 00  I.3.0......0....
 0220:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 0230:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 0240:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
 0250:  00 00 00 00 00 00 EB 12 90 90 00 00 00 00 00 00  ................
 0260:  00 00 00 00 00 00 00 00 00 00                    ..........

After searching through the code below, we were able to establish that all of the underlined 4-byte buffer or intermediate storage locations shown in the Data Area above are used by this code (links are to the secton of code below where each Double Word first occurs or is computed, followed by the location of each instruction using this value; we have also included a sample value for each one, so you will have an example of the relationships between them):

[024E] Bytes per Cluster (often 1000h = 4096 or eight 512-byte sectors); (D287, D2A5, D5AD, D9EA). Example / Sample:
            Bytes per Cluster = 0x1000 (4096).
[0252] Bytes per File Record Segment (or Bytes per FRS); (D2AC, D2CD, D2D7, D2E1, D2EB, D746, D74F, D8E2). Sample:
            Bytes per FRS = 0x0400 (1024).
[0256] Sectors per File Record Segment (or Sectors per FRS); (D2BC, D774, D7E1, D800, D8F2, DA05, DA0A).
            Note: The data you currently see at 0256 ("EB 12 90 90") is overwritten by the instruction at D2BC. Sample:
            Sectors per FRS = 0x0002.
[021E] Only used to store 0x00000001 (D73E, D8B5, D8D8); why couldn't this have been preset in Data Area?
[021A] Contains preset value of: 0x3000 (12,288); (D742, D786, D796).
[025A] Bytes per FRS + 3000h; (D74B, D8DD, D8ED, D91E, D928). Sample:
            BpFRS + 3000h = 0x3400 (13,312).
[024A] (2 x Bytes per FRS) + 3000h or: [(2 x BpFRS) + 3000h]; (D2C3, D754, D765). Sample:
            (2 x BpFRS) + 3000h = 0x3800 (14,336).
            However, due to BX being incremented by 4 at both D771 and D77E, [024A] results in being incremented by 8 at:
            D781 (and D813, D865 as well), so here [024A] = (2 x BpFRS) + 3000h + 8 = 0x3808 (14,344).

[0216] Contains preset value of: 0xE000 (57,344); (D7BB, D7C6, DD04, DD11).

[0200] Contains upper-case Unicode string for "NTLDR", (D3AC).
[020C] Contains upper-case Unicode string for "$I30", (DC9A, DCCF).

[0222] (D2C8, D2FB), .
[0226] (D2D2, D314, DA2E), .
[022A] (D2DC, D326, D3A5), .
[022E] (D30A, D332, DBC0), .
[0232] (D31C, D385, DA24, DBE4, DBF7), .
[0236] (D32E, D38F, D399), .
[023A] (D2E6, D3C8, D3D0, D3F0, D41C, D42C, D434, D46F), .
We did not find any reference to: [023E]).
[0242] (D2F0, D378, DA35, DC40), .
[0246] (D381, D3A0, DA4C), .
[025E] (D35F, D364, D37C, DC09), .
[0262] (D355, DA1F, DA29), .
and [0266] (D374). Curiously, there is only one instance of [0266] in this code, so it may possibly be used later by the ntldr program.

From the instruction at offset D2BC below, we know the bytes at offsets 0056 through 0059 of this Data Area ("EB 12 90 90") are never executed, since these same bytes after being loaded into Memory are overwritten by that instruction to store some data from EAX after a division operation! Furthermore, after examining many other NTFS partitions, we have always found the same exact bytes in this "Data Area" location on every disk. Our Conclusion: This area is never changed on any hard drive, but it is used to store data after being copied into Memory. However, it is a fact that if code execution was ever passed to Memory location 0000:D256 before being overwritten, the "EB 12" would jump to location 0000:D26A; where this NTLDR Loader code currently begins. So, for whatever reason, we can't help but assume some programmer chose these bytes for that purpose, even though they appear to no longer be used (unless someone can find a Boot Sector that still has the location 0xD256 coded into it?).

 


An Examination of the Code

This is a disassembled copy of the code (; with comments) after being loaded into memory by the NTFS Boot Sector; which first reloads itself at location 0D00:0000 and following, with the NTLDR "Bootstrap" sectors at locations 0D00:0200 (or 0000:D200) and following, then it transfers execution to location 0000:D26A (or simply Linear address 0xD26A as we'll refer to it below — without the 0000: segment prefix):

; =================   S T A R T    O F    M A I N    C O D E   P A T H    =====================================================

D26A 8CC8         MOV     AX,CS      ; AX = CS (Code Segment) = 0D00.
D26C 8ED8         MOV     DS,AX      ; Make DS (Data Segment) = 0D00.
                                     ; (Once again, 0D00:026A = 0000:D26A)
D26E C1E004       SHL     AX,04      ; That's 4 bits, so 0D00 -> D000.
D271 FA           CLI                ; Disable maskable Interrupts.
D272 8BE0         MOV     SP,AX      ; Stack Pointer = 0000:D000 since the
                                     ; Stack Segment (SS) is still 0000.
D274 FB           STI                ; Enable Interrupts again.
D275 E803FE       CALL    D07B       ; Now we see why the Boot Sector reloaded
                                     ; itself into Memory: So part of its code
                                     ;  could be used again by the "Bootstrap
                                     ;  Code"! So calculate Total Sectors on
                                     ;  Disk Drive again! Of course, if there
                                     ;  are more than 00FB0400h (16,450,560)
                                     ;  sectors, it fails to get actual total.
                                     ;  Listing of this Boot Sector subroutine
                                     ;  in its new location:

; Subroutine to Calculate Total Sectors on
; the Disk Drive (using only CHS) values
; from BIOS Interrupt 13 H, Function 08 H
D07B 8A162400      MOV     DL,[0024]    ; -> 80h (which is the First HDD)
                                        ; See BPB chart for Offset 24h.
D07F B408          MOV     AH,08        ; Function 08h of INT 13 
D081 CD13          INT     13           ; "Get Drive Parameters"

;            After executing INT 13 Function 08h:
;             AH = 00h and CF is cleared (set to 0) if successful.
; +-------------------------------------------------------+
; |           CH =  Low 8 bits of Maximum Cylinder Number |
; |CL (bits 7-6) = High 2 bits of    "       "       "    |
; +-------------------------------------------------------+ 
;  CL (bits 5-0) = Maximum Sector Number.
;             DH = Maximum   Head Number.
;             DL = Number of drives on the system.

D083 7305          JNB     D08A    ; Jump if successful, CF=0 (NoCarry)

D085 B9FFFF        MOV     CX,FFFF ; Otherwise: Set CX = FFFFh and
D088 8AF1          MOV     DH,CL   ;                DH = FFh which will
                                   ;   result in a count of 00FC0000h or
                                   ; 16,515,072 sectors being placed into
                                   ; [0000:7C20] and following.

D08A 660FB6C6    * movzx   eax,dh  ; Move with Zero Extend DH -> EAX
D08E 40            INC     AX      ; Maximum Head number + 1 = Total Heads
                                   ; (Desktop drives > 8 GB are almost always
                                   ;    FE h + 1 = FF h; or 255 Heads).

D08F 660FB6D1    * movzx   edx,cl  ; CL = Maximum Sector number (bits 5-0)
D093 80E23F        AND     DL,3F   ; To pick up only bits 5 through 0
                                   ; (Desktop drives > 8 GB almost always
                                   ;    have 3F h = 63 Sectors per Head).

D096 F7E2          MUL     AX,DX   ;   and multiply by the number of Heads:
                                   ; EAX now equals (Sectors x Heads) ->
                                   ;  3F h x FF h = 3EC1 h = (63 x 255) 
                                   ; (so often 16,065 for Desktop drives).

D098 86CD          XCHG    CL,CH   ; Put the low bits of Maximum Cylinder
                                   ; Number at the end of the CX register,
D09A C0ED06      * shr     ch,06   ; and shift bits 7-6 of CL next to them
                                   ; so that CX now equals Max Cyl number!
D09D 41            INC     CX      ;     CX + 1 = Total Cylinders
                                   ; (Desktop drives > 8 GB are almost always
                                   ;  3FF h + 1 = 400 h; or 1024 Cylinders).

D09E 660FB7C9    * movzx   ecx,cx  ; Move with Zero Extend CX -> ECX
D0A2 66F7E1      * mul     eax,ecx ;   so we multiply all three together:
                                   ; EAX = [Sectors * Heads] * Cylinders
                                   ;     = Total Number of Sectors; but this
                                   ; should only be true for drives having
                                   ; 1024 or less cylinders!

D0A5 66A32000    * mov     [0020],eax  ; Store Total Number of Sectors for
                                       ; Disk in [0000:D020] (4-byte Word).
D0A9 C3            RET             ; to D278.

; NOTE: A 4-byte Word for Total Sectors allows for almost 2048 Binary GB! 
;        ( FFFFFFFFh = 4,294,967,295 sectors = 2,199,023,255,040 bytes! )
; However, this subroutine can return a Maximum of only about 8.45 GB; if
; there's an error in determining the Sector Count; i.e., if the INT 13h
; "Get Drive Parameters" fails, this subroutine will return a count of:
; 63 * 256 * 1024 = 16,515,072 sectors (8455716864 bytes); which is not
; really possible using only CHS notation and standard BIOS functions.
; (See our Disk Terms page for a reality note about a 'bug' in MS-DOS!)
; [ 63 sectors * 255 heads * 1024 cylinders (2 + 8 = 10 bits -> 3FFh) =
; 16,450,560 sectors = 8,422,686,720 bytes (or only about 7.8 Binary GB)].

; NOTE: When we tested the code above using an 8.0 GiB Bochs image file,
; which is > FC0000h sectors; in fact, FFFFC0 (16,777,152) sectors, the
; Bochs BIOS function returned the expected result of: 16,450,560 (or:
; 0xFB0400) sectors; actual CAPACITY must be determined by other means.

;          C O N T I N U A T I O N    O F    M A I N    C O D E    P A T H
; ====================================================================================
; Computation of Bytes per Cluster :

D278 660FB7060B00    MOVZX   EAX,WORD PTR [000B]  ; Sector Size in (hex) bytes 
                                                  ; from the BPB.  (Example:
                                                  ; 200h = 512 bytes/sector.)
D27E 660FB61E0D00    MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster from BPB.

D284 66F7E3          MUL     EAX,EBX          ; So, EAX will = Bytes per Cluster 
D287 66A34E02        MOV     [024E],EAX       ;     Store in --> [0xD24E]

; ====================================================================================
; Computation of Bytes per File Record Segment (Bytes per FRS)
; (This code also shows how a -10 in 0xD040 turns into 1024 bytes per FRS):

D28B 668B0E4000      MOV     ECX,[0040]   ; [ Clusters per File Record Segment ]
D290 80F900          CMP     CL,00        ; Normally CL is F6h (-10 as signed-byte).
D293 0F8F0E00        JG      D2A5         ; If > 0, go to D2A5. But in most cases it
                                          ;   will be negative (Less Than Zero),...
D297 F6D9            NEG     CL           ;   So, Negation of F6(-10) = 0A (or +10).
D299 66B801000000    MOV     EAX,00000001 ;|  Put a 1 in EAX
D29F 66D3E0          SHL     EAX,CL       ;| Shift Left 1 by 10 bits = 400h = 1024
D2A2 EB08            JMP     D2AC         ;| So, default value is 1,024 bytes.
D2A4 90              NOP
D2A5 66A14E02        MOV     EAX,[024E]   ; Multiply Bytes per Cluster by
D2A9 66F7E1          MUL     EAX,ECX      ;   Clusters per File Record Segment =
                                          ;   Bytes per File Record Segment!
D2AC 66A35202        MOV     [0252],EAX   ;| Store BpFRS in --> [0xD252].

; ====================================================================================
; Computation of Sectors per File Record Segment :

D2B0 660FB71E0B00    MOVZX   EBX,WORD PTR [000B] ; Put Bytes per Sector in EBX...
D2B6 6633D2          XOR     EDX,EDX             ; EDX = 0.
D2B9 66F7F3          DIV     EAX,EBX      ; Divide BpFRS (still in EAX) by Bytes
                                          ;  per Sector, so EAX will become:
                                          ;  Sectors per File Record Segment 
                                          ; (If BpFRS is 1024, we would get 2 here.)
D2BC 66A35602        MOV     [0256],EAX   ; Store it in [D256].
                                          ; (Note: "EB 12 90 90" in Memory will
                                          ;   be replaced by whatever is in EAX.)

; D2C0 E80D04        CALL    D6D0         ; Old XP SP1 Call Location
; Windows 2000(SP4) and Windows XP(SP2) changed location of this subroutine!
; This line is now:
D2C0 E87104          CALL    D734         ; XP SP2 (or later) Call Location

D2C3 668B0E4A02      MOV     ECX,[024A]
D2C8 66890E2202      MOV     [0222],ECX    ; Store it in [D222].
D2CD 66030E5202      ADD     ECX,[0252]    ; Bytes per FRS
D2D2 66890E2602      MOV     [0226],ECX    ; Store it in [D226].
D2D7 66030E5202      ADD     ECX,[0252]    ; Bytes per FRS
D2DC 66890E2A02      MOV     [022A],ECX    ; Store it in [D22A].
D2E1 66030E5202      ADD     ECX,[0252]    ; Bytes per FRS
D2E6 66890E3A02      MOV     [023A],ECX    ; Store it in [D23A].
D2EB 66030E5202      ADD     ECX,[0252]    ; Bytes per FRS
D2F0 66890E4202      MOV     [0242],ECX    ; Store it in [D242].
D2F5 66B890000000    MOV     EAX,00000090  ; Put 0x90 (144) into EAX.
D2FB 668B0E2202      MOV     ECX,[0222]

; D300 E8EC08        CALL    DBEF       ; Old XP SP1 Call Location
; Windows 2000(SP4) and Windows XP(SP2) made changes to this code!
; This line is now:
D300 E85F09          CALL    DC62       ; XP SP2 (or later) Call Location

D303 660BC0          OR      EAX,EAX
D306 0F8457FE        JZ      D161      ; Another use of code from the
                                        ;  Boot Sector... in this case,
                                        ;  to display error messages!

; We'll call this the Black-Hole Subroutine, since there
; is no escape from it! If execution ends up here, your
; PC will lock-up after displaying an error message!
; ====================================== S U B R O U T I N E =============================================

D161 A0F801        MOV     AL,[01F8]  ; Contains 83h (Pointer value for
                                      ; all Languages to Message Area.)
                                      ; -> "A disk read error occurred"
D164 E80900        CALL    D170       ; DISPLAY MESSAGE
D167 A0FB01        MOV     AL,[01FB]  ; Contains C9h (for English string).
                                      ; -> "Press Ctrl+Alt+Del to restart"

D16A E80300        CALL    D170       ; DISPLAY MESSAGE
D16D FB            STI
D16E EBFE          JMP     D16E       ; Endless Loop -> Lock-up System,
                                      ;   so a reboot is necessary!

; ------------------------------ SUBROUTINE --------------------------------------------
;     INT 10, Function 0Eh (Teletype Output) is used to display each
; character of the error messages.

D170 B401          MOV     AH,01       ; A different method for add 100h to
                                       ; the offsets arlready in the AL register to Messages 
D172 8BF0          MOV     SI,AX       ; Offsets in AX -> Error Messages.
D174 AC            LODSB               ; Load Error Message strings 1 byte
                                       ;    at a time and INC SI pointer.
D175 3C00          CMP     AL,00       ; Look for Zero-byte terminator in
                                       ;    the Error Message strings.
D177 7409          JZ      7D82        ; Return (done)
D179 B40E          MOV     AH,0E       ; Function 0Eh of INT 10:
                                       ; "Teletype Output" (One Character)
D17B BB0700        MOV     BX,0007    ;| (BH = Display page 0,  BL = 07 is
                                      ;|  normal White on Black characters.)
D17E CD10          INT     10
7D80 EBF2          JMP D174            ; Do it all over again . . .
7D82 C3            RET

; ============================ E N D   O F   S U B R O U T I N E =========================================


D30A 66A32E02     MOV     [022E],EAX    ; Store it in [D22E].
D30E 66B8A00000   MOV     EAX,000000A0
     00
D314 668B0E2602   MOV     ECX,[0226]

; D319 E8D308     CALL    DBEF		; Old XP SP1 Call Location
; Windows 2000(SP4) and Windows XP(SP2) made changes to this code!
; This line is now:
D319 E84609       CALL    DC62		; XP SP2 (or later) Call Location

D31C 66A33202     MOV     [0232],EAX    ; Store it in [D232].
D320 66B8B00000   MOV     EAX,000000B0
     00
D326 668B0E2A02   MOV     ECX,[022A]
; D32B E8C108     CALL    DBEF		; Old XP SP1 Call Location
; Windows 2000(SP4) and Windows XP(SP2) made changes to this code!
; This line is now:
D32B E83409       CALL    DC62		; XP SP2 (or later) Call Location
This page is still under construction ...

But to give you an idea of how tedious this work would be to complete, here are all the rest of the uncommented lines of code (which still require hundreds or more man hours to analyze) from the NTLDR section we began above:

D32E 66A33602      MOV     [0236],EAX
D332 66A12E02      MOV     EAX,[022E]
D336 660BC0        OR      EAX,EAX
D339 0F8424FE      JZ      D161

D33D 6780780800    CMP     BYTE PTR [EAX+08],00
D342 0F851BFE      JNZ     D161

D346 67668D5010    LEA     EDX,[EAX+10]
D34B 67034204      ADD     AX,[EDX+04]
D34F 67660FB6480C  MOVZX   ECX,BYTE PTR [EAX+0C]
D355 66890E6202    MOV     [0262],ECX
D35A 67668B4808    MOV     ECX,[EAX+08]
D35F 66890E5E02    MOV     [025E],ECX
D364 66A15E02      MOV     EAX,[025E]
D368 660FB70E0B00  MOVZX   ECX,WORD PTR [000B]
D36E 6633D2        XOR     EDX,EDX
D371 66F7F1        DIV     ECX
D374 66A36602      MOV     [0266],EAX
D378 66A14202      MOV     EAX,[0242]
D37C 6603065E02    ADD     EAX,[025E]
D381 66A34602      MOV     [0246],EAX
D385 66833E320200  CMP     DWORD PTR [0232],+00

; D38B 0F841900    JZ      D3A8		; Old XP SP1 JZ address
; Windows 2000(SP4) and Windows XP(SP2) made changes to this code!
; This line is now:
D38B 0F841D00      JZ      D3AC		; XP SP2 (or later) JZ address


D38F 66833E360200  CMP     DWORD PTR [0236],+00
D395 0F84C8FD      JZ      D161

D399 668B1E3602    MOV     EBX,[0236]
D39E 1E            PUSH    DS
D39F 07            POP     ES
D3A0 668B3E4602    MOV     EDI,[0246]

; The new Win 2000(SP4)/XP(SP2) code added this instruction:
D3A5 66A12A02      MOV     EAX,[022A]


; And this Call address had to be changed as well:
D3A9 E8BC01        CALL    D568


D3AC 660FB70E0002  MOVZX   ECX,WORD PTR [0200]    ; "NTLDR" in Unicode.
D3B2 66B802020000  MOV     EAX,00000202
D3B8 E8FE07        CALL    DBB9          ; Another address change.


D3BB 660BC0        OR      EAX,EAX
D3BE 0F84A809      JZ      DD6A    ; All jump addresses like this
				; one will be different now since
				; new code lines were added above.
				
D3C2 67668B00      MOV     EAX,[EAX]
D3C6 1E            PUSH    DS
D3C7 07            POP     ES
D3C8 668B3E3A02    MOV     EDI,[023A]
D3CD E83106        CALL    DA01


D3D0 66A13A02      MOV     EAX,[023A]

; This new code has a different value than the old version!  Prior
; to the Windows XP (SP2) code, an "80" was placed into "EBX":
D3D4 66BB20000000  MOV     EBX,00000020

D3DA 66B900000000  MOV     ECX,00000000
D3E0 66BA00000000  MOV     EDX,00000000
D3E6 E8D600        CALL    D4BF

; Here they decided to use a "TEST" instead of "OR" instruction:
D3E9 6685C0        TEST    EAX,EAX
D3EC 0F852300      JNZ     D413
; And a line of code was deleted from the old version here.
D3F0 66A13A02      MOV     EAX,[023A]

; A number of lines of code were shuffled around here, so
; no more comments will be provided on all the details!
D3F4 66BB80000000  MOV     EBX,00000080
D3FA 66B900000000  MOV     ECX,00000000
D400 66BA00000000  MOV     EDX,00000000
D406 E8B600        CALL    D4BF

D409 660BC0        OR      EAX,EAX
D40C 0F854400      JNZ     D454
D410 E95709        JMP     DD6A   ; ERROR!

D413 6633D2        XOR     EDX,EDX
D416 66B980000000  MOV     ECX,00000080
D41C 66A13A02      MOV     EAX,[023A]
D420 E8BC08        CALL    DCDF

D423 660BC0        OR      EAX,EAX
D426 0F844009      JZ      DD6A   ; ERROR!
D42A 1E            PUSH    DS
D42B 07            POP     ES
D42C 668B3E3A02    MOV     EDI,[023A]
D431 E8CD05        CALL    DA01

D434 66A13A02      MOV     EAX,[023A]
D438 66BB80000000  MOV     EBX,00000080
D43E 66B900000000  MOV     ECX,00000000
D444 66BA00000000  MOV     EDX,00000000
D44A E87200        CALL    D4BF

D44D 660BC0        OR      EAX,EAX
D450 0F841609      JZ      DD6A   ; ERROR!
D454 67660FB7580C  MOVZX   EBX,WORD PTR [EAX+0C]
D45A 6681E3FF0000+ AND     EBX,000000FF
D461 0F850B09      JNZ     DD70   ; ERROR!
D465 668BD8        MOV     EBX,EAX
D468 680020        PUSH    2000
D46B 07            POP     ES
D46C 662BFF        SUB     EDI,EDI
D46F 66A13A02      MOV     EAX,[023A]
D473 E8F200        CALL    D568
; Exit Point to ntldr program at Linear offset 0x20000:
D476 8A162400      MOV     DL,[0024]  ; Drive Number - usually 80h (1st drive)
D47A B8E803        MOV     AX,03E8    ; 0x03E8 -> AX
D47D 8EC0          MOV     ES,AX      ; ES (Extra Segment) = 0x3E8
D47F 8D360B00      LEA     SI,[000B]  ; Bytes per Sector 
D483 2BC0          SUB     AX,AX      ; Zero-out AX (like: "XOR AX,AX")
D485 680020        PUSH    2000       ; 
D488 50            PUSH    AX         ; 
D489 CB            RETF               ; Jump to ntldr program file in
                                      ; Memory at Linear offset 0x20000

; ========================================    E N D    O F    M A I N    C O D E   ============================================


; ----------------------------------------------------------
; This Routine and all the others to follow (unless noted) are
; the same instructions as the old code version; except for the
; necessary changes in jump addresses.  This old code started
; at location "D45C" prior to Windows XP (SP2); and even the
; call to "DOC7" AND the NOP are the same:

D48A 06            PUSH    ES       ; Push ES onto Stack.
D48B 1E            PUSH    DS       ; Push DS onto Stack.
D48C 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.

D48E 668BDA        MOV     EBX,EDX
D491 660FB60E0D00  MOVZX   ECX,BYTE PTR [000D]  ; Sectors per Cluster -> ECX
D497 66F7E1        MUL     ECX
D49A 66A31000      MOV     [0010],EAX
D49E 668BC3        MOV     EAX,EBX
D4A1 66F7E1        MUL     ECX
D4A4 A30E00        MOV     [000E],AX
D4A7 8BDF          MOV     BX,DI
D4A9 83E30F        AND     BX,000F
D4AC 8CC0          MOV     AX,ES
D4AE 66C1EF04      SHR     EDI,04
D4B2 03C7          ADD     AX,DI
D4B4 50            PUSH    AX
D4B5 07            POP     ES
D4B6 E80EFC        CALL    D0C7

;   Subroutine from the Boot Sector; this one reads
;   sectors from disk drive into Memory:

D0C7 6660          PUSHAD           ; Push all "Double" Registers onto the
                                    ;  stack: EAX, ECX, EDX, EBX, original
                                    ;         ESP, EBP, ESI, and EDI.
D0C9 1E            PUSH    DS
D0CA 06            PUSH    ES

; When executed as the Boot Sector, [0010] "Must always be zero for NTFS!"
; But as we saw at D76D (and will see elsewhere), these Memory locations
; are now being used by the NTLDR Bootstrap Code!

D0CB 66A11000      MOV     EAX,[0010] ; The first time through, [D010]
                                      ; contains Starting Relative Sector 
; location of $MFT file in this Volume (Example: 600000h).

D0CF 6603061C00    ADD     EAX,[001C] ; Add Number of "Hidden Sectors"
                                      ;(For 1st Volume of XP HDD, this is
; often 63.   So EAX, for this Example, becomes: 60003Fh.)

D0D4 663B062000    CMP     EAX,[0020] ;  Total Number of Sectors on Disk:
                                      ;  Our 8.0 GiB Bochs image; which is
; comprised of exactly 8,589,901,824 bytes, or 16,777,152 sectors, and CHS
; values of "cylinders=16644, heads=16, spt=63" in its .bxrc configuration
; file, obviously exceeding the 1024 Cylinder limit, ends up with 0xFB0400
; filling [D020] through [D023] ("00 04 FB 00"); from the Boot Sector code
; at D07B through D0A9.

D0D9 0F823A00      JB      D117     ; 

D0DD 1E            PUSH    DS
D0DE 666A00        PUSH    00000000
D0E1 6650          PUSH    eax
D0E3 06            PUSH    ES
D0E4 53            PUSH    BX
D0E5 6668100001    PUSH    00010010
     00
D0EB 803E140000    CMP     BYTE PTR [0014],00  

D0F0 0F850C00      JNZ     D100
D0F4 E8B3FF        CALL    D0AA     ; Check for Extended INT 13 code. Yet
                                    ; another call to what was originally
; Boot Sector code!

D0F7 803E140000    CMP     BYTE PTR [0014],00

D0FC 0F846100      JZ      D161         ; Extensions are not installed.
                                        ; -> "A disk read error..." etc.

D100 B442          MOV     AH,42        ; Function 42h of INT 13:
                                        ;    " Extended Read "
D102 8A162400      MOV     DL,[0024]    ; -> "80h" (first hard drive).
D106 16            PUSH    SS
D107 1F            POP     DS
D108 8BF4          MOV     SI,SP
D10A CD13          INT     13

D10C 6658          POP     EAX
D10E 5B            POP     BX
D10F 07            POP     ES
D110 6658          POP     EAX
D112 6658          POP     EAX
D114 1F            POP     DS
D115 EB2D          JMP     D144

D117 6633D2        XOR     EDX,EDX
D11A 660FB70E18    MOVZX   ECX,WORD [0018]  ; [D018] = Sectors per Track
     00
D120 66F7F1        DIV     ECX
D123 FEC2          INC     DL
D125 8ACA          MOV     CL,DL
D127 668BD0        MOV     EDX,EAX
D12A 66C1EA10      SHR     EDX,10
D12E F7361A00      DIV     WORD PTR [001A]   ; [D01A] = Number of Heads
D132 86D6          XCHG    DL,DH
D134 8A162400      MOV     DL,[0024]     ; [D024] = Hard Drive Number
D138 8AE8          MOV     CH,AL
D13A C0E406        SHL     AH,06
D13D 0ACC          OR      CL,AH
D13F B80102        MOV     AX,0201       ; Function 02h of INT 13:
D142 CD13          INT     13            ; "Read Sector into Memory"

D144 0F821900      JB      D161          ; -> "A disk read error..." etc.
D148 8CC0          MOV     AX,ES
D14A 052000        ADD     AX,0020       ; Add another 200h (512 bytes) to
D14D 8EC0          MOV     ES,AX         ;    the Segment pointer in ES.
D14F 66FF061000    INC     DWORD PTR [0010]    ; 
D154 FF0E0E00      DEC     WORD PTR [000E] ; Decrement the Count of how
                                           ; many Sectors are left to read
D158 0F856FFF      JNZ     D0CB
D15C 07            POP     ES
D15D 1F            POP     DS
D15E 6661          POPAD
D160 C3            RET 

D4B9 6661          POPAD
D4BB 90            NOP
D4BC 1F            POP     DS
D4BD 07            POP     ES
D4BE C3            RET

; ----------------------------------------------------------
D4BF 67034014      ADD     AX,[EAX+14]
D4C3 67668338FF    CMP     DWORD PTR [EAX],-01
D4C8 0F844C00      JZ      D518
D4CC 67663918      CMP     [EAX],EBX
D4D0 0F853300      JNZ     D507
D4D4 660BC9        OR      ECX,ECX
D4D7 0F850A00      JNZ     D4E5
D4DB 6780780900    CMP     BYTE PTR [EAX+09],00
D4E0 0F852300      JNZ     D507
D4E4 C3            RET

; --------------------------------------------------------
D4E5 673A4809      CMP     CL,[EAX+09]
D4E9 0F851A00      JNZ     D507
D4ED 668BF0        MOV     ESI,EAX
D4F0 6703700A      ADD     SI,[EAX+0A]
D4F4 E89706        CALL    DB8E
D4F7 6651          PUSH    ECX
D4F9 1E            PUSH    DS
D4FA 07            POP     ES
D4FB 668BFA        MOV     EDI,EDX
D4FE F3            REPZ
D4FF A7            CMPSW
D500 6659          POP     ECX
D502 0F850100      JNZ     D507
D506 C3            RET

; ---------------------------------------------------------
D507 676683780400  CMP     DWORD PTR [EAX+04],+00
D50D 0F840700      JZ      D518
D511 6766034004    ADD     EAX,[EAX+04]
D516 EBAB          JMP     D4C3
D518 662BC0        SUB     EAX,EAX
D51B C3            RET

; ---------------------------------------------------------
D51C 668BF3        MOV     ESI,EBX
D51F E86C06        CALL    DB8E

D522 67660300      ADD     EAX,[EAX]
D526 67F7400C0200  TEST    WORD PTR [EAX+0C],0002
D52C 0F853400      JNZ     D564
D530 67668D5010    LEA     EDX,[EAX+10]
D535 673A4A40      CMP     CL,[EDX+40]
D539 0F851800      JNZ     D555
D53D 67668D7242    LEA     ESI,[EDX+42]
D542 E84906        CALL    DB8E

D545 6651          PUSH    ECX
D547 1E            PUSH    DS
D548 07            POP     ES
D549 668BFB        MOV     EDI,EBX
D54C F3            REPZ
D54D A7            CMPSW
D54E 6659          POP     ECX
D550 0F850100      JNZ     D555
D554 C3            RET

; ---------------------------------------------------------
D555 6783780800    CMP     WORD PTR [EAX+08],+00
D55A 0F840600      JZ      D564
D55E 67034008      ADD     AX,[EAX+08]
D562 EBC2          JMP     D526

D564 6633C0        XOR     EAX,EAX
D567 C3            RET

; ---------------------------------------------------------
; The code is different in some of the lines in this routine!
; And very different in the following routines (or it could
; be that I'm losing my eyesight due to all the monotony!

D568 67807B0800    CMP     BYTE PTR [EBX+08],00
D56D 0F851C00      JNZ     D58D
D571 06            PUSH    ES
D572 1E            PUSH    DS
D573 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
D575 67668D5310    LEA     EDX,[EBX+10]
D57A 67668B0A      MOV     ECX,[EDX]
D57E 668BF3        MOV     ESI,EBX
D581 67037204      ADD     SI,[EDX+04]
D585 F3            REPZ
D586 A4            MOVSB
D587 6661          POPAD

D589 90            NOP

D58A 1F            POP     DS
D58B 07            POP     ES
D58C C3            RET

; ---------------------------------------------------------
D58D 6650          PUSH    EAX
D58F 67668D5310    LEA     EDX,[EBX+10]
D594 6685C0        TEST    EAX,EAX
D597 0F850A00      JNZ     D5A5
D59B 67668B4A08    MOV     ECX,[EDX+08]
D5A0 6641          INC     ECX
D5A2 EB11          JMP     D5B5

D5A4 90            NOP

D5A5 67668B4218    MOV     EAX,[EDX+18]
D5AA 6633D2        XOR     EDX,EDX
D5AD 66F7364E02    DIV     DWORD PTR [024E]	; Divide by Bytes per Cluster 
D5B2 668BC8        MOV     ECX,EAX
D5B5 662BC0        SUB     EAX,EAX
D5B8 665E          POP     ESI
D5BA E80100        CALL    D5BE

D5BD C3            RET

; ---------------------------------------------------------
D5BE 06            PUSH    ES
D5BF 1E            PUSH    DS
D5C0 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
D5C2 67807B0801    CMP     BYTE PTR [EBX+08],01
D5C7 0F840300      JZ      D5CE
D5CB E993FB        JMP     D161


D5CE 6683F900      CMP     ECX,+00
D5D2 0F850600      JNZ     D5DC
D5D6 6661          POPAD
D5D8 90            NOP
D5D9 1F            POP     DS
D5DA 07            POP     ES
D5DB C3            RET


; ---------------------------------------------------------
D5DC 6653          PUSH    EBX
D5DE 6650          PUSH    EAX
D5E0 6651          PUSH    ECX
D5E2 6656          PUSH    ESI
D5E4 6657          PUSH    EDI
D5E6 06            PUSH    ES
D5E7 E89104        CALL    DA7B

D5EA 668BD1        MOV     EDX,ECX
D5ED 07            POP     ES
D5EE 665F          POP     EDI
D5F0 665E          POP     ESI
D5F2 6659          POP     ECX
D5F4 6685C0        TEST    EAX,EAX
D5F7 0F843400      JZ      D62F
D5FB 663BCA        CMP     ECX,EDX
D5FE 0F8D0300      JNL     D605
D602 668BD1        MOV     EDX,ECX
D605 E882FE        CALL    D48A

D608 662BCA        SUB     ECX,EDX
D60B 668BDA        MOV     EBX,EDX
D60E 668BC2        MOV     EAX,EDX
D611 660FB6160D00  MOVZX   EDX,BYTE PTR [000D]  ; Sectors per Cluster -> EDX
D617 66F7E2        MUL     EDX
D61A 660FB7160B00  MOVZX   EDX,WORD PTR [000B]
D620 66F7E2        MUL     EDX
D623 6603F8        ADD     EDI,EAX
D626 6658          POP     EAX
D628 6603C3        ADD     EAX,EBX
D62B 665B          POP     EBX
D62D EB9F          JMP     D5CE


D62F 6685F6        TEST    ESI,ESI
D632 0F842BFB      JZ      D161
D636 6651          PUSH    ECX
D638 6657          PUSH    EDI
D63A 06            PUSH    ES
D63B 67660FB64309  MOVZX   EAX,BYTE PTR [EBX+09]
D641 6685C0        TEST    EAX,EAX
D644 0F842000      JZ      D668
D648 66D1E0        SHL     EAX,1
D64B 662BE0        SUB     ESP,EAX
D64E 668BFC        MOV     EDI,ESP
D651 6654          PUSH    ESP
D653 6656          PUSH    ESI
D655 67660FB7730A  MOVZX   ESI,WORD PTR [EBX+0A]
D65B 6603F3        ADD     ESI,EBX
D65E 668BC8        MOV     ECX,EAX
D661 F3            REPZ
D662 A4            MOVSB
D663 665E          POP     ESI
D665 EB03          JMP     D66A


D667 90            NOP


D668 6650          PUSH    EAX
D66A 6650          PUSH    EAX
D66C 67668B03      MOV     EAX,[EBX]
D670 6650          PUSH    EAX
D672 67668B4318    MOV     EAX,[EBX+18]
D677 6650          PUSH    EAX
D679 67668B5620    MOV     EDX,[ESI+20]
D67E 6685D2        TEST    EDX,EDX
D681 0F840B00      JZ      D690
D685 668BFE        MOV     EDI,ESI
D688 1E            PUSH    DS
D689 07            POP     ES
D68A 668BC2        MOV     EAX,EDX
D68D E87103        CALL    DA01

D690 668BC6        MOV     EAX,ESI
D693 665A          POP     EDX
D695 6659          POP     ECX
D697 6642          INC     EDX
D699 6651          PUSH    ECX
D69B 6656          PUSH    ESI
D69D E83F06        CALL    DCDF

D6A0 6685C0        TEST    EAX,EAX
D6A3 0F84BAFA      JZ      D161
D6A7 665E          POP     ESI
D6A9 6659          POP     ECX
D6AB 668BFE        MOV     EDI,ESI
D6AE 1E            PUSH    DS
D6AF 07            POP     ES
D6B0 E84E03        CALL    DA01

D6B3 668BC6        MOV     EAX,ESI
D6B6 668BD9        MOV     EBX,ECX
D6B9 6659          POP     ECX
D6BB 665A          POP     EDX
D6BD 6651          PUSH    ECX
D6BF 6656          PUSH    ESI
D6C1 66D1E9        SHR     ECX,1
D6C4 E8F8FD        CALL    D4BF

D6C7 6685C0        TEST    EAX,EAX
D6CA 0F8493FA      JZ      D161
D6CE 665E          POP     ESI
D6D0 6659          POP     ECX
D6D2 6603E1        ADD     ESP,ECX
D6D5 07            POP     ES
D6D6 665F          POP     EDI
D6D8 6659          POP     ECX
D6DA 668BD0        MOV     EDX,EAX
D6DD 6658          POP     EAX
D6DF 665B          POP     EBX
D6E1 668BDA        MOV     EBX,EDX
D6E4 E9F5FE        JMP     D5DC


D6E7 06            PUSH    ES
D6E8 1E            PUSH    DS
D6E9 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
D6EB 26            ES:
D6EC 67660FB75F04  MOVZX   EBX,WORD PTR [EDI+04]
D6F2 26            ES:
D6F3 67660FB74F06  MOVZX   ECX,WORD PTR [EDI+06]
D6F9 660BC9        OR      ECX,ECX
D6FC 0F8461FA      JZ      D161
D700 6603DF        ADD     EBX,EDI
D703 6683C302      ADD     EBX,+02
D707 6681C7FE0100  ADD     EDI,000001FE
     00
D70E 6649          DEC     ECX
D710 660BC9        OR      ECX,ECX
D713 0F841700      JZ      D72E
D717 26            ES:
D718 678B03        MOV     AX,[EBX]
D71B 26            ES:
D71C 678907        MOV     [EDI],AX
D71F 6683C302      ADD     EBX,+02
D723 6681C7000200  ADD     EDI,00000200
     00
D72A 6649          DEC     ECX
D72C EBE2          JMP     D710

D72E 6661          POPAD

D730 90            NOP

D731 1F            POP     DS
D732 07            POP     ES
D733 C3            RET

; ====================================================================
; * Most of the following code is the same as it was under XP (SP1)! *
; ====================================================================

D734 06            PUSH    ES
D735 1E            PUSH    DS
D736 6660          PUSHAD               ; Push all GP "Double" Registers onto
                                        ; stack: EAX, ECX, EDX, EBX, original
                                        ;        ESP, EBP, ESI, and EDI.

; Simply sets [021E] to 0x00000001 (why not preset this in the Data Area?)
D738 66B801000000  MOV     EAX,00000001
D73E 66A31E02      MOV     [021E],EAX   ; Puts a 1 in [D21E]

; Makes Contents of 0xD25A = BpFRS + 3000h
D742 66A11A02      MOV     EAX,[021A]   ; Put 3000h into EAX.
D746 6603065202    ADD     EAX,[0252]   ; Add Bytes per File Record Segment
D74B 66A35A02      MOV     [025A],EAX   ; Puts (BpFRS + 3000h) into [D25A], so for
                                        ;    our Sample data, this now = 0x3400.

; Makes Contents of 0xD24A = (2 x BpFRS) + 3000h
D74F 6603065202    ADD     EAX,[0252]   ; Add Bytes per FRS again!
D754 66A34A02      MOV     [024A],EAX   ; Puts [(2 x BpFRS) + 3000h] into [024A]
                                          ; (for Sample data, this = 0x3800 then.)

; Put "Starting Cluster Number of $MFT File" into EAX. Then multiply that
; by Sectors per Cluster (in EBX) and copy answer ("Starting Relative
; Sector of $MFT File") into DS:[BX] as well as [D010 - D013].

D758 66A13000      MOV     EAX,[0030]   ; Starting Cluster Number $MFT File
                                        ; Example: C0000h = Cluster 786432

D75C 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]   ; Sectors per Cluster -> EBX
D762 66F7E3        MUL     EBX          ; Example: C0000h x 8 = 600000h in EAX
                                        ; So, Starting Relative Sector of $MFT
                                        ; file would be: (600000h) = 6291456
D765 668B1E4A02    MOV     EBX,[024A]   ; Using: 0x3800 for this example. 
D76A 668907        MOV     [BX],EAX     ;  EAX -> DS:[BX] (DS=0D00)
                                        ; If BX = 3800, Example's location is:
; DS:[BX] = D00:3800 = (0xD000 + 0x3800) = 0x10800; now containing 0x600000

D76D 66A31000      MOV     [0010],EAX  ; EAX -> [D010 thru D013]; also save
                                       ; Relative Sector location of $MFT
                                       ; file to [D010-D013] in the Volume.

D771 83C304        ADD     BX,+04      ; Example: 3800h + 4 = 3804h

D774 66A15602      MOV     EAX,[0256]  ; Sectors per FRS -> EAX
D778 668907        MOV     [BX],EAX    ; (Example: EAX = 2 sectors per FRS)
                                       ; EAX -> DS:[BX] (DS=0D00), so:
; DS:[BX] = D00:3804 = (0xD000 + 0x3804) = 0x10804; now containing 0x00000002

D77B A30E00        MOV     [000E],AX   ; AX -> [D00E] (save as 0x0002 here)

D77E 83C304        ADD     BX,+04      ; Example: 3804h + 4 = 3808h
D781 66891E4A02    MOV     [024A],EBX  ; If BX was originally 0x3804,
                                       ; we now save 0x3808 to [024A].

D786 668B1E1A02    MOV     EBX,[021A]  ; Reset EBX to 0x3000 (from [D21A]).
D78B 1E            PUSH    DS          ; DS is still 0x0D00
D78C 07            POP     ES          ;(ES was 09A0 up to this point)
D78D E837F9        CALL    D0C7

D790 668BFB        MOV     EDI,EBX
D793 E851FF        CALL    D6E7

D796 66A11A02      MOV     EAX,[021A]   ; Put 3000h into EAX.
D79A 66BB20000000  MOV     EBX,00000020
D7A0 66B900000000  MOV     ECX,00000000
D7A6 66BA00000000  MOV     EDX,00000000
D7AC E810FD        CALL    D4BF

D7AF 660BC0        OR      EAX,EAX
D7B2 0F841901      JZ      D8CF
D7B6 668BD8        MOV     EBX,EAX
D7B9 1E            PUSH    DS
D7BA 07            POP     ES
D7BB 668B3E1602    MOV     EDI,[0216]
D7C0 6633C0        XOR     EAX,EAX
D7C3 E8A2FD        CALL    D568

D7C6 668B1E1602    MOV     EBX,[0216]
D7CB 66813F800000+ CMP     DWORD PTR [BX],00000080
D7D2 0F84EB00      JZ      D8C1
D7D6 035F04        ADD     BX,[BX+04]
D7D9 EBF0          JMP     D7CB

D7DB 6653          PUSH    EBX
D7DD 668B4710      MOV     EAX,[BX+10]
D7E1 66F7265602    MUL     DWORD PTR [0256]  ; Multiply by Sectors per FRS
D7E6 6650          PUSH    EAX
D7E8 6633D2        XOR     EDX,EDX
D7EB 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D7F1 66F7F3        DIV     EBX
D7F4 6652          PUSH    EDX
D7F6 E8DC00        CALL    D8D5

D7F9 660BC0        OR      EAX,EAX
D7FC 0F8461F9      JZ      D161
D800 668B0E5602    MOV     ECX,[0256]  ; Sectors per FRS -> ECX
D805 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D80B 66F7E3        MUL     EBX
D80E 665A          POP     EDX
D810 6603C2        ADD     EAX,EDX
D813 668B1E4A02    MOV     EBX,[024A]    ; [(2 x BpFRS) + 3000h + 8] -> EBX
                                         ;(So in our Example, 0x3808 -> EBX)
D818 668907        MOV     [BX],EAX
D81B 83C304        ADD     BX,+04
D81E 660FB6060D00  MOVZX   EAX,BYTE PTR [000D]  ; Sectors per Cluster -> EAX
D824 662BC2        SUB     EAX,EDX
D827 663BC1        CMP     EAX,ECX
D82A 0F860300      JBE     D831
D82E 668BC1        MOV     EAX,ECX
D831 668907        MOV     [BX],EAX
D834 662BC8        SUB     ECX,EAX
D837 665A          POP     EDX
D839 0F847500      JZ      D8B2
D83D 6603C2        ADD     EAX,EDX
D840 6650          PUSH    EAX
D842 6633D2        XOR     EDX,EDX
D845 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D84B 66F7F3        DIV     EBX
D84E 6651          PUSH    ECX
D850 E88200        CALL    D8D5

D853 6659          POP     ECX
D855 660BC0        OR      EAX,EAX
D858 0F8405F9      JZ      D161
D85C 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D862 66F7E3        MUL     EBX
D865 668B1E4A02    MOV     EBX,[024A]    ; [(2 x BpFRS) + 3000h + 8] -> EBX
                                         ;(So in our Example, 0x3808 -> EBX)
D86A 668B17        MOV     EDX,[BX]
D86D 83C304        ADD     BX,+04
D870 660317        ADD     EDX,[BX]
D873 663BD0        CMP     EDX,EAX
D876 0F851500      JNZ     D88F
D87A 660FB6060D00  MOVZX   EAX,BYTE PTR [000D]  ; Sectors per Cluster -> EAX
D880 663BC1        CMP     EAX,ECX
D883 0F860300      JBE     D88A
D887 668BC1        MOV     EAX,ECX
D88A 660107        ADD     [BX],EAX
D88D EBA5          JMP     D834

D88F 83C304        ADD     BX,+04
D892 66891E4A02    MOV     [024A],EBX
D897 668907        MOV     [BX],EAX
D89A 83C304        ADD     BX,+04
D89D 660FB6060D00  MOVZX   EAX,BYTE PTR [000D]  ; Sectors per Cluster -> EAX
D8A3 663BC1        CMP     EAX,ECX
D8A6 0F860300      JBE     D8AD
D8AA 668BC1        MOV     EAX,ECX
D8AD 668907        MOV     [BX],EAX
D8B0 EB82          JMP     D834

D8B2 83C304        ADD     BX,+04
D8B5 66FF061E02    INC     DWORD PTR [021E]  ; So, INC by 1.
D8BA 66891E4A02    MOV     [024A],EBX
D8BF 665B          POP     EBX
D8C1 035F04        ADD     BX,[BX+04]
D8C4 66813F800000+ CMP     DWORD PTR [BX],00000080
D8CB 0F840CFF      JZ      D7DB
D8CF 6661          POPAD

D8D1 90            NOP

D8D2 1F            POP     DS
D8D3 07            POP     ES
D8D4 C3            RET

; ---------------------------------------------------------
D8D5 668BD0        MOV     EDX,EAX
D8D8 668B0E1E02    MOV     ECX,[021E]  ; Put a 1 in ECX.
D8DD 668B365A02    MOV     ESI,[025A]
D8E2 6603365202    ADD     ESI,[0252]  ; Bytes per FRS
D8E7 6652          PUSH    EDX
D8E9 6651          PUSH    ECX
D8EB 6652          PUSH    EDX
D8ED 668B1E5A02    MOV     EBX,[025A]
D8F2 668B3E5602    MOV     EDI,[0256]  ; Sectors per FRS -> EDI
D8F7 668B04        MOV     EAX,[SI]
D8FA 66A31000      MOV     [0010],EAX
D8FE 83C604        ADD     SI,+04
D901 668B04        MOV     EAX,[SI]
D904 A30E00        MOV     [000E],AX
D907 83C604        ADD     SI,+04
D90A 1E            PUSH    DS
D90B 07            POP     ES
D90C E8B8F7        CALL    D0C7
D90F 662BF8        SUB     EDI,EAX
D912 0F840800      JZ      D91E
D916 F7260B00      MUL     WORD PTR [000B]
D91A 03D8          ADD     BX,AX
D91C EBD9          JMP     D8F7
D91E 668B3E5A02    MOV     EDI,[025A]
D923 1E            PUSH    DS
D924 07            POP     ES
D925 E8BFFD        CALL    D6E7

D928 66A15A02      MOV     EAX,[025A]
D92C 66BB80000000  MOV     EBX,00000080
D932 66B900000000  MOV     ECX,00000000
D938 668BD1        MOV     EDX,ECX
D93B E881FB        CALL    D4BF

D93E 660BC0        OR      EAX,EAX
D941 0F841CF8      JZ      D161
D945 668BD8        MOV     EBX,EAX
D948 6658          POP     EAX
D94A 6656          PUSH    ESI
D94C E82C01        CALL    DA7B
D94F 665E          POP     ESI
D951 660BC0        OR      EAX,EAX
D954 0F840500      JZ      D95D
D958 665B          POP     EBX
D95A 665B          POP     EBX
D95C C3            RET

; ---------------------------------------------------------
D95D 6659          POP     ECX
D95F 665A          POP     EDX
D961 E284          LOOP    D8E7
D963 6633C0        XOR     EAX,EAX
D966 C3            RET

; ---------------------------------------------------------
D967 06            PUSH    ES
D968 1E            PUSH    DS
D969 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
D96B 6650          PUSH    EAX
D96D 6651          PUSH    ECX
D96F 6633D2        XOR     EDX,EDX
D972 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D978 66F7F3        DIV     EBX
D97B 6652          PUSH    EDX
D97D 6657          PUSH    EDI
D97F E853FF        CALL    D8D5

D982 665F          POP     EDI
D984 660BC0        OR      EAX,EAX
D987 0F84D6F7      JZ      D161
D98B 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D991 66F7E3        MUL     EBX
D994 665A          POP     EDX
D996 6603C2        ADD     EAX,EDX
D999 66A31000      MOV     [0010],EAX
D99D 6659          POP     ECX
D99F 660FB61E0D00  MOVZX   EBX,BYTE PTR [000D]  ; Sectors per Cluster -> EBX
D9A5 663BCB        CMP     ECX,EBX
D9A8 0F8E1300      JLE     D9BF
D9AC 891E0E00      MOV     [000E],BX
D9B0 662BCB        SUB     ECX,EBX
D9B3 6658          POP     EAX
D9B5 6603C3        ADD     EAX,EBX
D9B8 6650          PUSH    EAX
D9BA 6651          PUSH    ECX
D9BC EB14          JMP     D9D2

D9BE 90            NOP

D9BF 6658          POP     EAX
D9C1 6603C1        ADD     EAX,ECX
D9C4 6650          PUSH    EAX
D9C6 890E0E00      MOV     [000E],CX
D9CA 66B900000000  MOV     ECX,00000000
D9D0 6651          PUSH    ECX
D9D2 06            PUSH    ES
D9D3 6657          PUSH    EDI
D9D5 8BDF          MOV     BX,DI
D9D7 83E30F        AND     BX,000F
D9DA 8CC0          MOV     AX,ES
D9DC 66C1EF04      SHR     EDI,04
D9E0 03C7          ADD     AX,DI
D9E2 50            PUSH    AX
D9E3 07            POP     ES
D9E4 E8E0F6        CALL    D0C7

D9E7 665F          POP     EDI
D9E9 07            POP     ES
D9EA 66033E4E02    ADD     EDI,[024E]  ; Add Bytes per Cluster to EDI
D9EF 6659          POP     ECX
D9F1 6658          POP     EAX
D9F3 6683F900      CMP     ECX,+00
D9F7 0F8F70FF      JG      D96B
D9FB 6661          POPAD

D9FD 90            NOP

D9FE 1F            POP     DS
D9FF 07            POP     ES
DA00 C3            RET


; ---------------------------------------------------------
DA01 06            PUSH    ES
DA02 1E            PUSH    DS
DA03 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
DA05 66F7265602    MUL     DWORD PTR [0256]  ; Multiply by Sectors per FRS
DA0A 668B0E5602    MOV     ECX,[0256]  ; Sectors per FRS -> ECX
DA0F E855FF        CALL    D967
DA12 E8D2FC        CALL    D6E7

DA15 6661          POPAD

DA17 90            NOP

DA18 1F            POP     DS
DA19 07            POP     ES
DA1A C3            RET

; ---------------------------------------------------------
DA1B 06            PUSH    ES
DA1C 1E            PUSH    DS
DA1D 6660          PUSHAD           ; Push all GP "Double" Registers onto
                                    ; stack: EAX, ECX, EDX, EBX, original
                                    ;        ESP, EBP, ESI, and EDI.
DA1F 66F7266202    MUL     DWORD PTR [0262]
DA24 668B1E3202    MOV     EBX,[0232]
DA29 668B0E6202    MOV     ECX,[0262]
DA2E 668B362602    MOV     ESI,[0226]
DA33 1E            PUSH    DS
DA34 07            POP     ES
DA35 668B3E4202    MOV     EDI,[0242]
DA3A E881FB        CALL    D5BE

DA3D E8A7FC        CALL    D6E7

DA40 6661          POPAD

DA42 90            NOP

DA43 1F            POP     DS
DA44 07            POP     ES
DA45 C3            RET

; ---------------------------------------------------------
DA46 6650          PUSH    EAX
DA48 6653          PUSH    EBX
DA4A 6651          PUSH    ECX
DA4C 668B1E4602    MOV     EBX,[0246]
DA51 668BC8        MOV     ECX,EAX
DA54 66C1E803      SHR     EAX,03
DA58 6683E107      AND     ECX,00000007
DA5C 6603D8        ADD     EBX,EAX
DA5F 66B801000000  MOV     EAX,00000001
DA65 66D3E0        SHL     EAX,CL
DA68 678403        TEST    [EBX],AL
DA6B 0F840400      JZ      DA73
DA6F F8            CLC
DA70 EB02          JMP     DA74

DA72 90            NOP

DA73 F9            STC
DA74 6659          POP     ECX
DA76 665B          POP     EBX
DA78 6658          POP     EAX
DA7A C3            RET

; ---------------------------------------------------------
DA7B 67807B0801    CMP     BYTE PTR [EBX+08],01
DA80 0F840400      JZ      DA88
DA84 662BC0        SUB     EAX,EAX
DA87 C3            RET

; ---------------------------------------------------------
DA88 67668D7310    LEA     ESI,[EBX+10]
DA8D 67668B5608    MOV     EDX,[ESI+08]
DA92 663BC2        CMP     EAX,EDX
DA95 0F870B00      JA      DAA4
DA99 67668B16      MOV     EDX,[ESI]
DA9D 663BC2        CMP     EAX,EDX
DAA0 0F830400      JNB     DAA8
DAA4 662BC0        SUB     EAX,EAX
DAA7 C3            RET

; ---------------------------------------------------------
DAA8 67035E10      ADD     BX,[ESI+10]
DAAC 662BF6        SUB     ESI,ESI
DAAF 67803B00      CMP     BYTE PTR [EBX],00
DAB3 0F843E00      JZ      DAF5
DAB7 E88100        CALL    DB3B
DABA 6603F1        ADD     ESI,ECX
DABD E83900        CALL    DAF9

DAC0 6603CA        ADD     ECX,EDX
DAC3 663BC1        CMP     EAX,ECX
DAC6 0F8C2100      JL      DAEB
DACA 668BD1        MOV     EDX,ECX
DACD 6650          PUSH    EAX
DACF 67660FB60B    MOVZX   ECX,BYTE PTR [EBX]
DAD4 668BC1        MOV     EAX,ECX
DAD7 6683E00F      AND     EAX,0000000F
DADB 66C1E904      SHR     ECX,04
DADF 6603D9        ADD     EBX,ECX
DAE2 6603D8        ADD     EBX,EAX
DAE5 6643          INC     EBX
DAE7 6658          POP     EAX
DAE9 EBC4          JMP     DAAF

DAEB 662BC8        SUB     ECX,EAX
DAEE 662BC2        SUB     EAX,EDX
DAF1 6603C6        ADD     EAX,ESI
DAF4 C3            RET

DAF5 662BC0        SUB     EAX,EAX
DAF8 C3            RET


; ---------------------------------------------------------
DAF9 662BC9        SUB     ECX,ECX
DAFC 678A0B        MOV     CL,[EBX]
DAFF 80E10F        AND     CL,0F
DB02 6683F900      CMP     ECX,+00
DB06 0F850400      JNZ     DB0E
DB0A 662BC9        SUB     ECX,ECX
DB0D C3            RET

; ---------------------------------------------------------
DB0E 6653          PUSH    EBX
DB10 6652          PUSH    EDX
DB12 6603D9        ADD     EBX,ECX
DB15 67660FBE13    MOVSX   EDX,BYTE PTR [EBX]
DB1A 6649          DEC     ECX
DB1C 664B          DEC     EBX
DB1E 6683F900      CMP     ECX,+00
DB22 0F840D00      JZ      DB33
DB26 66C1E208      SHL     EDX,08
DB2A 678A13        MOV     DL,[EBX]
DB2D 664B          DEC     EBX
DB2F 6649          DEC     ECX
DB31 EBEB          JMP     DB1E

DB33 668BCA        MOV     ECX,EDX
DB36 665A          POP     EDX
DB38 665B          POP     EBX
DB3A C3            RET


; ---------------------------------------------------------
DB3B 6653          PUSH    EBX
DB3D 6652          PUSH    EDX
DB3F 662BD2        SUB     EDX,EDX
DB42 678A13        MOV     DL,[EBX]
DB45 6683E20F      AND     EDX,0000000F
DB49 662BC9        SUB     ECX,ECX
DB4C 678A0B        MOV     CL,[EBX]
DB4F C0E904        SHR     CL,04
DB52 6683F900      CMP     ECX,+00
DB56 0F850800      JNZ     DB62
DB5A 662BC9        SUB     ECX,ECX
DB5D 665A          POP     EDX
DB5F 665B          POP     EBX
DB61 C3            RET

; ---------------------------------------------------------
DB62 6603DA        ADD     EBX,EDX
DB65 6603D9        ADD     EBX,ECX
DB68 67660FBE13    MOVSX   EDX,BYTE PTR [EBX]
DB6D 6649          DEC     ECX
DB6F 664B          DEC     EBX
DB71 6683F900      CMP     ECX,+00
DB75 0F840D00      JZ      DB86
DB79 66C1E208      SHL     EDX,08
DB7D 678A13        MOV     DL,[EBX]
DB80 664B          DEC     EBX
DB82 6649          DEC     ECX
DB84 EBEB          JMP     DB71

DB86 668BCA        MOV     ECX,EDX
DB89 665A          POP     EDX
DB8B 665B          POP     EBX
DB8D C3            RET

DB8E 660BC9        OR      ECX,ECX
DB91 0F850100      JNZ     DB96
DB95 C3            RET

DB96 6651          PUSH    ECX
DB98 6656          PUSH    ESI
DB9A 67833E61      CMP     WORD PTR [ESI],+61
DB9E 0F8C0C00      JL      DBAE
DBA2 67833E7A      CMP     WORD PTR [ESI],+7A
DBA6 0F8F0400      JG      DBAE
DBAA 67832E20      SUB     WORD PTR [ESI],+20
DBAE 6683C602      ADD     ESI,+02
DBB2 E2E6          LOOP    DB9A

DBB4 665E          POP     ESI
DBB6 6659          POP     ECX
DBB8 C3            RET


; ---------------------------------------------------------
DBB9 6650          PUSH    EAX
DBBB 6651          PUSH    ECX
DBBD 668BD0        MOV     EDX,EAX
DBC0 66A12E02      MOV     EAX,[022E]
DBC4 67668D5810    LEA     EBX,[EAX+10]
DBC9 67034304      ADD     AX,[EBX+04]
DBCD 67668D4010    LEA     EAX,[EAX+10]
DBD2 668BDA        MOV     EBX,EDX
DBD5 E844F9        CALL    D51C

DBD8 660BC0        OR      EAX,EAX
DBDB 0F840500      JZ      DBE4
DBDF 6659          POP     ECX
DBE1 6659          POP     ECX
DBE3 C3            RET

DBE4 66A13202      MOV     EAX,[0232]
DBE8 660BC0        OR      EAX,EAX
DBEB 0F850800      JNZ     DBF7
DBEF 6659          POP     ECX
DBF1 6659          POP     ECX
DBF3 6633C0        XOR     EAX,EAX
DBF6 C3            RET

; ---------------------------------------------------------
DBF7 668B163202    MOV     EDX,[0232]
DBFC 67668D5210    LEA     EDX,[EDX+10]
DC01 67668B4218    MOV     EAX,[EDX+18]
DC06 6633D2        XOR     EDX,EDX
DC09 66F7365E02    DIV     DWORD PTR [025E]
DC0E 6633F6        XOR     ESI,ESI
DC11 6650          PUSH    EAX
DC13 6656          PUSH    ESI
DC15 6658          POP     EAX
DC17 665E          POP     ESI
DC19 663BC6        CMP     EAX,ESI
DC1C 0F843A00      JZ      DC5A
DC20 6656          PUSH    ESI
DC22 6640          INC     EAX
DC24 6650          PUSH    EAX
DC26 6648          DEC     EAX
DC28 E81BFE        CALL    DA46

DC2B 72E8          JB      DC15
DC2D E8EBFD        CALL    DA1B

DC30 665A          POP     EDX
DC32 665E          POP     ESI
DC34 6659          POP     ECX
DC36 665B          POP     EBX
DC38 6653          PUSH    EBX
DC3A 6651          PUSH    ECX
DC3C 6656          PUSH    ESI
DC3E 6652          PUSH    EDX
DC40 66A14202      MOV     EAX,[0242]
DC44 67668D4018    LEA     EAX,[EAX+18]
DC49 E8D0F8        CALL    D51C

DC4C 660BC0        OR      EAX,EAX
DC4F 74C4          JZ      DC15
DC51 6659          POP     ECX
DC53 6659          POP     ECX
DC55 6659          POP     ECX
DC57 6659          POP     ECX
DC59 C3            RET

; ---------------------------------------------------------
DC5A 6659          POP     ECX
DC5C 6659          POP     ECX
DC5E 6633C0        XOR     EAX,EAX
DC61 C3            RET


; ---------------------------------------------------------
DC62 6651          PUSH    ECX
DC64 6650          PUSH    EAX
DC66 66B805000000  MOV     EAX,00000005
DC6C 1E            PUSH    DS
DC6D 07            POP     ES
DC6E 668BF9        MOV     EDI,ECX
DC71 E88DFD        CALL    DA01

DC74 668BC1        MOV     EAX,ECX
DC77 66BB20000000  MOV     EBX,00000020
DC7D 66B900000000  MOV     ECX,00000000
DC83 66BA00000000  MOV     EDX,00000000
DC89 E833F8        CALL    D4BF

DC8C 665B          POP     EBX
DC8E 6659          POP     ECX
DC90 6685C0        TEST    EAX,EAX
DC93 0F851500      JNZ     DCAC
DC97 668BC1        MOV     EAX,ECX
DC9A 660FB70E0C02  MOVZX   ECX,WORD PTR [020C]    ; "$I30" in Unicode.
DCA0 66BA0E020000  MOV     EDX,0000020E
DCA6 E816F8        CALL    D4BF

DCA9 EB33          JMP     DCDE

DCAB 90            NOP
DCAC 6633D2        XOR     EDX,EDX

; Ah! I need some strong tea; not "dcaf" !!!  ;-)
; ------------------------------------------------
DCAF 668BC1        MOV     EAX,ECX
DCB2 668BCB        MOV     ECX,EBX
DCB5 6650          PUSH    EAX
DCB7 6653          PUSH    EBX
DCB9 E82300        CALL    DCDF

DCBC 665B          POP     EBX
DCBE 665F          POP     EDI
DCC0 660BC0        OR      EAX,EAX
DCC3 0F841700      JZ      DCDE
DCC7 1E            PUSH    DS
DCC8 07            POP     ES
DCC9 E835FD        CALL    DA01

DCCC 668BC7        MOV     EAX,EDI
DCCF 660FB70E0C02  MOVZX   ECX,WORD PTR [020C]    ; "$I30" in Unicode.
DCD5 66BA0E020000  MOV     EDX,0000020E
DCDB E8E1F7        CALL    D4BF

DCDE C3            RET

; ------------------------------------------------
DCDF 6652          PUSH    EDX
DCE1 6651          PUSH    ECX
DCE3 66BB20000000  MOV     EBX,00000020
DCE9 66B900000000  MOV     ECX,00000000
DCEF 66BA00000000  MOV     EDX,00000000
DCF5 E8C7F7        CALL    D4BF

DCF8 660BC0        OR      EAX,EAX
DCFB 0F846300      JZ      DD62
DCFF 668BD8        MOV     EBX,EAX
DD02 1E            PUSH    DS
DD03 07            POP     ES
DD04 668B3E1602    MOV     EDI,[0216]
DD09 6633C0        XOR     EAX,EAX
DD0C E859F8        CALL    D568

DD0F 1E            PUSH    DS
DD10 07            POP     ES
DD11 668B1E1602    MOV     EBX,[0216]
DD16 6659          POP     ECX
DD18 665A          POP     EDX
DD1A 2666390F      CMP     ES:[BX],ECX
DD1E 0F850C00      JNZ     DD2E
DD22 2666395708    CMP     ES:[BX+08],EDX
DD27 0F843100      JZ      DD5C
DD2B EB13          JMP     DD40

DD2D 90            NOP


DD2E 2666833FFF    CMP     DWORD PTR ES:[BX],-01
DD33 0F842F00      JZ      DD66
DD37 26837F0400    CMP     WORD PTR ES:[BX+04],+00
DD3C 0F842600      JZ      DD66
DD40 26660FB74704  MOVZX   EAX,WORD PTR ES:[BX+04]
DD46 03D8          ADD     BX,AX
DD48 8BC3          MOV     AX,BX
DD4A 250080        AND     AX,8000
DD4D 74CB          JZ      DD1A
DD4F 8CC0          MOV     AX,ES
DD51 050008        ADD     AX,0800
DD54 8EC0          MOV     ES,AX
DD56 81E3FF7F      AND     BX,7FFF
DD5A EBBE          JMP     DD1A

DD5C 26668B4710    MOV     EAX,ES:[BX+10]
DD61 C3            RET

DD62 6659          POP     ECX
DD64 665A          POP     EDX
DD66 6633C0        XOR     EAX,EAX
DD69 C3            RET

DD6A A0F901        MOV     AL,[01F9]   ; Contains A0h (for English string)
                                       ; -> "NTLDR is missing"
DD6D E9F4F3        JMP     D164        ; DISPLAY MESSAGE

DD70 A0FA01        MOV     AL,[01FA]   ; Contains B3h (for English string)
                                       ; -> "NTLDR is compressed"
DD73 E9EEF3        JMP     D164        ; DISPLAY MESSAGE

Memory Location 0000:DD75 is the last byte of the NTLDR Section's new "Bootstrap" code.  


This page is still under construction . . . .

First Published: July 26, 2007 (26.07.2007).
Updated: 30 JAN 2009 (30.01.2009); 1 FEB 2009 (01.02.2009); there were many updates during JULY and AUGUST of 2015 (07.2015) and (08.2015).
Last Update: 30 AUGUST 2015 (01+.09.2015). [ There will be many updates during SEP as well! ]


 

  Back to The Starman's Realm MBR pages

The Starman's Realm Index Page