在软件的保护注册中,特别是实现一机一码中,获得硬件编码是一个很重要的工作
1)MAC地址
//对每块网卡,通过网卡编号,获得MAC地址
//网卡编号一般从0开始,但是2000中并不一定是连续分配
for (int i=0 ;i<lenum.length;i++)
{
//发送一个NCBRESET命令,进行初始化
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command = NCBRESET ;
ncb.ncb_lana_num = lenum.lana[i];//MAC NUM
uRetCode = Netbios(&ncb);
//发送NCBASTAT命令获得网卡信息
memset(&ncb,0,sizeof(ncb));
ncb.ncb_command = NCBASTAT;
ncb.ncb_lana_num = lenum.lana[i];
strcpy((char *)ncb.ncb_callname,"* ");
ncb.ncb_buffer = (unsigned char *)&Adapter;
ncb.ncb_length = sizeof(Adapter);
uRetCode = Netbios(&ncb)[color=#008000];
2)硬盘号
逻辑硬盘序列号
GetVolumeInformation(“c:\\”,VolumeNameBuffer,256,&VolumeSerialNumber,&MaximumComponentLength,&FileSystemFlags,FileSystemNameBuffer,256);
但是这个是一个后天信息,而且有可能作弊
然后我们想从硬盘中直接提取信息,但是这个在windows下是很不方便的,因为windows不允许直接I/O操作,同时windows也不提供相应的api给我们,怎么办呢?
static unsigned int WaitHardDiskIde()
{
BYTE xx;
Waiting:
_asm
{
mov dx,0x1f7
in al,dx
cmp al,0x80
jb Endwaiting
jmp Waiting
}
EndWaiting:
_asm
{
mov xx,al
}
return (xx);
}
void __declspec(naked)InterruptProcess(void)
{
int xx;
int i;
WORD temp;
//store
_asm
{
push eax
push ebx
push ecx
push edx
push esi
}
WaitHardDiskIde();//等待硬盘空闲
_asm
{
mov dx,0x1f6
mov al,0xa0
out dx,al
}
xx = WaitHardDiskIde();
if ((xx&0x58)!=0x58)
{
goto EndIntrupt;
}
for (i=0;i<256;i++)
{
_asm
{
mov dx,0x1f0
in ax,dx
mov temp,ax
}
serial[i] = temp ;
}
EndIntrupt:
//恢复寄存器
_asm
{
pop esi
pop edx
pop ecx
pop ebx
pop eax
iretd
}
}
3)Cpu编号
这个是破解一个软件的时候发现的,结果真的是有实际用途的
_asm
{
mov eax,1
cupid
mov ps,eax
mov mi,ebx
mov ff,edx
}