2010年3月4日 星期四

在安裝DOS的硬碟,將MBR讀出,並反組譯



http://www.pczone.com.tw/vbb3/archive/t-51849.html這裡的code比較多,這是用光碟安裝xp時,寫入mbrㄉ狀況;但此連結也有很多可參考的資訊。以下這一小段程式可能比較適合理解mbr的Boot Partition Loader ,這是我用virtualBoxㄉ虛擬dos執行fdisk後將虛擬HD分割為單一顆後,並用spfdisk將磁註0磁頭0磁區1的MBR共512bytes儲存,並反組譯所得到的程式碼如下。
參考以下的CODE必須參照上圖。

.386
seg000 segment byte public '' use16
assume cs:seg000
assume es:nothing, ss:nothing, ds:nothing, fs:nothing, gs:nothing
cli ;關閉中斷
xor ax, ax ;ax=0
mov ss, ax ;ss=0
mov sp, 7C00h ;sp=7c00h
mov si, sp ;si=7c00h
push ax
pop es ;將es設為0
push ax
pop ds ;將ds設為0
sti ;啟用中斷
cld ;清除方向旗標,使si di隨位址遞增
mov di, 600h ;設di=600h
mov cx, 100h ;設cx=100h,目的當成計數器
repne movsw ;重覆搬移100h次,每次搬移2bytes,來源ds:si -->0000:7c00h 目的es:di -->0000:0600h 因此共搬移512bytes
jmp far ptr 0:61Dh ;長跳躍到0000:061dh

mov si, 7BEh ;7beh - 600h = 1beh,也就是說si指到位移值 01BE ~ 01CD <-- 第一分割表
mov bl, 4 ;設定bl=4
next:
cmp byte ptr [si], 80h ;比對first_partition第一ㄍbyte是否為80h
jz is_a_boot_partition
cmp byte ptr [si], 0 ;比對first_partition第一ㄍbyte是否為00h
jnz invalid_table
add si, 10h ;將si指到下一ㄍ分割表
dec bl ;bl減1
jnz next
int 18h ; TRANSFER TO ROM BASIC
; causes transfer to ROM-based BASIC (IBM-PC)
; often reboots a compatible; often has no effect at all
is_a_boot_partition:
mov dx, [si] ;設dx=80h ,也就是DH=01 DL=80H 請參考first_partition
mov cx, [si+2] ;設cx=01h ,也就是CH=00 CL=01H 等一下讀取硬諜時會用到,可參考first_partition 分割開始之磁區編號 (6 bits) 最高的 2 個 bits(bit6-7), 為磁柱編號的 bit8-9
mov bp, si ;將bp設為指向first_partition

next_partition:
add si, 10h
dec bl
jz chk_set_OK
cmp byte ptr [si], 0
jz next_partition

invalid_table:
mov si, 68Bh ;68B指到str_invalid

show_msg:
lodsb ;以下幾行code是呼叫int 10h顯示單一字元
cmp al, 0
jz Exit
push si
mov bx, 7
mov ah, 0Eh
int 10h
; - VIDEO - WRITE CHARACTER AND
; AL = character, BH = display page (alpha modes)
; BL = foreground color (graphics modes)
pop si
jmp show_msg
; ---------------------------------------------------------------------------

Exit:
jmp Exit ;無窮迴圈 程式停在此處
; ---------------------------------------------------------------------------

chk_set_OK:
mov di, 5

repeat_5time:
;這個中斷程式的spec:http://lrs.uni-passau.de/support/doc/interrupt-57/RB-0569.HTM
mov bx, 7C00h ;
mov ax, 201h ;讀取1ㄍ磁區
push di
int 13h ; 讀取 磁頭head=1 drive=80H 磁軌track=0 磁區sector=1(*****此處就是dos作業系統INSTALL的啟始位置*****)
; 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
pop di
jnb drive_read_OK
xor ax, ax
int 13h ; DISK - RESET DISK SYSTEM
; DL = drive (if bit 7 is set both hard disks and floppy disks reset)
dec di
jnz repeat_5time
mov si, 6A3h ;6A3h指向str_err_loading "Error loading operating system"
jmp short show_msg
; ---------------------------------------------------------------------------

drive_read_OK:
mov si, 6C2h ;6c2h指向str_miss_OS "Missing operating system"
mov di, 7DFEh ;7DFEh指向55aa之55位置
cmp word ptr [di], 0AA55h ;比對是否510及511位置是否為55aa
jnz short show_msg ;若不是55AA便顯示"Missing operating system"
mov si, bp
jmp far ptr 0:7C00h ; 轉移控制權到 0000:7C00H 程式到止結束;注意,此時的0000:7C00H已經更新為剛才重新讀取的磁頭head=1 drive=80H 磁軌track=0 磁區sector=1,因此這裡也就是進入dos作業系統的指令。
; ---------------------------------------------------------------------------
str_invalid db 'Invalid partition table',0
str_err_loading db 'Error loading operating system',0
str_miss_OS db 'Missing operating system',0
db 0
db 88h ;
db 74h ;
db 63h ;
db 3Ch ;
db 222 dup(0)
first_partition db 80h,01h,01h,00h,06h,1Fh,0BFh,07h,3Fh,00h,00h,00h,0C1h,0FEh,0Fh, 00h
db 30h dup(0)
db 55h, 0AAh ;55aa標示符號
seg000 ends

end
--> 閱讀更多...