Board logo

标题: DOS启动后用隐藏分区数据的程序,源码公开了! [打印本页]

作者: TurboY     时间: 2005-7-23 23:04    标题: DOS启动后用隐藏分区数据的程序,源码公开了!

  我去年曾发过一个帖子那位有办法能在DOS中让隐藏分区可见吗?,里面提到了两个思路:
  第一种思路:在系统恢复盘的引导扇区中加入一段程序,它驻留内存后接管Int13H,凡是对备份分区的ID的读取(1BH),均返回0BH即可见分区。后来的DOS启动后,此分区自然可见了。这是类似引导型病毒的做法。
  第二种思路:在系统恢复盘的DOS启动后,由一个程序查找隐藏的备份分区,并将它作为一个正常的FAT32分区添加到DOS的设备链上,并赋以相应的盘符。这是类似NTFS4DOS的做法。

  希望有人能够利用这个思路做点工具出来,可是很久还是没有见到,我自己也懒得理了,开始用批处理来查找分区供GHOST调用。
  今年又看到这个帖子,终于不想偷懒,由于我对DOS的细节还是不清楚,就写个引导程序来做了。终于有了结果,在Bochs-2.1.1和VM里测试通过,能够欺骗DOS在启动后为1B和1C格式的隐藏分区分配盘符。在这里拿出来希望朋友们能够帮忙用多余的真实硬盘测试一下。(特别提醒,我保证程序中没有写MBR的代码,可是难保一切意外的发生,最好用没保存重要数据的真实硬盘来做!)
  下载地址:
已经改成8月23日编译的了,见附件。
  测试方法:
  解压下载的ZIP文件,准备一个启动盘镜像文件。
  运行解压目录里的镜像修改程序,格式
    MAKEIMG <原镜像文件> <新镜像文件>
  生成的新镜像文件即可在虚拟机中测试,如要在真实机器里测试可写入软盘或用VFLOPPY等软件来做。

  VMware截图:




下面是编程的记录:
  这是一个用来引导我的系统备份/恢复光盘的启动软盘的程序,将会放在软盘的第一个扇区内。此程序引导系统时,出现一个提示,用户可选择按任意键启动工具软盘,也可以在等待8秒后引导硬盘上的操作系统。在选择由工具软盘启动DOS后,在MBR中隐藏的FAT32主分区(0B/0C)将会分配盘符变得可见,这就可以用常规工具来做备份了——备份在隐藏分区里,看谁能删得掉!
最后版本:2005/7/23 2005/6/29
后记:
  6月29日的版本只处理了传统INT13的2号功能,所以在虚拟机中的小硬盘(1B-FAT32)中调试正常,一到了用LBA方式读取的分区(1C-FAT32LBA,1E-FAT16LBA)就完了。可是现在的硬盘已经没有8GB以下的了,读取也几乎全是用LBA方式了。
7月23日:
  加入对扩展INT3读取(42号)功能的接管,实现对隐藏LBA分区的读取,由于现在硬盘分区几乎没有用FAT16的了,所以只处理了FAT32的。
  由于新代码的加入,我原来的提示信息也不得已剪了一部分。

【目前最新版本】
  HFBOOT.ASM还是9月1日的,MAKEIMG.EXE在9月5日新增选项后编译

  新的命令行如下:
  MAKEIMG  源镜像文件名  [目的镜像文件名] [选项]
   源镜像文件名  用来制作显隐藏分区功能的软盘镜像文件
   目的镜像文件名 将要生成的带显隐藏分区功能的软盘镜像文件,可省略,默认值为YISIR.IMG
  可选参数:
   /f       生成的程序在计算机启动时直接从软盘启动。
   /b       生成的程序在计算机启动时直接激活隐藏分区并启动。(注意隐藏分区中必须已安装了操作系统,此功能也未写MBR)
  无 /f 和 /b 参数时将出现提示并等待8秒,这期间按任意键从软盘启动,否则从硬盘启动且不加载显隐藏分区功能。
   /k:n      n=1-4,6-12。设置直接激活隐藏分区并启动时用的按键,可以是F1-F4、F6-F12
    /p:nn=0 - 255 ,自定义构成进度条的字符,默认是62即“>”,象219(实心方块)、220、223也挺好看
    /r:nn=1 - 24 ,自定义提示信息的在屏幕中的开始行,默认是21行,即在21行显示提示,22行显示进度条。
   /u       卸载本程序,将由本程序生成的镜像文件还原,结果保存成一个镜像文件。

