| 
 | 
更新:制作显隐藏分区功能的软盘镜像文件工具,真正启动隐藏分区里的操作系统
干脆直接贴过来算了: 
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) |   
 
 
 
 |