思路很简单(容易破解):
1. 在代码内设定最后使用期限
2. 程序运行时首先从网络获取时间
3. 获取网络时间失败(如用户未联网)或者网络时间显示已经超过设定期限,程序退出。
4. 特别注意:程序需要在Release模式下编译运行,否则会出错(由CSocket.Create()函数引起,具体原因不明)。
5. 以下附此方法的代码,实现过程参考了 《互联网对时》中的代码。
6. 作者主页: http://blog.csdn.net/word_world
#ifndef _DEBUG
#include <afxsock.h>
#endif
void main()
{
#ifndef _DEBUG // Release模式下才使用
if (ExceedTimeLimit(2016, 8, 20))
return;
#endif
printf("Hello World!\n");
}
bool ExceedTimeLimit(const int yearLimit, const int monthLimit, const int dayLimit, const int hourLimit = 23, const int minuteLimit = 59, const int secondLimit = 59)
{
bool timeLimitExceed = false;
const int limitCnt = 6;
int timeLimit[limitCnt] = { // 超期时期
yearLimit, monthLimit, dayLimit, hourLimit, minuteLimit, secondLimit
};
const int svrCnt = 5;
const char * tmSvrNames[] = {
"time.nist.gov",
"time-a.nist.gov",
"time-b.nist.gov",
"time-nw.nist.gov",
"nist1.nyc.certifiedtime.com",
};
// 时间同步
CSocket sockClient;
TIME_ZONE_INFORMATION tzinfo; // 时间
DWORD dwStdDaylight;
long bias, sminute, shour;
//初始化CSocket
if(!AfxSocketInit())
{
MessageBox(0, "初始化失败", "通知", MB_ICONINFORMATION);
return true;
}
std::cout<<" \n 请确保您的计算机已经连接到网络.\n Please enusure the computer have access to the Internet.\n";
bool firstCheck = true; // 第一次检查网络
CONNECTED:
if(!firstCheck)
std::cout<<" 连接已恢复"<<std::endl;
sockClient.Create(); //创建socket
dwStdDaylight = GetTimeZoneInformation(&tzinfo); //获取时区与UTC的时间差 应该返回-8
bias = tzinfo.Bias;
if (dwStdDaylight == TIME_ZONE_ID_INVALID) //函数执行失败
{
// std::cout<<"TIME_ZONE_ID_INVALID"<<std::endl;
std::cout << "system error!\n";
return true;
}
else if (dwStdDaylight == TIME_ZONE_ID_STANDARD) //标准时间有效
bias += tzinfo.StandardBias;
else if (dwStdDaylight == TIME_ZONE_ID_DAYLIGHT) //夏令时间
bias += tzinfo.DaylightBias;
shour = bias / 60;
sminute = bias % 60; //fmod(bias,60);
//循环判断服务器是否连接成功
int i;
for (i = 0; i < svrCnt; i++)
{
std::cout<<" # "<<i<<" : we are trying to connect to \""<<tmSvrNames[i]<<"\".\n";
if (1 == sockClient.Connect(tmSvrNames[i], 13))
break;
}
if(0<i && i<svrCnt && firstCheck)
{
firstCheck = false;
goto CONNECTED;
}
const int timeLen = 256;
unsigned char szTime[timeLen]; //临时接收数据要求足够的大
//memset(szTime, 0, sizeof(szTime));
memset(szTime, 0, timeLen);
int recvBytes = 0;
int recvTimes = 0, maxRecvTime = 5;
do{
recvBytes = sockClient.Receive(szTime, sizeof(szTime)); //接收服务器发送来得的数据
recvTimes++;
if (recvBytes <= 0)
{
std::cout << "\r try" << recvTimes << ": Please check out your connection, enusure your computer on line.";
Sleep(1000);
}
else
break;
} while (recvTimes<maxRecvTime);
if (recvTimes >1)
std::cout << std::endl;
sockClient.Close(); //关闭socket
// std::cout<<szTime<<std::endl;
if (recvTimes == maxRecvTime)
{
MessageBox(0, " 无法连接到网络", "通知", MB_ICONINFORMATION);
return true; // 无法连接而超期
}
CString strTime;
strTime.Format("%s", szTime);
int first = strTime.Find("-");
int second = strTime.Find("-", first + 1);
int tfirst = strTime.Find(":");
int tsecond = strTime.Find(":", tfirst + 1);
int hyear = 2000 + atoi(strTime.Mid(first - 2, 2));
int hmonth = atoi(strTime.Mid(first + 1, 2));
int hday = atoi(strTime.Mid(second + 1, 2));
int hhour = atoi(strTime.Mid(tfirst - 2, 2)) - shour;
int hminute = atoi(strTime.Mid(tfirst + 1, 2)) - sminute;
int hsecond = atoi(strTime.Mid(tsecond + 1, 2));
int timeNow[limitCnt] = { // 网络获取的当前时间
hyear, hmonth, hday,
hhour, hminute, hsecond
};
for (i = 0; i<limitCnt; i++)
{
//std::cout<<timeNow[i]<<" ";
if (timeNow[i] !=timeLimit[i])
break;
}
if(i<limitCnt && timeNow[i] >timeLimit[i])
timeLimitExceed = true;
if (timeLimitExceed)
{
CString errMsg = "未知错误";
errMsg.Format(" 已过有效期 %d-%d-%d %2d:%2d:%2d.", yearLimit, monthLimit, dayLimit, hourLimit, minuteLimit, secondLimit);
std::cout << " 已过有效期 " << yearLimit << "-" << monthLimit << "-" << dayLimit << " " << hourLimit << ":" << minuteLimit << ":" << secondLimit << ". \n";
//std::cout<<errMsg<<std::endl;
MessageBox(0, errMsg, "通知", MB_ICONINFORMATION);
}
std::cout << " ********** 感谢使用授权软件 **********\n\n";
Sleep(1000);
system("cls");
return timeLimitExceed;
}