希望下载和使用了这个软件的朋友跟帖或到我的小站留言谈一下看法。

[ Last edited by TurboY on 2005-9-6 at 15:38 ]
作者: hnlyzhd     时间: 2005-8-5 10:50
楼主这个很有创意,我要转贴了!SYSOFT.ZDWX.COM和BBS.WUYOU.COM

不过楼主最好能写个专用的创建隐藏分区的小程序。我对这个引导盘进行 测试后发现不支持HIDE.COM,PQ,GRUB等程序创建的隐藏分区。如果这个小引导程序能够支持HPA分区就更好了!

关注和期待中!

[ Last edited by hnlyzhd on 2005-8-5 at 10:56 ]
作者: TurboY     时间: 2005-8-11 19:07
  谢谢关注!是这样的,由于程序在启动扇区中,只能用512字节,还要保留一些空间,所以代码不能太长(也许优化一下可以处理更多的分区类型,以后我再挤一挤),目前这个程序只处理了两种类型的隐藏分区,即0X1B(FAT32)和0X1C(FAT32-LBA),而且只能是主分区(在MBR中定义的)。理论上只要是用DOS能支持的分区类型转成的隐藏分区,应该都没有问题的。你可以把常见的这些隐藏分区的类型码发上来,我就可以全加上去。
作者: hnlyzhd     时间: 2005-8-12 13:17
隐藏分区的类型我还不太懂得如何来看呢,不好意思了!
你可以用GRUB或者PQ或者ACRONIS等软件来测试,支持的隐藏分区越多越好1
作者: pfox     时间: 2005-8-13 20:28
列出目前我所知道的隐藏分区类型:
11、14、16、17、1b、1c、1e、26
如果这个东东能够支持HPA那就完美了,当然,如果空间太小支持不了,那么可以单独做成一个软件吗。

[ Last edited by pfox on 2005-8-13 at 20:36 ]
作者: TurboY     时间: 2005-8-14 22:51
我刚才在 DOS7.10的FDISK所带的FDISKPT.INI文件里发现很多有用的信息,可以找到下面的对应关系:
11 -- 01 FAT12
14 -- 04 FAT16
16 -- 06 FAT16(BIGDOS)
17 -- 07 NTFS
1b -- 0b FAT32
1c -- 0c FAT32 LBA
1e -- 0e FAT16 LBA
26 -- ? 这个就不知道是原始类型是什么了。

有了这些对照,才能开工。
作者: pfox     时间: 2005-8-16 09:42


  Quote:
Originally posted by TurboY at 2005-8-14 10:51 PM:
我刚才在 DOS7.10的FDISK所带的FDISKPT.INI文件里发现很多有用的信息,可以找到下面的对应关系:
11 -- 01 FAT12
14 -- 04 FAT16
16 -- 06 FAT16(BIGDOS)
17 -- 07 NTFS
1 ...

呵呵,26是spfdisk自己使用的隐藏分区类型,我列出的那些类型是从spfdisk搬出来的,所以这个你在FDISKPT.INI查不到。
作者: crshen     时间: 2005-8-19 08:38
建议把源程序贴出来,大家可以一起完善。
作者: crshen     时间: 2005-8-19 08:57
晕,懒惯了,没想到512字节必然是汇编代码,现粗略看了一下,大家一起讨论吧:

