|
更新:制作显隐藏分区功能的软盘镜像文件工具,真正启动隐藏分区里的操作系统
干脆直接贴过来算了:
0100 jmp 013C
013C cli
013D xor ax, ax
013F mov ds, ax
0141 mov es, ax
0143 mov ss, ax
0145 mov ax, 7C00
0148 mov sp, ax
014A sti
014B push ax
014C mov ax, 1301
014F mov bx, 000A
0152 mov cx, 0068 //字符串长度
0155 mov dx, 1500
0158 mov bp, 7D94 //字符串地址为7D94-7c00+100=294,即文末
015B int 10 //显示字符串及属性
015D mov ah, 01
015F mov cx, 2000
0162 int 10 //设置光标形状
0164 mov si, 046C //BIOS数据区0040:006c存放着定时器的计数值
0167 mov edx, [si]
016A mov ecx, edx
016D add edx, 0000009F //设置等待时间
0174 mov ah, 01
0176 int 16 //判断字符是否存在
0178 je 0183 //没有则跳转
017A mov ah, 00
017C int 16 //如有则读字符,限83键盘,ah=10时支持扩展键盘
017E xor dx, dx //如果有按键,则dx=0
0180 jmp 01A0
0183 cmp ecx, [si]
0186 jnb 0195
0188 test cl, 01
018B je 0195
018D mov ax, 0E3E
0190 mov bx, 0004
0193 int 10 //显示字符0x3E ">"
0195 mov ecx, [si]
0198 cmp edx, ecx //定时器是否到时
019B jnb 0174
019D mov dx, FFFF //规定时间内无按键,则dx=0xFFFF
01A0 mov ah, 01
01A2 mov cx, 0D0E
01A5 int 10
01A7 mov bx, 0413
01AA mov ax, [bx]
01AC dec ax //直接减少0040:0013处的值, 减少可用内存的容量
01AD cmp dx, FFFF
01B1 je 01B5
01B3 mov [bx], ax //保存基本内存容量
01B5 shl ax, 06
01B8 mov es, ax //算出减1K后的高端段址
01BA pop si //si=7C00,ds:si(0000:7C00)
01BB push es
01BC xor di, di //目的地址es:di(es:0000)
01BE cld
01BF mov cx, 0100 //0x100个字,即本程序512字节搬移
01C2 repnz
01C3 movsw //字符移动
01C4 mov si, 004C //取中断向量表中,INT 13H的偏移位置
01C7 mov di, 0109 //即下面的0209,更改jmp 0000:0000为jmp 真正INT13地址
01CA mov eax, [si]
01CD mov es:[di], eax //保存原INT 13H的偏移位置
01D1 cmp dx, FFFF
01D5 je 01E3 //如果从硬盘启动则跳转,即不接替INT 13
01D7 push es
01D8 pop ax
01D9 shl eax, 10
01DD mov ax, 011B
01E0 mov [si], eax //更改INT 13H的偏移位置为下面的021B
01E3 push ds
01E4 pop es
01E5 mov bx, 00EA
01E8 push bx
01E9 retf //ip=00EA,cs=es,实际为执行下面的01EA
01EA cmp dx, FFFF
01EE je 01F9
01F0 mov cx, 4F12
01F3 mov dx, 0100 //从软盘启动,0面79道18扇区
01F6 jmp 01FF
01F9 mov cx, 0001 //从硬盘启动,0面0道1扇区
01FC mov dx, 0080
01FF mov ax, 0201
0202 mov bx, 7C00 //读1个扇区到7C00
0205 pushf
0206 push ds //ds=0000
0207 push bx //bx=7C00,INT 13返回后跳转到0000:7C00
0208 jmp 0000:0000 //01CD处修改后成为INT 13
020D-021A 11 01 14 04 16 06 17 07 1B 0B 1C 0C 1E 0E //分区类型表
021B cmp ah, 02 //老的读扇区功能
021E jne 0231
0220 cmp dx, 0080
0224 jne 0231
0226 cmp cx, 0001
022A je 024F //读硬盘BOOT扇区
022C cmp ah, 42 //扩展读功能,×××这里似乎不可能到达×××
022F je 0234
0231 jmp 0208
0234 push eax
0236 xor eax, eax
0239 cmp [di+08], eax
023D jne 024A
023F cmp [di+0C], eax
0243 jne 024A
0245 pop eax
0247 jmp 024F
024A pop eax
024C jmp 0231
024F pushf
0250 push cs
0251 call 0208
0254 jb 0293
0256 push es
0257 push ds
0258 push ax
0259 push bx
025A push cx
025B push cs
025C pop ds
025D cmp ah, 42 //扩展读功能
0260 jne 026B
0262 mov bx, [di+04]
0265 mov es, [di+06]
0268 jmp 026B
026B add bx, 01C2
026F mov cx, 0004 //4个主分区
0272 mov si, 010D //分区类型表地址020D-021A
0275 cld
0276 lodsw //ds:si到ax,ds=cs代码段址
0277 cmp si, 011B
027B jnb 0288 //直到类型表比较完成
027D cmp es:[bx], al //比较是否为隐藏分区
0280 jne 0275
0282 mov es:[bx], ah //将隐藏分区改为非隐藏
0285 jmp 0275
0288 add bx, 0010 //第个分区表0x10字节
028C loop 0272 //4个分区表逐一检查
028E pop cx
028F pop bx
0290 pop ax
0291 pop ds
0292 pop es
0293 iret
Yisir Restore Tool Loader, yisir.9126.com
Press any key to load RESTORE DISK or BOOT from HARDDISK...
0x00 0x00 0x55 0xAA
---------------------------------------
建议版主以后直接发带注释的源程序,以便大家完善,看汇编代码本来就很费神,我都没这么好的耐心,相信别人也不轻松。
另外
0208 jmp 0000:0000 //01CD处修改后成为INT 13
020D-021A 11 01 14 04 16 06 17 07 1B 0B 1C 0C 1E 0E //分区类型表
021B cmp ah, 02 //老的读扇区功能
021E jne 0231
0220 cmp dx, 0080
0224 jne 0231
0226 cmp cx, 0001
022A je 024F //读硬盘BOOT扇区
022C cmp ah, 42 //扩展读功能,×××这里似乎不可能到达×××
022F je 0234
0231 jmp 0208
请楼主看一下,从021B处判断ah是否为02号功能,不是则执行int 13,是则往下执行,但ah不可能变成42h吧,那022C处岂不有问题?
----------------------------------
020D-021A 11 01 14 04 16 06 17 07 1B 0B 1C 0C 1E 0E 为分区类型表
026F mov cx, 0004 //4个主分区
0272 mov si, 010D //分区类型表地址020D-021A
0275 cld
0276 lodsw //ds:si到ax,ds=cs代码段址
0277 cmp si, 011B
027B jnb 0288 //直到类型表比较完成
027D cmp es:[bx], al //比较是否为隐藏分区
0280 jne 0275
0282 mov es:[bx], ah //将隐藏分区改为非隐藏
0285 jmp 0275
0288 add bx, 0010 //第个分区表0x10字节
028C loop 0272 //4个分区表逐一检查
从026F起检查分区表类型,个人认为只要检测最后一个分区即可,很少有人将中间的分区隐藏的。
从分区表类型看,隐藏与非隐藏差别为bit4,所有类型可合并为一种,即:
if (al and 0xF0)=0x10 then 分区类型=(al and 0x0F) |
|