保护软件版权的实用技巧 转发自VC知识库

1 限制软件部分功能

做法一是在软件的功能菜单中将该菜单所对应的功能实现函数全部置空,这样在执行该功能时会弹出提示对话框或者什么动也没有。做法二是为了方便起见,直接将菜单的属性设置为变灰或者非激活状态,这样在运行系统时,该菜单项就会变灰或者没有激活。这种方法虽然简便,但是如果用Visual
C++直接以资源方式打开可执行文件的话,就可以将将变灰或者非辙活状态去掉,从而去掉软件部分功能的限制。

2 限制软件试用时间

这里介绍记录时间的时问限制方法。

2.1设置三个时间变量         起始时间:int
nYear0,nMonth0,nDate0;         终止时间:int
nYear,nMonth,nDate;         当前时间:int
nYearCur,nMonthCur,nDateCur;

2.2初次运行时给上述变量的赋值         对于当前时间:

view
source

print?

1.SYSTEMTIME stCur;

2.GetSystemTnne(&stCur);

3.nYearCUFstCur.wYear.nMonthCur=stCur.wMonth;

4.nDateCur=stCur.wDay;

起始时间和终止时间的赋值是在程序第一次运行时将当前时间和预设的期限写入某个文件当中,以后将这两个时间同当前的系统时间进行比较,判断软件是否过期或者试用时间是否到期:

view
source

print?

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为上次运行的时间:

view
source

print?

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获取的计算机硬盘卷序列号,不是正确的唯一序列号:

view
source

print?

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正确获取硬盘的序列号

正确获取硬盘序列号代码如下:

view
source

print?

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;

67.                      USHORT*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
软件版权保护方法调用

在程序初始化时,根据实际需要调用不同软件保护方法,具体时间如下所示:

view
source

print?

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){

19.        CCommandLineInfo  cmdInfo;

20.        ParseCommandLine(cmdInfo);

21.    }

22.}

以上简单介绍了在Visual
C++中实现软件版权保护的方法,显然,保护有效性从高到低依次为硬件dog方法版本、注册码注册方法、功能限制方法、时间限制方法,用户可以根据工作实际需要进行选择。

时间: 2024-11-04 22:01:06

保护软件版权的实用技巧 转发自VC知识库的相关文章

一个功能强大的API函数 ShellExecute 转发自VC知识库

问题的提出: 我使用MFC编写一个APP,要求About对话框中显示LOGO.公司名.地址和公司的URL链接.使用户点击URL链接以后,启动浏览器访问Web页面,这种对话框中的热链接使应用程序增色不少.我琢磨的方法是从系统注册表中通过查找.htm 或 .html文件的关联程序来获得缺省浏览器的名字,这样好象有很多工作要做.此外,如果浏览器已经打开,总是开始一个新的实例替代当前已有的一个实例.想找一个容易一点的方法,但我查过有关的资料,没有收获,请高手指教. 解决方法: 如果有这样的一个API函数

很全面的WinRAR实用技巧系列 - imsoft.cnblogs

WinRAR也可以管理我的桌面时间长了,桌面上堆的东西实在太多,平时该如何管理呢?安装了WinRAR的朋友可以请它来帮忙,用它管理清除无用的桌面文件或图标. 以XP系统为例,系统所在目录是"c:\windows",假设用户名为"user",桌面上的图标和文件都在"c:\documents and settings\user\桌面"文件夹中.确定桌面上需要保存的图标和文件,在记事本中撰写文件列表,如: c:\documents and settin

Mac预览怎么用 Mac预览功能实用技巧大全

Mac预览怎么用?有很多的用户以为Mac自带的预览功能只具有简单的图片浏览功能,其实不然,其实"预览"是一款强大的看图.修图.改图软件,也同时是一款多功能的 PDF 阅读与编辑工具,接下来Pc6苹果小编给大家详细介绍一下Mac预览功能实用技巧. 目前的 Mac 预览程式可以支持 TIFF. PNG. JPEG. GIF. BMP. PDF 等主要文件格式的浏览与编辑,而单纯预览上也可以支持像是 Photoshop 等专业图像处理软件. Office 等专业文书处理软件所产生的特殊文件格

iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式

iOS开发实用技巧—Objective-C中的各种遍历(迭代)方式 说明: 1)该文简短介绍在iOS开发中遍历字典.数组和集合的几种常见方式. 2)该文对应的代码可以在下面的地址获得:https://github.com/HanGangAndHanMeimei/Code 一.使用for循环 要遍历字典.数组或者是集合,for循环是最简单也用的比较多的方法,示例如下: 1 //普通的for循环遍历 2 -(void)iteratorWithFor 3 { 4 //////////处理数组/////

NSString的八条实用技巧

NSString的八条实用技巧 有一篇文章写了:iOS开发之NSString的几条实用技巧 , 今天这篇,我们讲讲NSString的八条实用技巧.大家可以收藏起来,方便开发随时可以复制粘贴. 0.首字母大写 代码: //首字母大写 NSString *string = @"ligang"; NSLog(@"string: %@",[string capitalizedString]); 打印: 2015-07-16 23:06:11.652 iOSStrongDem

Android开发:TVBox智能机顶盒开发实用技巧分享

本文旨在指导想要进入Android TVBox智能机顶盒开发领域或刚刚进入Android TVBox开发领域的新人带路,愿你们越走越远! 实用工具篇 Eclipse+ADT 别问它干嘛用的,我也不知道. SercureCRT SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议. SecureCRT是一款用于连接运行包括Windows.UNIS和VMS的远程系统的理想工具. 通过使用内含的VCP命令行程序可以进行加密文件的传输.有流行CR

程序员在编程开发中的10个实用技巧

程序员在编程开发中的10个实用技巧,下面是我自己在工作中学到的一些简单的技巧和策略,希望能对各位有用.1.     橡皮鸭调试法不知道各位有没有这样的经历,当你正在给别人描述问题的时候,突然灵机一动想到了解决方案?这种情况的产生是有科学依据的.高谈阔论能让我们的大脑重新有条理地组织问题.在这种情况下,你的聊天对象就是“橡皮鸭”.团队中的每个人都应该积极主动乐意地成为彼此的“橡皮鸭”.有时候,如果你幸运的话,你的“橡皮鸭”搞不好还能给出有效的建议呢.2.     快速信息反馈一旦写好代码就要尽快得

iOS实用技巧 - 简易实现多皮肤功能

前言:不记得谁说的了,中国的用户大概是世界上最喜欢多皮肤功能的用户了.我很讨厌写安卓程序,图形界面设计工具及其难用,还不如手写,编辑器慢如蜗牛,智能提示总是跟不上我输入的速度,相同的功能,安卓的代码量至少是iOS的三倍,每写一行代码,都觉得自己的手指在滴血.可是安卓灵活统一的style功能确实很贴心!5之前,iOS平台上实现相同的功能一直没有个比较好的办法. iOS5之后,苹果将所有界面组件的设定,都绑定在一个叫UIAppearance的协议上了,你可以简单的通过UIAppearance设定组件

iOS实用技巧 - AFNetworking2安全的使用自签证书访问HTTPS

友情提示:本文使用的AFNetworking是最新git pull的2.3.1版本,如果想确认你机器上的AFNetworking版本,请打git tag命令查看. 绝大部分iOS程序的后台服务都是基于RESTful或者WebService的,不论在任何时候,你都应该将服务置于HTTPS上,因为它可以避免中间人攻击的问题,还自带了基于非对称密钥的加密通道!现实是这些年涌现了大量速成的移动端开发人员,这些人往往基础很差,完全不了解加解密为何物,使用HTTPS后,可以省去教育他们各种加解密技术,生活轻