PAGE  59,132

;圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹
;圹                                                                         圹
;圹                                HFBOOT                                         圹
;圹                                                                         圹
;圹      Created:                                                         圹
;圹      Passes:    5          Analysis        Options on: none                 圹
;圹                                                                         圹
;圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹

target                EQU   'M5'                      ; Target assembler: MASM-5.0

include  srmacros.inc


; The following equates show data references outside the range of the program.

d_0000_01C2_e        equ        1C2h
d_0000_0413_e        equ        413h
d_0000_7D81_e        equ        7D81h                        ;*

seg_a                segment        byte public
                assume        cs:seg_a, ds:seg_a


                org        100h

HFBOOT                proc        far

start:
                jmp        short real_start
                                                ;* No entry point to code
                nop
                dec        bp
                push        bx
                inc        sp
                dec        di
                push        bx
                xor        ax,302Eh
                add        [bp+si],al
                add        [bx+di],ax
                add        [bp+si],al
                loopnz        locloop_0113                ; Loop if zf=0, cx>0


locloop_0113:
                inc        ax
                or        si,ax
                or        [bx+si],ax
                adc        al,[bx+si]
                add        al,[bx+si]
                db        10 dup (0)
                db         29h, 28h, 06h, 05h
                db        ' YISIR_LOADERFAT12'

;圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹
;
;                       External Entry Point
;
;圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹圹

real_start:
                cli                                ; Disable interrupts
;*                xor        ax,ax                        ; Zero register
                db         31h,0C0h                ;  Fixup - byte match
                mov        ds,ax
                mov        es,ax
                mov        ss,ax
                mov        ax,7C00h
;*                mov        sp,ax
                db         89h,0C4h                ;  Fixup - byte match
                sti                                ; Enable interrupts
                push        ax
                mov        ax,1301h
                mov        bx,0Ah
                mov        cx,7Ah
                mov        dx,1500h
                mov        bp,d_0000_7D81_e
                int        10h                        ; Video display   ah=functn 13h
                                                ;  write string, al=mode,bh=page
                                                ;   bl=attrib, cx=string length
                                                ;   dh=row, dl=column, at es:bp
                mov        ah,1
                mov        cx,2000h
                int        10h                        ; Video display   ah=functn 01h
                                                ;  set cursor mode in cx
                mov        si,46Ch
                db         66h, 8Bh, 14h, 66h, 89h,0D1h
                db         66h, 81h,0C2h, 9Fh, 00h, 00h
                db         00h,0B4h, 01h,0CDh, 16h, 74h
                db         09h,0B4h, 00h,0CDh, 16h, 31h
                db        0D2h,0E9h, 1Dh, 00h, 66h, 3Bh
                db         0Ch, 73h, 0Dh,0F6h,0C1h, 01h
                db         74h, 08h,0B8h, 3Eh, 0Eh,0BBh
                db         04h, 00h,0CDh, 10h, 66h, 8Bh
                db         0Ch, 66h, 39h,0CAh, 73h,0D7h
                db        0BAh,0FFh,0FFh
loc_01A0:
                mov        ah,1
                mov        cx,0D0Eh
                int        10h                        ; Video display   ah=functn 01h
                                                ;  set cursor mode in cx
                mov        bx,d_0000_0413_e
                mov        ax,[bx]
                dec        ax
;*                cmp        dx,0FFFFh
                db         81h,0FAh,0FFh,0FFh        ;  Fixup - byte match
                jz        $+4                        ; Jump if zero
                mov        [bx],ax
                db        0C1h,0E0h, 06h, 8Eh,0C0h, 5Eh
                db         06h, 31h,0FFh,0FCh,0B9h, 00h
                db         01h,0F2h,0A5h,0BEh, 4Ch, 00h
                db        0BFh, 09h, 01h, 66h, 8Bh, 04h
                db         26h, 66h, 89h, 05h, 81h,0FAh
                db        0FFh,0FFh, 74h, 0Ch, 06h, 58h
                db         66h,0C1h,0E0h, 10h,0B8h, 0Dh
                db         01h, 66h, 89h, 04h, 1Eh, 07h
                db        0BBh,0EAh, 00h, 53h,0CBh, 81h
                db        0FAh,0FFh,0FFh, 74h, 09h,0B9h
                db         12h, 4Fh,0BAh, 00h, 01h,0E9h
                db         06h, 00h,0B9h, 01h, 00h,0BAh
                db         80h, 00h
