精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>嵌入式开发>>Windows XP的BootSector反向工程

主题:Windows XP的BootSector反向工程
发信人: wenbobo()
整理人: wenbobo(2003-01-10 10:28:31), 站内信件
以下是今晚的初步反汇编,但目前有几条指令(大概是jxx吧),只是做到了意图一致,再次汇编后指令长度不一致,暂时没能完全还原:(

而且,就算你修改了,也千万注意,这是我的硬盘分区上的BootSector,FAT32表格和你的肯定不同,千万不要直接覆盖自己的0扇区,否则……哭吧

另外一个很烦人的问题某些指令,比如原版的xor ax, ax用0x33指令,我用nasm编译怎么都是0x31,虽然都是一样的,但是……也就意味着我再努力也不可能完全的用这段asm“还原”出本来的引导扇区了。微软的工程师很变态,只因为0x33比0x31快1个时钟周期就强制编译器用0x33,辛苦省下的时间谁能感觉得到?


不过基本已经理清头绪,作为一个参考范例,还是值得一看得。大家注意,M$用了INT 13H扩展函数,没有这个函数的话将莫名其妙的显示错误:“Disk error”,哈哈,应该是BIOS Error吧。也就是说,某些旧版本的BIOS根本就不能跑XP!不过42H这个调用的确功能很强大,大大的减少了代码量,值得一用!

由于习惯,注释没有用中文,希望大家能够习惯。

; Boot Sector
; Base Address :    0000h 
; Range        :    7C00h - 7DFFh 
; Loaded length:    0200h

    org 0x7C00

    jmp    short start
    nop
    
    OemName                    db    "MSWIN4.1"      ;03
    BytesPerSector             dw    0x200           ;0B
    SectorsPerCluster          db    0x20            ;0D
    ReservedSectors            dw    0x20            ;0E    
    Fats                       db    0x02            ;10
    RootEntries_n32            dw    0x00            ;11
    TotalSectorsLow_n32        dw    0x00            ;13
    MediaDescriptor            db    0xF8            ;15    - f0: 1.4 MB floppy, f8: hard disk
    SectorsPerFat_n32          dw    0x00            ;16 - 0: fat32, 9:fat12/fat16
    SectorsPerHeadTrack        dw    0x3F            ;18 - Sectors per head/track
    HeadsPerCylinder           dw    0xFF            ;1A
    HiddenSectors              dd    0x3F            ;1C
    TotalSectorsHigh           dd    0x038A7FB3      ;20 - Total number of sectors
    SectorsPerFat_32           dd    0x000038A2      ;24 - Sector per FAT (FAT32)
    Flags                      dw    0x00            ;28 - Flags (FAT32)
    Version                    dw    0x00            ;2A - FS Version (FAT32)
    RootStartCluster           dd    0x02            ;2C - Root start cluster (FAT32)
    FsInfoSector               dw    0x01            ;30 - FS Info Sector (FAT32)
    BackupBootRecord           dw    0x06            ;32 - Backup Boot Record
    
    times    12                db    0xF6            ;Unused ???
    
    BiosDriveNumber            db    0x80            ;40 - BIOS drive number
    HeadTempNumber             db    0x00            ;41 - Head/temp number????
    ExtendedBootRecordSign     db    0x29            ;42 - Extended Boot Record sig.
    VolumeSerialNumber         dd    0x3D0F93EB      ;43 - Volume serial number
    VolumeLabel                db    'DISK2_1    '   ;47 - Volume label
    FileSystemId               db    'FAT32   '      ;52 - File System ID

start:        ; .text:7C00
    xor    cx, cx
    mov    ss, cx
    ;assume ss:seg000
    mov    sp, 7BF4h        ; stack here ?
    mov    es, cx
    mov    ds, cx
    mov    bp, 7C00h
    mov    [bp+2],    cl        ; NOP here, used as cReadCount;
    mov    dl, [bp+40h]    ; BIOS drive number
    mov    ah, 8
    int    13h    ; DISK - DISK -    GET CURRENT DRIVE PARAMETERS (XT,AT,XT286,CONV,PS)
            ; DL = drive number
            ; Return: 
            ; CF set on error
            ; AH =    status code, AL = 0(maybe)
            ; BL = drive type
            ; CH = low eight bits of maximum cylinder number
            ; CL = maximum sector number (bits 5-0)
            ;      high two bits of maximum cylinder number (bits 7-6)
            ; DH = maximum value for head number
            ; DL = number of consecutive drives
            ; ES:DI -> drive parameter
    jnb    GetDriveParamSuccess
    
    ; God!~~~~failed ?
    mov    cx, 0FFFFh
    mov    dh, cl        ; set to MAX values, maybe bug ??

GetDriveParamSuccess:        
    ; .text:7C72
    movzx    eax, dh
    inc    ax                    ; ax = HeadsNumber
    movzx    edx, cl
    and    dl, 3Fh                ; dx = SectorsNumber 
    mul    dx                    ; eax = dx * ax = total sectors per cylinder
    xchg    cl, ch
    shr    ch, 6
    inc    cx
    movzx    ecx, cx                ; cx = CylinderNumber
    mul    ecx                        ; eax = TotalSectors
    mov    [bp-8],    eax                ; Save it
    cmp    word [bp+16h], 0    ; Is FAT32?
    jnz    PrintMissNtLoader        ; No, display error
    cmp    word [bp+2Ah], 0    ; FS Version = 0 ?
    ja    PrintMissNtLoader        ; No, display error
    mov    eax, [bp+1Ch]            ; Hidden sectors
    add    eax, 0Ch                ; Read from: HiddenSectors + 12
    mov    bx, 8000h                ; Save KernelLoader to this address
    mov    cx, 1
    call    ReadLoader
    jmp    near 8000h            ; Run KernelLoader
; -----------------------------------------------------------------------------

PrintDiskError:        ; .text:7D60
    mov    al, [ds:0x7DFA]

PrintString:        ; jump from 7CD4, 7CD9
    mov    ah, 7Dh    ;
    mov    si, ax

PrintNextChar:        ; .text:7CCF
    lodsb
    test    al, al
    jz    Reboot
    cmp    al, 0FFh
    jz    PrintRebootHint
    mov    ah, 0Eh
    mov    bx, 7
    int    10h    ; - VIDEO - WRITE CHARACTER AND    ADVANCE    CURSOR (TTY WRITE)
            ; AL = character, BH = display page (alpha modes)
            ; BL = foreground color    (graphics modes)
    jmp    short PrintNextChar
; -----------------------------------------------------------------------------

PrintRebootHint:        ; .text:7CC6
    mov    al, [ds:7DFBh]
    jmp    short PrintString
; -----------------------------------------------------------------------------

PrintMissNtLoader:        ; jump from 7C9C, 7CA2
    mov    al, [ds:7DF9h]
    jmp    short PrintString
; -----------------------------------------------------------------------------

Reboot:        ; .text:7CC2
    cbw
    int    16h    ; KEYBOARD - wait key press
    int    19h    ; DISK BOOT
            ; causes reboot    of disk    system

ReadLoader:        ; called from 7CB2 return at 7D6B
    pushad
    cmp    eax, [bp-8]                ; TotalSectors < StartAddress ?
jb ReadComplete ; Yes, read complete
push dword 0
push eax
push es
push bx
push dword 10010h
cmp byte [bp+2], 0 ; cReadCount == 0 ?
jnz ExterndedReadDisk ; No, jump to externded read
mov ah, 41h ;
mov bx, 55AAh
mov dl, [bp+40h]
int 13h ; DISK - Check INT 13H Extensions API
jb near NoInt13Extensions ; Not installed
cmp bx, 0AA55h ; bx = aa55 ?
jnz near NoInt13Extensions ; No, not installed
test cl, 1 ; extended disk access functions (AH=42h-44h,47h,48h) supported ?
jz near NoInt13Extensions ; no, not supported
inc byte [bp+2] ; yes, supported!

ExterndedReadDisk: ; .text:7CFB
mov ah, 42h
mov dl, [bp+40h] ;drive number
mov si, sp ;si = 7BF4->disk address packet struct:
    int    13h    ; DISK - INT 13 Extensions - EXTENDED READ

    db 0xB0        ;mov    al, 0F9h
NoInt13Extensions:    
    db 0xF9        ;stc    
    pop    eax
    pop    eax
    pop    eax
    pop    eax
    jmp    short DiskError
; -----------------------------------------------------------------------------

ReadComplete:        ; .text:7CE6
    xor    edx, edx
    movzx    ecx, word [bp+18h]
    div    ecx
    inc    dl
    mov    cl, dl
    mov    edx, eax
    shr    edx, 10h
    div    word [bp+1Ah]
    xchg    dl, dh
    mov    dl, [bp+40h]
    mov    ch, al
    shl    ah, 6
    or    cl, ah
    mov    ax, 201h
    int    13h    ; DISK - READ SECTORS INTO MEMORY
            ; AL = number of sectors to read, CH = track, CL = sector
            ; DH = head, DL    = drive, ES:BX -> buffer to fill
            ; Return: CF set on error, AH =    status,    AL = number of sectors read

DiskError:        ; .text:7D32
    popad
    jb    near PrintDiskError    ; jump if error 
    add    bx, 200h        ; else continue to read
    inc    eax
    dec    cx
    jnz    near ReadLoader
    retn
; -----------------------------------------------------------------------------
    FileName db "NTLDR      "
    times 49 db 0
    StrMissFile        db 0x0d, 0x0a, "NTLDR is missing", 0xff
    StrDiskError    db 0x0d, 0x0a, "Disk error", 0xff
    StrRestart        db 0x0d, 0x0a, "Press any key to restart", 0x0d, 0x0a
    times 17 db 0
    db 0ACh    ; Error Hint: StrMissFile       
    db 0BFh    ; Error Hint: StrDiskError
    db 0CCh    ; Error Hint: StrRestart
    times 2 db 0
    db    0x55, 0xAA    ;the end

[关闭][返回]