|
更新:制作显隐藏分区功能的软盘镜像文件工具,真正启动隐藏分区里的操作系统
感谢各位朋友的关注,为方便感兴趣的朋友改进,源程序开放。先公开引导区模块(HFBOOT.ASM)的源程序。
在写这个程序之前,我看到了很多“一键恢复”的介绍,这些工具里面以IBM技术为基础的为多。网上搜索到关于IBM“F11”键恢复的文章很多,可是多数是讲如何修复IBM的,觉得程序写在MBR里面是不妥的,很容易被破坏。另外IBM虽然没有追究大家的盗版使用责任,可是这也不是长久的。我于是决定写一个与之功能相似的程序,让大家测试和使用。我在写程序时思考了IBM“F11”键恢复的原理,可是我并没有反汇编和阅读IBM的代码,因此完全是自己写的,没有那些多麻烦。但是正因为只是自己一个人写的,所以不一定象IBM一样有过充分的测试,尽管我在程序中没有任何写硬盘的代码(可参看源代码),但使用此程序的风险还是存在的。希望朋友们在充分测试(虚拟机、空闲硬盘……)后再正式使用它!
还是那句老话,本人保留对原始程序的所有权。你可以自由阅读和修改你认为可以改进的地方,但是请在重新发布时保留原作者的信息,并且我希望你能将源文件公开并告诉我(turboy@163.com),保持这个工具的一贯作风。
这里是本人网站上语法加亮的源程序:http://yisir.softhome.cn/yiarticle/act.php?obj=article&id=136
下面是引导区模块(HFBOOT.ASM)的源程序:; ==========================================================================
; 这是一个用来引导我的系统备份/恢复光盘的启动软盘的程序,将会放在软盘的第一
; 个扇区内。此程序引导系统时,出现一个提示,用户可选择按任意键启动工具软盘,
; 也可以在等待8秒后引导硬盘上的操作系统。在选择由工具软盘启动DOS后,在MBR中
; 隐藏的FAT32主分区(0B/0C)将会分配盘符变得可见,这就可以用常规工具来做备
; 份了——备份在隐藏分区里,看谁能删得掉!
; 最后版本:2005/9/5
; ==========================================================================
; 编程记录:
; 6月29日的版本只处理了传统INT13的2号功能,所以在虚拟机中的小硬盘(1B-FAT32)
; 中调试正常,一到了用LBA方式读取的分区(1C-FAT32LBA,1E-FAT16LBA)就完了。可是
; 现在的硬盘已经没有8GB以下的了,读取也几乎全是用LBA方式了。
;
; 7月23日:
; 加入对扩展INT3读取(42号)功能的接管,实现对隐藏LBA分区的读取,由于现
; 在硬盘分区几乎没有用FAT16的了,所以只处理了FAT32的。
; 由于新代码的加入,我原来的提示信息也不得已剪了一部分。
;
; 8月22日:
; 加入一个可识别分区标志码列表(FlagTable),逐一判断处理。
; 在FlagTable DW xxyy中,每一个字中的xx代表原始分区标志码,yy代表隐藏时的分区标志码
; 如0414h代表原始分区为04h(FAT12),隐藏时的分区标志码为14h
; 现在,可以无限扩充了。
;
; 8月28日:
; 试验加入从隐藏分区启动的功能。
; 1、在启动后利用自己的INT13将原分区激活标志改为00,将能改为正常分区的原隐
;藏分区的激活标志改为80。
; 2、在安装前判断按键,用DX寄存器作为标志,无按键DX=0XFFFF,按F7时DX=1,
; INT13中CH=1,按其他键时DX=0,INT13中CH=0。
; 3、在INT13中,使用CH作为是否激活隐藏分区的判断标志,为1时从隐藏分区启动。
; 3、由于BOCHS虚拟机使用了F11和F12两个键,故设定按F7键由隐藏分区启动。
;
; 8月31日:
; crshen发现了几个BUG,现在一一解决。从隐藏分区启动的功能。
; 1、读不出F11是因为INT10H的0号功能不支持扩展键盘,现在改为10H号功能。可是
; 在QEMU中10号功能也不能读F11,而VPC却可以,可能是两者的BIOS不同或QEMU拦截
; 了F11/F12吧。
; 2、在安装前判断按键,如果按ESC键,则直接进入硬盘启动。
; 3、有一个判断跳转有误,致使INT13H的42H功能处理无效,我大意了,在加入处理
; 42H功能代码时忘了改前面的代码。
; 4、不能从8G以后的隐藏分区启动是因为在我的INT13过程中有一个严重的错误,这
; 个错误是由于我参考的资料有误而引入的。 在INT13H扩展功能中是用DS:SI来指向
; DAP的, 而不是那篇资料中说的DS:DI。这可真是……
; 在MS-FDISK、FREE-FDISK、AEFDISK、PQMAGIC、Acronis Disk Editor等大多数
; 程序中隐藏分区都会以正常分区显示,但GDISK却可以看出此分区为隐藏分区,
; GDISK一定有超越BIOS中断的独特存取硬盘方法。
; 9月1日:
; 目前9-2 0:47我已经将可能想到的BUG全部排除了, 而程序的长度也接近512字节的
; 极限了。
; 1、又发现原来的程序中有一处死码,是在调用原INT13中断后,AH已被作为返回值
; 了,却还在用AH判断扩展INT13,所以后面处理扩展INT13功能的代码就不会运行了。
; 修改成将AX压栈保存,但代码就更乱了,于是重写了前面的代码。
; 2、跟踪、思考了两天,才发现不能在机房的P4上启动隐藏分区上的OS的原因竟是原
; 来玩的一个技巧。真是聪明反被聪明误啊!
; 3、改变了开始时判断方式,DX中,DH=0安装INT13,DH=FFH不安装;DL=0载入软盘
; 引导记录启动,DL=80H载入硬盘MBR启动
; 4、新加入一个功能ESC键:可以不加载本程序,正常从硬盘盘启动,以用于一般情
; 况。
; 5、新加入一个功能F5键:可以不加载本程序,正常从软盘盘启动,以用于一般情况。
; ==========================================================================
;GoodFlag1 equ 0bh
;HideFlag1 equ 1bh
;GoodFlag2 equ 0ch
;HideFlag2 equ 1ch
;GoodFlag3 equ 0eh
;HideFlag3 equ 1eh
ORIGIN EQU 7C00H; Origin of bootstrap LOADER
BIO_MEMEQU 0413H; BIOS Memory size =640(KB)
BIO_CLKEQU 046CH; BIOS Clock (1/18.2 seconds)
DSK_PARMSEQU 1EH*4;POINTER TO DRIVE PARAMETERS
KEY_BOOTHIDDENEQU 41H;Scancode: F7=41H, F11=85H, F12=86H
KEY_BOOTFLOPPYEQU 3FH;Scancode: F5=3FH
KEY_ESCAPEEQU 01H;Scancode: ESC=01H
BOOTHIDDENFLAGEQU 80h
ORG0000h
START:
; WARNING -- Don change this to a short jmp
jmp short main; Jump to start of code
nop
; ==========================================================================
; Start of BPB area of the boot record
OemName DB "MSDOS"
OsVersion DB "5.0"; DOS version number
BPB:
BytesPerSector DW 512; Size of a physical sector
SecsPerClust DB 1; Sectors per allocation unit
ReservedSecs DW 1; Number of reserved sectors
NumFatsDB 2; Number of fats
NumDirEntries DW 00E0h; Number of direc entries
TotalSectors DW 0B40H; Number of sectors - number of hidden
; sectors (0 when 32 bit sector number)
MediaByte DB 0F0H; MediaByte byte
NumFatSecs DW 9; Number of fat sectors
SecPerTrack DW 18; Sectors per track
NumHeads DW 2; Number of drive heads
HiddenSecs DD 0; Number of hidden sectors
BigTotalSecs DD 0; 32 bit version of number of sectors
BootDrv DB 0h
CurrentHead DB 0h; Current Head
ExtBootSig DB 41
SerialNum DD 20050628h
VolumeLabel DB "YISIR_LOADER"
FatId DB "FAT12"
; =========================================================================
; First thing is to reset the stack to a better and more known
; place. The ROM may change, but wed like to get the stack
; in the correct place.
main:
cli;Stop interrupts till stack ok
xor AX,AX
mov ds,ax
mov es,ax
mov SS,AX;Work in stack just below this routine
mov ax,ORIGIN
mov sp,ax
sti
PUSH AX
;Show message
mov ax,1301h
mov bx,000ah
mov cx,MyMsgLen
mov dx,1500h
mov bp,MyMsg+ORIGIN
int 10h
;Hide the cursor
mov ah,1
mov cx,2000h
int 10h
;Wait 10 seconds
mov si, BIO_CLK
mov edx, dword [si]
mov ecx, edx
add edx, 159;18.2*10 seconds
ReadKB:
;Change 5 bytes with install option
;Case Option:/f Boot from floppy disk directly, do not waiting 8 seconds
;31H D2Hxor dx,dx
;E9H xxH 00Hjmp BiosMemory
;
;Case Option:/b Boot from HIDDEN parition derectly (activate it and load it)
;31H D2Hxor dx,dx
;E9H xxH 00Hjmp Key_F7
;
;Case Default: Show message and wait 8 second
mov ah, 11h;Get keyboard status
int 16h
jz NoKeyPress
mov ah,10h;Read a key (In old code, AH=0, can not read F11/F12...)
int 16h
xor dx,dx
cmp ah, KEY_ESCAPE
jz DX_HD;Press ESC to BOOT from Harddisk
cmp ah, KEY_BOOTFLOPPY
jnz RKB_1
mov dh, 0ffh;dh=0 Install INT13, else do not Install. Now DX=FF00H
jmp BiosMemory
RKB_1:
cmp ah, KEY_BOOTHIDDEN
jnz BiosMemory
Key_F7:
;If press Hot key, Boot From Hidden Partition. Now DX=0001H
;modify CH=80h in Int13 procedure
mov byte[ORIGIN+2+BootHiddenCode], BOOTHIDDENFLAG
jmp DX_HD
NoKeyPress:
cmp ecx, dword [si]
jae L_0
test cl,1
jz L_0
mov ax,0e3eh; write ">" to show progressing
mov bx,0004h
int 10h
L_0:
mov ecx, dword [si]
cmp edx,ecx
jae ReadKB
mov dh,0ffh;Do not install INT13. Now DX=FF00
DX_HD:
mov dl,080h;Boot from HD.
;DH=0 Install INT13, DH=FFH do not Install
;DL=0 Boot Floppy, DL=80H Boot HD
;Now:
; ESC DX=FF80, F5 DX=FF00H, F7 DX=0080H, ANYKEY DX=0000H, TIMEOUT DX=FF80H
BiosMemory:
;Show the cursor
mov ah,1
mov cx,0d0eh
int 10h
;BIOS MEMORY - 2KB
mov bx,BIO_MEM;bx=280H (KB)
mov ax,word [bx]
dec ax
cmp dh,0
jnz L_1
mov word [bx],ax;If DH=FF, Do not install
L_1:
;Move to High Memory. ex. 9fc0:0000
shl ax,6;ax=9fc0h SEG of top memory
mov es,ax;es=9fc0h
pop si;si=7c00h
push es;ready to RETF
xor di,di;di=0
cld
mov cx,100h
repnz movsw;move code to 9fc0:0000
cmp dh,0
jnz L_2;If DH=0ffh, Do not install
;modify Int13
mov si,4ch;Int13 13h*4
mov di,OLDINT13
;Save Old
mov eax,[si]
mov [es:di],eax
;cmp dh,0
;jnz L_2;If DH=0ffh, Do not install
push es
pop ax
shl eax,16
mov ax, MyInt13
mov [si],eax
L_2:;Jump to high address, 9fc0:00xx
push ds
pop es
mov bx,word Entre2
push bx;push 9fc0:Entre2
retf;跳到高端执行
Entre2:
cmp dl,0;If DX <> 0, Load HD-MBR
jnz L_3
ReadFD:;Read old boot sector from Floppy H1 T79 S18
mov cx,4f12h
mov dx,0100h
jmp RunInt13
L_3:;Read from Harddisk H0 T0 S1 MBR
mov cx,1
mov dx,80h
RunInt13:
mov ax,0201h
mov bx,ORIGIN
push ds
push bx
int 13h
retf
; 2005-9-1
; 这里是原来用的花哨技巧代码,就是它们导致使用F7启动不了隐藏分区。因为这里读到的是原始的MBR
; pushf ;int 13h
; push ds
; push bx
; ------------------------------------------
;Jump to Old INT 13H
JmpFarInt13:
DB 0eah ;JMP far OLDINT13
OLDINT13 DW 0,0
;End of Install-code
;Partition Flag Table normal and hidden
FlagTable:
dw 0111h, 0414h, 0616h, 0717h, 0b1bh, 0c1ch, 0e1eh
FlagTableEnd:
;My INT13h code
MyInt13:
cmp ah,2 ;Is Read?
jz Func2
cmp ah,42h ;Is ExtRead?
jz Func42
JmpOldInt13:
jmp JmpFarInt13
Func2:
CMP DX,0080H;Is Harddisk and Head 0?
jnz JmpOldInt13
cmp cx,0001H;Is Track 0 Sector 1?
jnz JmpOldInt13
pushf;Simulate INT operator
push cs
CALL JmpFarInt13;Call old INT13
jc exit;Flase then Exit
push bx
push es
jmp EditFlag
Func42:
cmp dl,80h;Is Harddisk
jnz JmpOldInt13
push eax
xor eax,eax
cmp dword [si+8],eax;Is Sector 0, Low 32bit
jnz ExitFunc42
cmp dword [si+12],eax;Is Sector 0, Hight 32bit
jnz ExitFunc42
pop eax
pushf;Simulate INT operator
push cs
CALL JmpFarInt13;Call old INT13
jc exit;If flase then Exit
push bx
push es
mov bx, [si+4]; Fix BX,ES like Int13h Func02
mov es, [si+6]
jmp EditFlag
ExitFunc42:
pop eax
jmp JmpOldInt13
EditFlag:
push ax
push cx
push si; DS:SI -> DAP
push ds
push cs
pop ds
add bx, 01c2h; ES:BX -> Partition Flag
BootHiddenCode:
mov cx, 4; CL=4, CH will can be change by Makeimg.c with 1 to Modify the ActiveFlag
cmp1:
mov si, FlagTable
cmp ch, BOOTHIDDENFLAG;If CH=BOOTHIDDENFLAG, Boot from hidden Partition
jnz nextFlag
mov byte [es:bx-4], 0;Clear Active Flag for boot from hidden partition
nextFlag:
cld
lodsw
cmp si, FlagTableEnd
jae nextPart
cmp byte [es:bx], al
jnz nextFlag
mov byte [es:bx], ah
cmp ch,BOOTHIDDENFLAG;If CH=BOOTHIDDENFLAG, Boot from hidden Partition
jnz JmpNextFlag
mov byte [es:bx-4], 80h
xor ch, ch;Set CH=0h, Don';t modify the next.
JmpNextFlag:
jmp nextFlag
nextPart:
add bx,10h
dec cl
ja cmp1
pop ds
pop si
pop cx
pop ax
pop es
pop bx
exit:
iret
; End of INT13H code
MyMsg db "PartUnhide Loader, yisir.9126.com, 2005-9-5",13,10
; db "Press any key to load RESTORE FLOPPY DISK...",13,10
MyMsgLen equ $-MyMsg
times 510 -($-$$) db 0
BOOTFLAG db 55h,0aah |
|