VC之关于软件注册码mac cpuID 硬盘ID.docx
《VC之关于软件注册码mac cpuID 硬盘ID.docx》由会员分享,可在线阅读,更多相关《VC之关于软件注册码mac cpuID 硬盘ID.docx(9页珍藏版)》请在冰豆网上搜索。
VC之关于软件注册码maccpuID硬盘ID
VC之获取计算机网卡mac地址
(2009-08-0221:
59:
24)
转载
标签:
vc系列
杂谈
分类:
技术乱弹
网卡的物理地址即mac地址全球唯一,占用六个字节。
(正规厂家的网卡mac地址全球唯一,盖因有统一的委员会进行分配,一般前3个字节为生产厂商ID,后三个字节为产品子ID.mac地址一般烧写在网卡的prom中,上电后读入网络协议芯片的mac地址寄存器中。
笔者曾开发了一个基于单片机的远程测控系统,采用C8051F120和RTL8019as实现,当然委员会不可能给笔者分配一个mac,哥们便将其定为01-02-03-04-05-06,不想通过sniffer进行调试时发现该mac属于3com公司,一不小心侵了3com的权。
由于mac地址会存在地址寄存器中,这就为某些修改mac的软件提供了可乘之机,当然其修改也是暂时的,这是题外话,暂且不表)。
一般情况下,获取mac地址生成序列号可以保护我们的软件版权,这也是一帆风颇费周章的目的。
获取mac地址,一可以使用NetBIOS函数,二可使用IP助手函数。
一帆风推荐使用后者,因为:
Netbios函数得到的MAC经常是不准确的。
它依赖于机器上安装网络协议的顺序。
比如先装IPX协议再装TCP协议,与先装TCP再装IPX所得到的MAC很有可能不一致。
这是因为Netbios函数会得到很多的虚拟MAC地址而不是真正的网卡MAC。
IPCONFIG就是使用IP助手函数来做的。
以下是我的做法请参考:
#include "iphlpapi.h"
#pragma comment(lib, "iphlpapi.lib ")
//----------------------------------------------
//功能:
获得网卡物理地址
//参数:
strMac返回网卡物理地址
//返回:
TRUE成功
//FALSE失败
//----------------------------------------------
BOOL CCApp:
:
GetMacAddress(CString &strMac)
{
PIP_ADAPTER_INFOpAdapterInfo;
DWORDAdapterInfoSize;
TCHARszMac[32] = {0};
DWORDErr;
AdapterInfoSize = 0;
Err = GetAdaptersInfo(NULL, &AdapterInfoSize);
if((Err !
= 0) && (Err !
= ERROR_BUFFER_OVERFLOW)){
TRACE("获得网卡信息失败!
");
return FALSE;
}
// 分配网卡信息内存
pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, AdapterInfoSize);
if(pAdapterInfo == NULL){
TRACE("分配网卡信息内存失败");
return FALSE;
}
if(GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize) !
= 0){
TRACE(_T("获得网卡信息失败!
\n"));
GlobalFree(pAdapterInfo);
return FALSE;
}
strMac.Format(_T("%02X%02X%02X%02X%02X%02X"),
pAdapterInfo->Address[0],
pAdapterInfo->Address[1],
pAdapterInfo->Address[2],
pAdapterInfo->Address[3],
pAdapterInfo->Address[4],
pAdapterInfo->Address[5]);
GlobalFree(pAdapterInfo);
return TRUE;
}
应注意以下几点:
1。
iphlpapi.h和iphlpapi.lib在VC中不包含,在sdk中有,应下载sdk,并在vc路径中包含sdk的include和lib目录;
2。
应将include和lib放在vc包含路径中的第一个。
该函数在VC6+sdk平台下开发,在WinXPsp2+联想T61平台下测试通过。
VC 之获取硬盘序列号
(2009-08-0314:
36:
17)
转载
标签:
vc系列
it
分类:
技术乱弹
上一回,一帆风给大家讲了讲如何读取计算机的MAC地址,这次聊聊怎么获取硬盘序列号。
硬盘物理序列号是硬盘的出厂序列号,它是全球都是唯一的,不会随着系统的安装、硬盘的格式化等操作而改变,跟mac地址一样都具有唯一性。
1,第一步:
创建设备对象,得到设备句柄,设备为硬盘。
{
CStringsFilePath;
sFilePath.Format("\\\\.\\PHYSICALDRIVE%d",driver);
HANDLEhFile=:
:
CreateFile(sFilePath,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,
0,NULL);
DWORDdwBytesReturned;
GETVERSIONINPARAMSgvopVersionParams;
DeviceIoControl(hFile, //向设备对象发送SMART_GET_VERSION设备请求,获取硬盘属性
SMART_GET_VERSION,
NULL,
0,
&gvopVersionParams,
sizeof(gvopVersionParams),
&dwBytesReturned,NULL);
if(gvopVersionParams.bIDEDeviceMap<=0) return-2;
2。
第二步,发送SMART_RCV_DRIVE_DATA设备请求,获取硬盘详细信息。
//IDEorATAPIIDENTIFYcmd
intbtIDCmd=0;
SENDCMDINPARAMSInParams;
intnDrive=0;
btIDCmd=(gvopVersionParams.bIDEDeviceMap>>nDrive&0x10)?
IDE_ATAPI_IDENTIFY:
IDE_ATA_IDENTIFY;
//输出参数
BYTEbtIDOutCmd[sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1];
if(DoIdentify(hFile,
&InParams,
(PSENDCMDOUTPARAMS)btIDOutCmd,
(BYTE)btIDCmd,
(BYTE)nDrive,&dwBytesReturned)==FALSE) return-3;
:
:
CloseHandle(hFile);
DWORDdwDiskData[256];
USHORT*pIDSector;//对应结构IDSECTOR,见头文件
pIDSector=(USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer;
for(inti=0;i<256;i++) dwDiskData[i]=pIDSector[i];
//取系列号
ZeroMemory(szSerialNumber,sizeof(szSerialNumber));
strcpy(szSerialNumber,ConvertToString(dwDiskData,10,19));
//取模型号
ZeroMemory(szModelNumber,sizeof(szModelNumber));
strcpy(szModelNumber,ConvertToString(dwDiskData,27,46));
return0;
}
BOOL__fastcallDoIdentify(HANDLEhPhysicalDriveIOCTL,
PSENDCMDINPARAMSpSCIP,
PSENDCMDOUTPARAMSpSCOP,
BYTEbtIDCmd,
BYTEbtDriveNum,
PDWORDpdwBytesReturned)
{
pSCIP->cBufferSize=IDENTIFY_BUFFER_SIZE;
pSCIP->irDriveRegs.bFeaturesReg=0;
pSCIP->irDriveRegs.bSectorCountReg =1;
pSCIP->irDriveRegs.bSectorNumberReg=1;
pSCIP->irDriveRegs.bCylLowReg =0;
pSCIP->irDriveRegs.bCylHighReg=0;
pSCIP->irDriveRegs.bDriveHeadReg=(btDriveNum&1)?
0xB0:
0xA0;
pSCIP->irDriveRegs.bCommandReg=btIDCmd;
pSCIP->bDriveNumber=btDriveNum;
pSCIP->cBufferSize=IDENTIFY_BUFFER_SIZE;
returnDeviceIoControl( hPhysicalDriveIOCTL,
SMART_RCV_DRIVE_DATA,
(LPVOID)pSCIP,
sizeof(SENDCMDINPARAMS)-1,
(LPVOID)pSCOP,
sizeof(SENDCMDOUTPARAMS)+IDENTIFY_BUFFER_SIZE-1,
pdwBytesReturned,NULL);
}
char*__fastcallConvertToString(DWORDdwDiskData[256],intnFirstIndex,intnLastIndex)
{
staticcharszResBuf[1024];
charss[256];
intnIndex=0;
intnPosition=0;
for(nIndex=nFirstIndex;nIndex<=nLastIndex;nIndex++)
{
ss[nPosition]=(char)(dwDiskData[nIndex]/256);
nPosition++;
//GetlowBYTEfor2ndcharacter
ss[nPosition]=(char)(dwDiskData[nIndex]%256);
nPosition++;
}
//Endthestring
ss[nPosition]='\0';
inti,index=0;
for(i=0;i {
if(ss[i]==0||ss[i]==32) continue;
szResBuf[index]=ss[i];
index++;
}
szResBuf[index]=0;
returnszResBuf;
}
详细信息请搜索msdn。
上述代码在WinXPsp2平台测试通过。
VC之获取CPU序列号
(2009-08-0318:
31:
18)
转载
标签:
vc系列
杂谈
分类:
技术乱弹
首先说明,CPU序列号并不是全球唯一的,以Intel为例,其不同型号的CPU序列号肯定不同,但不保证同型号的CPU序列号也各不相同,但据说P3后都是全球唯一的,一帆风没有详细考证。
CPU序列号有一个好处就是非常难以修改,至少目前还没听说。
将CPUID和MACid、硬盘id组合起来生成软件序列号,可以大大增加序列号的安全性。
(后两者都可以通过软件方法修改)。
好了,转入正题,闷头发源码:
CStringCGetCpuIDDlg:
:
GetCPUID()
{
CStringCPUID;
unsignedlongs1,s2;
unsignedcharvendor_id[]="------------";
charsel;
sel='1';
CStringVernderID;
CStringMyCpuID,CPUID1,CPUID2;
switch(sel)
{
case'1':
__asm{
xoreax,eax //eax=0:
取Vendor信息
cpuid //取cpuid指令,可在Ring3级使用
movdwordptrvendor_id,ebx
movdwordptrvendor_id[+4],edx
movdwordptrvendor_id[+8],ecx
}
VernderID.Format("%s-",vendor_id);
__asm{
moveax,01h //eax=1:
取CPU序列号
xoredx,edx
cpuid
movs1,edx
movs2,eax
}
CPUID1.Format("%08X%08X",s1,s2);
__asm{
moveax,03h
xorecx,ecx
xoredx,edx
cpuid
movs1,edx
movs2,ecx
}
CPUID2.Format("%08X%08X",s1,s2);
break;
case'2':
{
__asm{
movecx,119h
rdmsr
oreax,00200000h
wrmsr
}
}
AfxMessageBox("CPUidisdisabled.");
break;
}
MyCpuID=CPUID1+CPUID2;
CPUID=MyCpuID;
returnCPUID;
}
以上代码在WindowsXPsp2+intelP4上测试通过,能否在AMD的CPU上测试通过有待验证。
来源:
(-VC之获取CPU序列号_一帆风_新浪博客
VC之关于软件注册码
(2009-08-0408:
05:
51)
转载
上三篇blog,macid cpuid harddiskserialnumber,其目的都是获得机器的唯一标识,虽然cpuid不唯一,另外两个有可能被修改,但将三者结合起来,作为机器的唯一标识,非专业用户还是很难破解的。
不失为保护软件版权的一个好方法。
----软件版权保护水平到一个什么水平,这是一个问题,太弱容易被破解,太强代价太高。
理论上不存在破解不了的加密机制,关键在于破解需要多大的成本。
因此,根据你的软件价值选取合适的保护机制:
如果你的软件价值好几万,那么选取好的保护方式是值得的;如果你的软件卖不了钱,那有没有保护机制就区别不大了。
因此,我们的政策是,“保护钱多得,不管没钱的”。
现在假设得到了机器的唯一标识(blog,macid cpuid harddiskserialnumber),用户通过一定的手段(来人来电来信来妹儿)告知你该表示,如何根据它生成注册码以告知用户呢?
简单的办法,将该表示进行一定的运算,比如每字节加23,再整个字符串反序,再首尾异或,在每字节右移2位,。
。
。
,总之,运算方法随你的大小便,尽量多算几次,提高解密的难度。
一顿狂算以后,得到注册码,告知用户,用户输入,程序运行同样的算法,生成注册码和用户输入的相比对,一致,OK,合法用户,NO,Sorry,Norighttouse.
经过以上的折腾,可以保证大部分(应不小于90%,因为专业级的用户毕竟不多)用户使用合法版本。
至于如何防止另外的9%(有1%是防不胜防的)以后再讲,当然,代价也是蛮大的。
来源:
(-VC之关于软件注册码_一帆风_新浪博客