我们运行软件时经常会遇到以下情况,有的软件在一台机器上安装后就不能将其拷贝到其他机器上运行;有的软件甚至连原来机器的软、硬件配置改变后也无法再次运行。其实这些情况有的是利用CMOS对软件加密来实现的。安装软件时,通过安装程序把软件安装到硬盘上,同时把当前机器的CMOS信息保存到安装软盘上,也就是相当于保存了密钥。等到以后在硬盘上运行该软件时,软件的主程序会把记录在安装盘上的密钥与正在运行该软件机器的CMOS信息进行比较,如果完全相同,则允许软件继续运行,否则终止软件运行。国内的许多软件都是采用此原理进行加密的。
由于CMOS具有比磁盘更好的隐蔽性和正常DOS下的不可访问性,所以利用CMOS对软件进行加密是防止软件非法拷贝的一种方法。本文将重点介绍通过C语言利用CMOS对软件进行加密防止非法拷贝的实现方法。
一、CMOS数据格式
CMOS是互补金属氧化物半导体的缩写,其本意是指制造大规模集成电路芯片用的一种技术或用这种技术制造出来的芯片。在这里是指计算机主板上的一块可读写的RAM芯片。它靠系统电源和后备电池供电,系统掉电后内容不会丢失。它存储了机器软、硬件配置的基本信息,共有128个字节。系统在上电引导时要读取CMOS信息来初始化机器各部件状态。
表1 CMOS数据格式地址说明地址说明
00H秒数10H软盘驱动器类型
01H秒数报警11H保留
02H分数12H硬盘驱动器类型
03H分数报警13H保留
04H小时数14H设备字节
05H小时数报警15~16H基本内存容量,单位K
06H星期数17~18H扩充内存容量,单位K
07H日期19H硬盘驱动器0类型
08H月份1AH硬盘驱动器1类型
09H年份1B~2DH保留
0AHA寄存器状态2E~2FH10-2DH校验和
0BHB寄存器状态30~31H扩充内存容量,单位K
0CHC寄存器状态32HBCD码世纪值
0DHD寄存器状态33H信息标志
0EH诊断状态字节34~3FH保留
0FH停机状态字节40~7FH保留
二、加密原理
如果想要限定软件只在固定的机器上运行,可以在软件的安装时把当前机器CMOS中的内容读出,作为密钥以文件的形式保存到安装盘上。在软件运行时自动检查当前正在运行程序机器的CMOS中内容是否与安装盘上保存的密钥相同。如果检查结果不正确,则证明已经不是原来安装软件的那台机器,运行的软件不是安装到硬盘的,是非法拷贝过来,必须终止软件运行,从而达到了加密软件防止非法拷贝的目的。
在CMOS的128个字节单元中,00H-0FH字节单元中的数据随机性太强,不易作为密钥。1BH~2DH,34H~3FH,40H~7FH是CMOS的保留单元。不同的BIOS版本对此保留单元设置不一样。根据笔者的观察,AST系列原装机BIOS对此单元填充数据为0。COMPAQ系列原装机和采用AWARD、AMI等BIOS的机器对此单元均填充不同的数据。2EH、2FH单元中存放的是10H~2DH单元中各字节的校验和。系统每次引导时要读取CMOS信息,同时还要检查10H~2DH单元中的各字节的校验和是否与2EH、2FH单元中的数据相同,不同则提示CMOS中数据有错。因涉及到保留单元,不建议作为密钥。30H~33H单元内容无法区分不同配置的机器,可以不用考虑。
只有CMOS的10H~2DH单元中内容涉及到软盘、硬盘、内存、显示卡等最基本的硬件配置。实际应用中软、硬件配置完全相同的机器几乎是不存在的,所以可以采用CMOS中的内容作为密钥进行检查,完全可以做到加密软件,防止对软件的非法拷贝。
三、实现方法
在计算机系统中,对CMOS中数据的读写是通过两个I/O端口来实现的,其中,端口70H是一个字节的只写端口,用它来设置CMOS中的数据地址;而端口71H是用来读写端口70H设置的CMOS地址中的数据单元字节内容。所以在读写CMOS数据时,可以通过70H端口写入一个地址值,再通过71H端口读出一个数据,对软件的加密就是通过这个来实现的。
在利用CMOS加密软件的过程中,一般需要编制两段程序:一段程序的功能为在安装程序中保存CMOS内容作为密钥;另一段程序的功能为在软件主程序中检测密钥是否存在及正确,在每次运行该软件时都调用此段程序。
本文采用的密钥检查方法是“校验和法”。所谓校验和法是指先对全部信息或部分信息计算出一个累加和,作为密钥存放在安装盘上。当软件运行时对所检查信息部分再计算一个累加和,两者进行比较,一致时才能正确执行。一旦发现不一致,则可作一些处理,终止软件运行。因为一台机器配置改变,校验和必然发生变化。
程序1:将CMOS中10H~2DH单元中的数据的校验和作为密钥写入到安装软盘上的某个文件中。使用时将此段程序嵌入到软件的安装程序中。
/*JM1.C*/
#include"stdio.h"
main()
{
unsigned int i ,csum=0;
FILE *fp;
for (i=0x10;i〈=0x2d;i++)/*求得安装程序机器的CMOS中校验和*/
{
outportb(0x70,i);
csum+=inportb(0x71);
}
if ((fp=fopen("A:\MIMA.DAT","wb"))==NULL)/*打开密钥文件*/
{printf ("请打开写保护\07");
exit (0);
}
fwrite (&csum,2,1,fp);
fclose(fp);
}
运行结果:在A盘上产生一个名为MIMA.DAT的文件,该文件记录了程序安装时产生的密钥。
程序2:检查当前机器CMOS中10H~2DH单元中的校验和与保存在安装软盘上的密钥是否相同。使用时将此段程序嵌入到软件的主程序中。
/*JM2.C*/
#include"stdio.h"
main()
{
unsigned int i,csum=0;
unsigned int fsum;
FILE *fp;
for(i=0x10;i〈=0x2d;i++)
{
outportb(0x70,i);
csum+=inportb(0x71);/*求得运行程序机器的CMOS中的校验和*/
}
if((fp=fopen("A:\MIMA.DAT","rb"))==NULL)
{printf("请插入钥匙盘");
exit(0);/*安装盘不存在,终止程序运行*/
}
fread(&fsum,2,1,fp);
if (fsum!=csum)/*把当前机器CMOS中校验和与密钥进行比较*/
{printf ("您不是合法用户,请您购买正版软件!\07");
exit(0);/*终止程序的运行,可进一步做处理*/
}
else
{printf ("您是合法用户,欢迎使用!");
}
fclose(fp);/*继续运行主程序*/
}
运行结果:如果软件是通过安装程序安装到机器上的,则提示“您是合法用户,欢迎使用!”,继续运行程序;如果软件是通过非法拷贝到机器上的,则警铃提示“您不是合法用户,请您购买正版软件!”,并终止该程序的运行。
(其中JM1.C、JM2.C是用TUBRO C V2.0编写,链接生成EXE文件,在UCDOS 6.0下调试通过。)
四、结束语
最后需要说明的是,利用CMOS进行软件加密的实现方法不同,在实际应用中要根据具体情况来决定简单与复杂。通常可考虑以下几个方面的因素:
1. CMOS密钥的难易程度。检查的CMOS数据越多,对机器的软、硬件配置检查越严格。
2.CMOS密钥检查方法。如果能做到逐个字节的检查最为准确。
3.~CMOS密钥保存方法。如果以文件的形式存放在磁盘上可能容易被发现破解,可考虑保存到软盘的隐含扇区,如引导扇区、目录区、文件分配表区等;或者保存到硬盘的隐含扇区,如主引导记录、分区表等,同时也就需要每次启动时读安装盘;或者保存到CMOS的保留单元中。这些方法都可以增加CMOS密钥的破译难度,提高软件加密的可靠性。
4.结合在安装盘上做指纹技术,利用INT13H格式化出额外磁道和特殊扇区,将CMOS密钥保存到额外磁道的特殊扇区中,可以大大地增强安装盘的防拷贝能力,进一步对软件加密。
评论0