3、编写安装程序
用Tc2.0语言编写安装程序如下:
#include"stdio.h"
#include"bios.h"
int getcyl(unsigned char * d1,unsigned char *d2) /*获得硬盘的C分区的末柱面号的函数*/
{unsigned char b[512]; /*d1是C分区的末柱面号的低8位,d2是C分区*/
unsigned char x,y; /*的末柱面号的高2位*/
if(biosdisk(2,0x80,0,0,1,1,b))return 1; /*成功返回0,否则返回1*/
if((b[0x1be]==0x80)&&(b[510]==0x55)&&(b[511]==0xaa))/*判断分区表是否有效*/
{x=b[0x1be+7];y=b[0x1be+6]; /*分区表偏移为7的字节是末柱面号的低8位*/
*d1=x;*d2=(y&0xc0)>>6; /*偏移为6的字节的高2位是末柱面号的高2位*/
return 0;}
return 1;
}
void main()
{FILE *fp;
int x,y;
unsigned char c1,c2;
unsigned char mbr[512*3],buf[512*3];
if(biosdisk(2,0x80,0,0,1,3,mbr))
{printf("\n Read disk Error!");return;}/*读出0面0柱1扇区到3扇区到mbr[512*3]中*/
if(mbr[0xc1]=='W'&&mbr[0xc2]=='D'&&mbr[0xc3]=='M'){printf("\nyou have installed!");
return;} /*如果已经安装则退出,主引导扇区的c1,c2,c3字节有标记“WDM”*/
if((fp=fopen("mbrbak.dat","wb"))==NULL){printf("\n Create File Error!");return;}
fwrite(mbr,512*3,1,fp); /*将原来的数据备份到mbrbak.dat文件中*/
printf("\n Your Boot Record backup successfull!");
fclose(fp);
for(x=0;x<512;x++)mbr[512+x]=mbr[x];/*将0面0柱1扇区的内容写到0面0柱2扇区中*/
if((fp=fopen("mymbr.dat","rb"))==NULL){printf("\n Open File Error!");return;}
fread(mbr,512,1,fp);/*打开mymbr.dat文件,将新的主引导记录写入0面0柱1扇区*/
if((fp=fopen("int13.dat","rb"))==NULL){printf("\n Open File Error!");return;}
fread(mbr+1024,512,1,fp);/*打开int13.dat文件,将新的int 13h代码写入0面0柱3扇区*/
if(getcyl(&c1,&c2)){printf("\n Cant't get your end cylinder!");return;}
mbr[1024+0x1e]=c1; /* 填入实际的c盘末拄面号 */
mbr[1024+0x1f]=c2;
mbr[0x1be+16+4]=0x05; /*填入特殊的分区表数据使c盘无法从a盘引导*/
mbr[0x1be+16+1]=0x00;
mbr[0x1be+16+2]=0x01;
mbr[0x1be+16+3]=0x00;
for(x=0;x<15;x++)mbr[0x1be+x+1]=0xff;
if(biosdisk(3,0x80,0,0,1,3,mbr)){printf("\n Write disk Error!");return;}/*正式写入磁盘前3个扇区*/
if(biosdisk(2,0x80,0,0,1,3,buf)){printf("\n Read disk Error!");return;}/*再读出校验一次*/
for(x=0;x<512*3;x++)if(buf[x]!=mbr[x]){printf("\n check Error!");return;}
printf("\n Procted System is installed successfull!");/*校验成功,显示安装成功信息*/
}
4、编写使从A盘能启动的程序。
当我们安装了保护程序后,A盘不能启动,我们要解除保护,怎么办?下面给出使你的系统盘能够启动,并自动解除保护的程序。
要使A盘系统能启动,我们必须修改A盘的引导记录。
在debug下输入如下代码:
-a100
26E4:0100 CLI ;这段代码装入软盘引导记录的偏移为3eh处,所以代码中的跳转和存储器寻址
26E4:0101 XOR AX,AX ;都加了3eh,请阅读时注意!
26E4:0103 MOV SS,AX ;代码运行在0000:7c00处,所有指令都是以他为准
26E4:0105 MOV SP,7C00
26E4:0108 MOV SI,SP
26E4:010A PUSH AX
26E4:010B POP ES
26E4:010C PUSH AX
26E4:010D POP DS
26E4:010E STI
26E4:010F CLD
26E4:0110 MOV DI,0600 ;将0000:7c00开始的100h个字的代码移到0000:600处
26E4:0113 MOV CX,0100
26E4:0116 REPNZ
26E4:0117 MOVSW
26E4:0118 JMP 0000:065B ;实际相当于转向0000:061d
26E4:011D PUSH AX
26E4:011E PUSH ES
26E4:011F PUSH BX
26E4:0120 PUSH CX
26E4:0121 PUSH SI
26E4:0122 MOV AX,9FC0 ;将硬盘0面0柱2扇区读到9fc0:200处
26E4:0125 MOV ES,AX
26E4:0127 MOV BX,0200
26E4:012A MOV AX,0201
26E4:012D MOV CX,0002
26E4:0130 MOV DX,0080
26E4:0133 INT 13
26E4:0135 MOV CX,0001
26E4:0138 MOV AX,0301
26E4:013B INT 13 ;
将刚才读出的0面0柱2扇区写入硬盘0面0柱1扇区
26E4:013D MOV CX,000D
26E4:0140 MOV AH,0E
26E4:0142 MOV SI,00AC ;显示信息存放在相对代码首偏移为6eh处*/
26E4:0145 ADD SI,0600 ; 由于运行时代码移到了0000:0600处,则实际偏移为 */
26E4:0149 MOV AL,[SI];600+6eh+3eh=6ach */
26E4:014B INT 10 ;显示“PT Fixed!”解除保护成功的信息
26E4:014D INC SI
26E4:014E LOOP 0149
26E4:0150 XOR AX,AX
26E4:0152 MOV ES,AX
26E4:0154 MOV DS,AX
26E4:0156 MOV AX,0201 ;
从A盘的0面40h磁道1扇区读出原来的软盘引导记录
26E4:0159 MOV BX,7C00 ;到0000:7c00处
26E4:015C MOV CX,4001
26E4:015F MOV DX,0000
26E4:0162 INT 13
26E4:0164 POP SI
26E4:0165 POP CX
26E4:0166 POP BX
26E4:0167 POP ES
26E4:0168 POP AX
26E4:0169 JMP 0000:7C00 ;转原来的软盘引导记录,正常引导
26E4:016E DB 0d,0a,50 ;
下面是“PT Fixed!"的显示信息的ASCII码数据
26E4:0171 DB 54
26E4:0172 DB 20,46,69
26E4:0175 DB 78,65
26E4:0177 DB 64
26E4:0178 DB 21,0d
26E4:017A DB 0a
-rcx
cx 00
:7b
-nboot.dat ;将7bh个字节写入boot.dat文件中
-w100
得到软盘的新的引导记录boot.dat。
将boot.dat装配到软盘的c程序如下:
/*key.c 编译连接后为 key.exe*/
#include"stdio.h"
#include"bios.h"
void main()
{FILE *fp;
int x,y;
unsigned char mbr[512],buf[512];
if(biosdisk(2,0x00,0,0,1,1,mbr)){printf("\n Read Floppy Error!");return;}/*读出原软盘引导记录*/
if(biosdisk(3,0x00,0,0x40,1,1,mbr)){printf("\n Write Floppy Error!");return;}/*写入到A盘0面40h磁道1扇区*/
if(biosdisk(2,0x00,0,0x40,1,1,buf)){printf("\n Read Floppy Error!");return;}/*读出校验*/
for(x=0;x<512;x++)if(buf[x]!=mbr[x]){printf("\n check Error!");return;}
if((fp=fopen("boot.dat","rb"))==NULL){printf("\n Open File Error!");return;}
fread(mbr+0x3e,123,1,fp); /*打开boot.dat文件,将代码装入到软盘的引导记录的3eh处*/
fclose(fp);
if(biosdisk(3,0x00,0,0,1,1,mbr)){printf("\n Write disk Error!");return;}/*写入*/
if(biosdisk(2,0x00,0,0,1,1,buf)){printf("\n Read disk Error!");return;}/*校验*/
for(x=0;x<512;x++)if(buf[x]!=mbr[x]){printf("\n check Error!");return;}
printf("\n your Key disk made successfull!");/*成功信息*/
}
五、安装注意问题
1、必须禁用PWIN9X的32位保护模式下的磁盘驱动程序,否则pwin9x无法启动。
2、PWIN9X的虚拟内存文件(win386.swp)必须设在D盘以后的非保护区。
3、由于C盘无法写进数据,所以任何程序的临时文件要设在在D盘以后的非保护区。这在安装应用软件时尤其要注意!
4、光驱驱动程序一定要在config.sys和autoexec.bat中加载,否则找不到光驱。
5、用本文中key.exe处理过的启动盘只能用来解除保护,不能用来启动没有保护的机器,否则数据全部丢失!
六、实际评测
本系统在我们机房PIII500 10G,PII450 9G,K6-266 4G,cyrix 266 3.2G,Pwin98系统下全部通过,性能稳定,速度基本不变;对photoshop5.0,office97,visual basic 6.0,visual c++ 6.0,红色警戒等常用软件测试全部正常。防破坏测试方面,对跟踪程序和汇编不熟练的专业人员同样具有保护威力。
七、结束语
当然,既然是软件,他的防护能力不可能同硬件相比,本文为讲述方便,没有加入反跟踪和反编译的代码,如果您有兴趣的话,可以自己加入这些代码,尽可能的提高他的防护强度。如果您需要编译好的程序,可到http://jzsoft.topcool.net下载。欢迎来信交流。(wdm.ls@263.net)
|