.软件版权保护的几种方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1?限制软件部分功能?
做法一是在软件的功能菜单中将该菜单所对应的功能实现函数全部置空,这样在执行该功能时会弹出提示对话框或者什么动也没有。做法二是为了方便起见,直接将菜单的属性设置为变灰或者非激活状态,这样在运行系统时,该菜单项就会变灰或者没有激活。这种方法虽然简便,但是如果用Visual?C++直接以资源方式打开可执行文件的话,就可以将将变灰或者非辙活状态去掉,从而去掉软件部分功能的限制。?
2?限制软件试用时间?
这里介绍记录时间的时问限制方法。
?2.1设置三个时间变量?
????????
起始时间:int?nYear0,nMonth0,nDate0;?????????
终止时间:int?nYear,nMonth,nDate;?
????????
当前时间:int?nYearCur,nMonthCur,nDateCur;?
2.2初次运行时给上述变量的赋值?????????
对于当前时间:?
?
1.SYSTEMTIME?stCur;?
2.GetSystemTnne(&stCur);?
3.nYearCUFstCur.wYear.nMonthCur=stCur.wMonth;?
4.nDateCur=stCur.wDay;?
起始时间和终止时间的赋值是在程序第一次运行时将当前时间和预设的期限写入某个文件当中,以后将这两个时间同当前的系统时间进行比较,判断软件是否过期或者试用时间是否到期:?
01.String?sFn="c:\\muxuanshe.sys";?
02.FII.E?*fp=fopen(sFn,"rb");?
03.{?
04.nDateO=nDateCur;?
05.nYear0=n?YearCur;?
06.nMonthO=nMonthCur;?
07.nDate=nDate0;?
08.nYear=nYear0;?
09.nMonth=nMonth0+1;?
10.if(nMonth>12){?
11.nMonth-=12;?
12.nYcar++;?
13.}//跨年度计算依次将起始时间、到期时间和当前时间及文件的字节数写入
c:\\muxuanshe?sys?
14.}?
2.3比较时间?
每次运行时比较当前时间与文件记录中的时间,有两种情况,一是判断是否将系统系统时间提前:?
?if(IsPrcTime(nYear0,nMonth0,nDate0)||IsPreTime(nYear01d,nMo?nthOld,nDateOJd)))其中nYearOld,nMonthOld,nDateOld为上次运行的时间:
?
01.BOOL?JsOverTime(int?nYear,int?nMonth,int?nDate)
?02.{
?
03.SYSTEMTIME?st;
?
04.GetSysten/rime(&st);
?05.if(st.wYear>nYear
06.return?TRUE;
?
07.else?if(st.wYearnMonth)
?08.return?TRUE;
?
09.else?if(st.wMonth==nMonth&&st.wDay>nDate)
?10.return?TRUE;
?11.return?FALSF;
?12.}?
如果您前移了机器时间则将终止时间nYear=l并写入c:\\muxuanshe.sys,软件以后终止运行!
?
另一种情况是对于正常的剩余时问计算:IsOverTime(nYear,nMonth,nDate),不再赘述,具体实现请参见示例代码。
?
这里介绍的方法主要是要注意存放时间的文件要保密,如果知道了时间存放位置,那么时间限制就很容易被解除。也可以用其他更为稳妥的方法将时间存放,如存放在注册表中。
?
3根据机器码实现软件注册
?
机器码指与计算机硬件(CPU、网号、硬盘)有关的串号,如硬盘序列号、MAC地址等,编写软件的人常用机器码作为产生软件序列号的依据,目的是区分用
户,确保自己的软件使用受控,下面通过读取用户计算机硬盘卷序列号,经一定的加密算法进行换算后,返回给用户一个产品注册码,由于硬盘卷序列号是唯一的,提供的产品注册码也是唯一的,用户利用该注册码通过验证后获得软件全部功能。
?
在笔者的编程实践中发现有时候由于所使用的函数不正确,常常不能正确获取硬盘的序列号,这里就这一问题进行讨论。?
3.1不正确的序列号
?
利用GetVolumelnformation获取的计算机硬盘卷序列号,不是正确的唯一序列号:?
01.void?CWJGISApp::Register()?
02.{?
03.DWORD?VolumeSerialNumber;?
04.GetVolumeInformation("c:\\",NULL,NULL,&VolumeSeriaINumber,NULL,NULL,NULL,NULL);?
05.char?charVolumeSerialNumber[l0];?
06.itoa(VolumeSerlalNumber,charVoIumeSerialNumber,10);?
07.CString?strTemp;?
08.strTemp.Format("%s",charVolumeSerialNumber);?
09.}?
该函数获取的序列号在硬盘格式化后会发生变化。?
3.2正确获取硬盘的序列号?正确获取硬盘序列号代码如下:?
01.//读般硬盘序列号函数?
02.char*?CGetHDSerial::GetHDSerial()?
03.{?
04.m_buffer[0]='\n';?
05.//得到当前操作系统版本?
06.OSVERSIONINFO?OSVersionInfo;?
07.OSVersionInfo.dwOSVersionInfoSize?=?sizeof(OSVERSIONINFO);?
08.GetVersionEx(&OSVersionInfo);?
09.if(OSVersionInfo.dwPlatformld?!=?VER_PLATFORM_WIN32_NT)?
10.{?
11.//Windows?9x/ME下读取硬盘序列号12.WORD?m_wWin9xl'HDSerial[256];
13.Win9xReadHDSerial(m_wWin9xHDSerial);?
14.strcpy?(m_buffer,?WORDToChar(m?_wWin9xHDSerial,?10,?19));?
15.}?
16.else?
17.{?
18.//Windows?NT/2000/XP下读取硬盘序列弓?
19.DWORD?m_wWinNTHDSerial[256];?
20.//判断是否有SCSI硬盘?
21.if?(!WinNTReadIDEHDSerial(m_wWinNTHDSerial))?
22.WinNTReadSCSIHDSerial(m_wWinNTHDSerial);?
23.strcpy?(m_buffer,DWORDToChar(m_wWinNTHDSerial,10,?19));?
24.}?
25.return?m_buffer;?
26.}?
27.//Windows?NT/2000/XP下读取IDE硬盘序列号?
28.BOOL?CGetHDScriaI::WinNTReadIDEHDSerial(DWORD*?buffer)?
29.{?
30.BYTE?JdOutCmd?[sizeof(SENDCMDOUTPARAMS)+IDFNTIFY_BUFFER_SIZE?-1];?
31.BOOL?bFlag?=?FALSE;?
32.int?drive?=?0;?
33.Char?driveName[256];?
34.HANDLE?hPhysicalDrivelOCTL=0;?
35.??
36.Sprintf(driveName,"\\\.\\PhysicalDrive%d",drive);?
37.//Windows?NT/2000/XP?下创建文件需要管理员权限?
38.hPhysicalDriveIOCTL=CreateFile(driveName,GENERIC_READ|GENERIC_WRITE,?
39.FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);?
40.??
41.if(hPhysicalDriveIOCTL!=INVALID_HANDLE_VALUE)?
42.{?
43.GETVERSIONOUTPARAMS?VersionParams;?
44.DWORD?cbBytesReturned=0;?
45.//得到驱动器的I/O控制器版本?
46.memser((void*)&VersionParams,0,sizeof(VersionParams));?
47.if(DeviceIoControl(hPhysicalDriveIOCTL,IOCTL_GET_VERSION,NULL,?
48.0,&VersionPaiams,sizeof(VersionParams),sizeof(VersionParams),?
49.&cbBytesReturned,NULL))?
50.{?
51.if(VersionParams.bIDEDeviceMap>0)?
52.{?
53.BYTE?bIDCmd=0;//IDE或者ATAPI识别命令?
54.SENDCMDINPARAMS??scip;?
55.//如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY,command,
56.否则采用命令IDE_ATA_IDENTIFY读取驱动器信息?
57.bIDCmd=(VersionParams.bIDEDeviceMap>>drive&0x10)????????????????????
58.IDE_ATAPI_IDENTIFY?:?IDE_ATA_IDENTIFY;?
59.??
60.memset(&scip,0,sizeof(scip));?
61.memset(IdOutCmd,0,sizeof(IdOutCmd));?
62.//获取驱动器信息?
63.if(WinNTGetIDEHDInfo(hPhysicalDrivelOCTL,&scip,(PSENDCMDOUTPARMS)&?
64.IdOutCmd,(BYTE)bIDCmd,(BYTE)drive,&cbBytesReturned))?
65.{?
66.int?m=0;?
HORT*pldSector=(USHORT*)((PSENDCMDOUTPARAMS)IdOutCmd)->bBuffer;?
68.for(m=0;m<256;m++)?
69.buffer[m]=pIdSector[m];?
70.bFlag=TRUE;??//读取硬盘信息成功?
71.}?
72.}?
73.}?
74.CloseHandle(hPhysicalDriyeIOCTL);?//关闭句柄?
75.}?
76.Return?bFlag;?
77.}?
4?软件版权保护方法调用??????????
在程序初始化时,根据实际需要调用不同软件保护方法,具体时间如下所示:?
01.BOOL?g_nSoftType=0;//0,relese;1,demo;2?anti_copy;3?dog;?
02.BOOL?CTestApp::InitInstance()?
03.{?
04.if(g_nSoftType==1){?
05.if(DemoIsOverTime())?
06.return?FALSE;?
07.}?
08.else?if(g_nSoftType==2){?
09.if(!IsInstalledSoft())?
10.return?FALSE;?
11.}?
12.else?if(g_nSoftType==3){???
13.if(!Dog()){?
14.AfxMessageBox(“您没有安装软件狗,请购买正版软件。\n\n抱歉……”);?
15.return?FLASE;?
16.}?
17.}?
18.if(!g_bDemo){?
ommandLineInfo??cmdInfo;
20.ParseCommandLine(cmdInfo);?
21.}?
22.}?
以上简单介绍了在Visual?C++中实现软件版权保护的方法,显然,保护有效性从高到低依次为硬件dog方法版本、注册码注册方法、功能限制方法、时间限制方法,用户可以根据工作实际需要进行选择。