loc_01FF:
                mov        ax,201h
                mov        bx,7C00h
                pushf                                ; Push flags
                push        ds
                push        bx

HFBOOT                endp

;哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌哌
;                              SUBROUTINE
;苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘苘

sub_0208        proc        near
loc_0208:
;*                jmp        far ptr l_0000_0000        ;*
sub_0208        endp

                db        0EAh
                dw        0, 0                        ;  Fixup - byte match
                                                ;* No entry point to code
                cmp        ah,2
                jne        loc_0223                ; Jump if not equal
                cmp        dx,80h
                jne        loc_0223                ; Jump if not equal
;*                cmp        cx,1
                db         81h,0F9h, 01h, 00h        ;  Fixup - byte match
                jz        loc_0241                ; Jump if zero
                cmp        ah,42h                        ; 'B'
                je        $+5                        ; Jump if equal
loc_0223:
;*                jmp        loc_0208
                db        0E9h,0E2h,0FFh                ;  Fixup - byte match
                db         66h, 50h, 66h, 31h,0C0h, 66h
                db         39h, 45h, 08h, 75h, 0Bh, 66h
                db         39h, 45h, 0Ch, 75h, 05h, 66h
                db         58h,0E9h, 05h, 00h, 66h, 58h
                db        0E9h,0E2h,0FFh
loc_0241:
                pushf                                ; Push flags
                callf        sub_0208
                jc        loc_ret_0280                ; Jump if carry Set
                push        es
                push        ds
                push        bx
                push        cx
                cmp        ah,42h                        ; 'B'
                jne        loc_025A                ; Jump if not equal
                mov        bx,[di+4]
                mov        es,[di+6]
                jmpn        loc_025C
loc_025A:
                push        es
                pop        ds
loc_025C:
                add        bx,d_0000_01C2_e
                mov        cx,4

locloop_0263:
                cmp        byte ptr [bx],1Bh
                jne        loc_026E                ; Jump if not equal
                mov        byte ptr [bx],0Bh
                jmpn        loc_0276
loc_026E:
                cmp        byte ptr [bx],1Ch
                jne        loc_0276                ; Jump if not equal
                mov        byte ptr [bx],0Ch
loc_0276:
;*                add        bx,10h
                db         81h,0C3h, 10h, 00h        ;  Fixup - byte match
                loop        locloop_0263                ; Loop if cx > 0

                pop        cx
                pop        bx
                pop        ds
                pop        es

loc_ret_0280:
                iret                                ; Interrupt return
                db        'Yisir Restore Tool Loader, 2005-'
                db        '7-23 http://yisir.9126.com/', 0Dh
                db        0Ah, 'Press any key to load RESTO'
                db        'RE DISK or BOOT from HARDDISK...'
                db        0Dh, 0Ah
                db         00h, 00h, 00h, 55h,0AAh

seg_a                ends



                end        start
