怎樣用CMOS加密軟體防止非法拷貝
我們運行軟體時經常會遇到以下情況,有的軟體在一台機器上安裝後就不能將其拷貝到其他機器上運行;有的軟體甚至連原來機器的軟、硬體設定改變後也無法再次運行。其實這些情況有的是利用CMOS對軟體加密來實現的。安裝軟體時,通過安裝程式把軟體安裝到硬碟上,同時把當前機器的CMOS資訊儲存到安裝磁碟片上,也就是相當於儲存了密鑰。等到以後在硬碟上運行該軟體時,軟體的主程式會把記錄在安裝盤上的密鑰與正在運行該軟體機器的CMOS資訊進行比較,如果完全相同,則允許軟體繼續運行,否則終止軟體運行。國內的許多軟體都是採用此原理進行加密的。
由於CMOS具有比磁碟更好的隱蔽性和正常DOS下的不可訪問性,所以利用CMOS對軟體進行加密是防止軟體非法拷貝的一種方法。以下將重點介紹通過C語言利用CMOS對軟體進行加密防止非法拷貝的實現方法。
一、CMOS資料格式
CMOS是互補性氧化金屬半導體的縮寫,其本意是指製造大規模整合電路晶片用的一種技術或用這種技術製造出來的晶片。在這裡是指電腦主板上的一塊可讀寫的RAM晶片。它靠系統電源和後備電池供電,系統掉電後內容不會丟失。它儲存了機器軟、硬體設定的基本資料,共有128個位元組。系統在上電引導時要讀取CMOS資訊來初始化機器各組件狀態。
二、加密原理
如果想要限定軟體只在固定的機器上運行,可以在軟體的安裝時把當前機器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密鑰儲存到額外磁軌的特殊扇區中,可以大大地增強安裝盤的防拷貝能力,進一步對軟體加密。
表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 保留
0AH A寄存器狀態 2E~2FH 10-2DH校正和
0BH B寄存器狀態 30~31H 擴充記憶體容量,單位K
0CH C寄存器狀態 32H BCD碼世紀值
0DH D寄存器狀態 33H 資訊標誌
0EH 診斷狀態位元組 34~3FH 保留
0FH 停機狀態位元組 40~7FH 保留