作者: TurboY     时间: 2005-8-22 22:50
我用的是NASM,程序是启动扇区代码,上面的朋友反汇编有问题。
我现在还在改它,现在加入一个可识别分区标志码列表(FlagTable),逐一判断处理,只要是表中有的分区类型都可以处理了,现在可支持01-11,04-14,06-16,07-17,0b-1b,0c-1c,0e-1e。没有的也可很快加进来。大家可以到这里下新的。
http://yisir.softhome.cn/yisir/hfboot/fortestd.zip
作者: hnlyzhd     时间: 2005-8-24 20:21
我用GRUB隐藏了一个分区型号为1B,用这个启动后还是认不到隐藏隐藏分区。
作者: TurboY     时间: 2005-8-25 09:08
1B的分区我在我机房的电脑上试过,可以的啊。
你的这个分区是主分区吗?这个程序只能处理主分区。
作者: hnlyzhd     时间: 2005-8-25 10:22
原来如此呀,你没说明,我弄的是扩展分区,呵呵,能不能支持扩展分区呢?
作者: hnlyzhd     时间: 2005-8-25 10:25
还有个更好的想法:
比如IBM的F11激活隐藏分区,ACRONIS的F11激活隐藏分区然后从隐藏分区启动相应恢复程序,这些都要写到MBR上,能不能写个引导代码从软件来激活它们呢?
或者直接用NTLDR加载激活呢?
作者: TurboY     时间: 2005-8-26 12:32
向IBM和ACRONIS那样应该是可以的。
在这个程序里加上一个从隐藏分区启动的功能应可以做到,但我可又要挤一挤了。512字节的空间写不了太多程序啊。
用NTLDR加载也可以,我现在来做试试看。
作者: pfox     时间: 2005-8-26 17:03
原来用老版本处理过的img可以直接再用新版本进行处理吗?还是要没有处理过的img才能处理?
作者: TurboY     时间: 2005-8-26 18:01
得用没有处理过的img重做才行,或者你用标准的启动扇区替换已经做过的后再做。只是做程序了,忘了考虑卸载程序,以后一定加上。
我在无忧已经发了个新的,不过也没有卸载程序。
作者: pfox     时间: 2005-8-26 21:25


  Quote:
Originally posted by TurboY at 2005-8-26 06:01 PM:
得用没有处理过的img重做才行,或者你用标准的启动扇区替换已经做过的后再做。只是做程序了,忘了考虑卸载程序,以后一定加上。
我在无忧已经 ...

无忧的版本你你这里的版本不同吗?
作者: TurboY     时间: 2005-8-26 21:38
谢谢!
两者实际是一样的,这里原来那个只是没改MAKEIMG而已.
作者: TurboY     时间: 2005-8-29 00:36
8月28日的进展
  我和无忧的hnlyzhd版主交流时他提出个建议:能否启动安装在隐藏分区内的操作系统
  现在实现了,新程序在启动时出现的8秒等待中如果按了F7键(我用BOCHS调试的,它不准我用F11、F12),则会从第一个隐藏主分区启动,此盘分配为C:。
  目前我只测试了DOS7.1,不知道能不能启动WIN98。但WIN2K和XP或LINUX不用试肯定不行,它们都不依赖BIOS读盘。
  新的命令行如下:
  MAKEIMG  源镜像文件名  [目的镜像文件名] [/f | /b | /u]
   源镜像文件名  用来制作显隐藏分区功能的软盘镜像文件
   目的镜像文件名 将要生成的带显隐藏分区功能的软盘镜像文件,可省略,默认值为YISIR.IMG
  可选参数:
   /f       生成的程序在计算机启动时直接从软盘启动。(f为小写字母)
   /b       生成的程序在计算机启动时直接激活隐藏分区并启动。(b为小写字母,注意隐藏分区中必须已安装了DOS操作系统,此功能也未写MBR)
  无 /f 和 /b 参数时将出现提示并等待8秒,这期间按任意键从软盘启动,否则从硬盘启动且不加载显隐藏分区功能。
   /u       卸载本程序,将由本程序生成的镜像文件还原。(u为小写字母)

真心希望各位下载试过了的朋友能回复讨论一下这个新加功能的稳定性!
作者: TurboY     时间: 2005-8-29 14:24
又发现了一个强大的DOS文件系统驱动程序,这是在DOS层实现我所提出的问题的。
我等了一年了,看来能人真不少啊。软件厂家的网站是www.paragon.ag

我是在下面的帖子中得到的,里面有下载
[url]http://bbs.wuyou.com/cgi-bin/topic.cgi?forum=34&topic=10488&show=0[url]
Paragon DOS IFS Driver 通吃NTFS/Ext2FS/Ext3FS以及隐藏FAT/FAT32的读写,才300多k,比NTFS PRO FOR DOS好多了,另外,它还支持DOS长文件名读写,完全支持中文名称。功能巨大,不可不拥有。
作者: crshen     时间: 2005-8-29 18:16
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

[ Last edited by crshen on 2005-8-31 at 08:04 ]
作者: crshen     时间: 2005-8-29 18:19
建议版主以后直接发带注释的源程序,以便大家完善,看汇编代码本来就很费神,我都没这么好的耐心,相信别人也不轻松。

另外
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)

[ Last edited by crshen on 2005-8-31 at 08:23 ]
作者: TurboY     时间: 2005-9-2 02:47
【9月1日最新更新】
  谢谢crshen指出BUG,看来DOS启动时基本上没用扩展INT13功能来读MBR,所以那些死代码基本上就没有运行到,从运行表面上看好像没问题了,但BUG还是存在。现在已经全部修正了。
  8月28日无法从后面的隐藏分区启动的问题解决了,现在已经可以正常启动隐藏主分区中的操作系统。其实是程序本身的问题,程序虽然在启动后把隐藏分区向其他程序报告为正常分区,但在自己完工后把控制权交还MBR时却忘了改。结果MBR还是装入了原来的激活分区引导程序,但在那个操作系统启动时读到的激活分区却是那个已经显示出来的隐藏分区了。所以当两个系统都是DOS或Win98时由于启动文件一样时是正常的,两个系统不同时就有异常了。
  新程序在启动时出现的8秒等待中如果按了F7键(或自定义的键),则会从第一个隐藏主分区启动,此盘分配为C:。目前我只测试了DOS7.1(Win98启动盘),我想应该也能启动WIN98。WinXP启动后会将隐藏分区变成非隐藏,用硬盘重启后仍是可显示的,肯定时WinXP在什么时候更新过MBR。LINUX没有试。
  新加入一个功能键ESC:可以不加载本程序,正常从硬盘盘启动,。
  新加入一个功能键F5:可以不加载本程序,正常从软盘盘启动,用于需要正确查看实际分区时。
  MAKEIMG.EXE的命令行选项可以忽略大小写了。
  尽管程序改动了不少,裁掉了很多提示信息,可是程序已经快写满512字节了,只剩1个字节的空间了。如果再要加别的功能,只能再开一个扇区了。

  新的命令行如下:
  MAKEIMG  源镜像文件名  [目的镜像文件名] [/f | /b | /u | /k:n]
   源镜像文件名  用来制作显隐藏分区功能的软盘镜像文件
   目的镜像文件名 将要生成的带显隐藏分区功能的软盘镜像文件,可省略,默认值为YISIR.IMG
  可选参数:
   /f       生成的程序在计算机启动时直接从软盘启动。
   /b       生成的程序在计算机启动时直接激活隐藏分区并启动。(注意隐藏分区中必须已安装了操作系统,此功能也未写MBR)
  无 /f 和 /b 参数时将出现提示并等待8秒,这期间按任意键从软盘启动,否则从硬盘启动且不加载显隐藏分区功能。
   /k:n      n=1-4,6-12。设置直接激活隐藏分区并启动时用的按键,可以是F1-F4、F6-F12
   /u       卸载本程序,将由本程序生成的镜像文件还原,结果保存成一个镜像文件。
附件 1: build050901.zip (2005-9-2 02:47, 43.59 K, 下载附件所需积分 1点 ,下载次数: 33)

作者: TurboY     时间: 2005-9-6 15:03
  感谢各位朋友的关注,为方便感兴趣的朋友改进,源程序开放。先公开引导区模块(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

作者: TurboY     时间: 2005-9-6 15:04
【目前最新版本】
  HFBOOT.ASM还是9月1日的,MAKEIMG.EXE在9月5日新增选项后编译
MAKEIMG.EXE可以处理非1.44M软盘镜像了。
  新的命令行如下:
  MAKEIMG  源镜像文件名  [目的镜像文件名] [选项]
   源镜像文件名  用来制作显隐藏分区功能的软盘镜像文件
   目的镜像文件名 将要生成的带显隐藏分区功能的软盘镜像文件,可省略,默认值为YISIR.IMG
  可选参数:
   /f       生成的程序在计算机启动时直接从软盘启动。
   /b       生成的程序在计算机启动时直接激活隐藏分区并启动。(注意隐藏分区中必须已安装了操作系统,此功能也未写MBR)
  无 /f 和 /b 参数时将出现提示并等待8秒,这期间按任意键从软盘启动,否则从硬盘启动且不加载显隐藏分区功能。
   /k:n      n=1-4,6-12。设置直接激活隐藏分区并启动时用的按键,可以是F1-F4、F6-F12
     /p:nn=0 - 255 ,自定义构成进度条的字符,默认是62即“>”,象219(实心方块)、220、223也挺好看
     /r:nn=1 - 24 ,自定义提示信息的在屏幕中的开始行,默认是21行,即在21行显示提示,22行显示进度条。
   /u       卸载本程序,将由本程序生成的镜像文件还原,结果保存成一个镜像文件。

希望下载和使用了这个软件的朋友跟帖或到我的小站留言谈一下看法。

[ Last edited by TurboY on 2005-9-6 at 20:15 ]
附件 1: build050905.zip (2005-9-6 20:15, 44.33 K, 下载附件所需积分 1点 ,下载次数: 47)

作者: crshen     时间: 2005-9-6 21:34
图形界面版升级至1.1版,可用于非1.44M映像。

[ Last edited by crshen on 2005-9-10 at 20:17 ]
附件 1: 安装.jpg (2005-9-10 19:30, 33.97 K, 下载附件所需积分 1点 ,下载次数: 2)


附件 2: 启动提示.jpg (2005-9-10 20:16, 6.75 K, 下载附件所需积分 1点 ,下载次数: 3)


附件 3: unhide.rar (2005-9-10 20:16, 171.66 K, 下载附件所需积分 1点 ,下载次数: 75)

作者: hnlyzhd     时间: 2005-9-8 23:49
再来看一下,准备睡觉!
暂没有意见,正在找问题和发现新的需要的功能!
哈哈!~
作者: fdsiuha     时间: 2005-9-10 00:06
crshen贴出的像MBR,但是是哪个操作系统的呢?

我记得我看过的几个MBR开始初始化寄存器之后都是将7C00的引导代码立刻读到内存中的其他地方,把堆栈放在7C00开始。

我不太清楚是为什么要这样做,而且crshen贴出的ASM没有这些步骤。
哪位大侠解说一下?

[ Last edited by fdsiuha on 2005-9-10 at 00:12 ]
作者: hiboy     时间: 2005-9-11 10:55
我看了,弱问一个为什么代码里有eax?是8086?我用了16位的汇编,自己研究的时候会被卡巴认为是病毒。IBM的F11好像用了int 13h重写MBR,而不是驻留。因为确实很多病毒做法是驻留,而改写int 13h的那一段代码是特征码,大概用eax才没有被报告是病毒
作者: cqly88     时间: 2009-9-16 05:48
很好很不错啊,值得学习
作者: atoms     时间: 2010-3-19 16:00    标题: 2.88改写后,生成新的成1.44的了

2.88改写后,生成新的成1.44的了  0906版OK

[ Last edited by atoms on 2010-3-19 at 17:00 ]
作者: lodossboy     时间: 2018-4-6 16:24
膜拜