admin管理员组

文章数量:1530850

2024年1月25日发(作者:)

用api函数读取硬盘的序列号

关于盘序列号有两种:

硬盘序列号: 英文名 Hard Disk Serial Number, 该号是出厂时生产厂家为

区别产品而设置的, 是唯一的, 是只读的, 利用硬盘序列号的

加密往往是利用其唯一和只读的特性, 大多是针对有序列号的

IDE HDD而言, 对于没有序列号或SCSI HDD硬盘则无能为力,

这也是利用它进行加密的局限性.

卷的序列号: 英文名 Volume Serial Number, 该号既可指软磁盘要得, 如:

A:盘和B:盘的, 又可以指硬盘的逻辑盘, 如: C:, D:...的,

是高级格式化时随机产生的, 是可以修改的, 所以利用其进行

加密,

在写程序时我们想对每一台计算机都生成一个唯一的标识,而且在一此共享软件中我们也看到,软件在不同的机器上生成了不同的标识,这是如何实现的呢,其实是软件有一部分程序读取了,本地计算机的一部分硬件参数(如硬盘序列号,网卡序列号等等),再通过一系列算法而得到了一个唯一标识,其实我们也可以通过一个api函数生成我们的唯一标识,由于硬盘人人都有,而网卡不一定每个人都有,所以以读硬盘序列号为例,

下面就先介绍一下我们要用到的api函数

BOOL GetVolumeInformation(

LPCTSTR lpRootPathName, // 硬盘的路径

LPTSTR lpVolumeNameBuffer, // 硬盘的卷标

DWORD nVolumeNameSize, // 卷标的字符串长度

LPDWORD lpVolumeSerialNumber, // 硬盘的序列号

LPDWORD lpMaximumComponentLength, // 最大的文件长度

LPDWORD lpFileSystemFlags, // 文件系统的一此标志

LPTSTR lpFileSystemNameBuffer, // 存储所在盘符的分区类型的长指针变量

DWORD nFileSystemNameSize // 分区类型的长指针变量所指向的字符串长度

);

如果上述函数成功就返回一个非0值。

光说不做,是不行了,我们还得实践一下:// 最大的文件长度

首选用MFC AppWizard建立一个基于Dialog base的对话框工程,名为GetHardID,点击finish。

加一个按钮,双击它,点击ok,并在对应的函数中加入如下代码:

LPCTSTR lpRootPathName="c:"; //取C盘

LPTSTR lpVolumeNameBuffer=new char[12];//磁盘卷标

DWORD nVolumeNameSize=12;// 卷标的字符串长度

DWORD VolumeSerialNumber;//硬盘序列号

DWORD MaximumComponentLength;// 最大的文件长度

LPTSTR lpFileSystemNameBuffer=new char[10];// 存储所在盘符的分区类型的长

指针变量

DWORD nFileSystemNameSize=10;// 分区类型的长指针变量所指向的字符串长度

DWORD FileSystemFlags;// 文件系统的一此标志

::GetVolumeInformation(lpRootPathName,

lpVolumeNameBuffer, nVolumeNameSize,

&VolumeSerialNumber, &MaximumComponentLength,

&FileSystemFlags,

lpFileSystemNameBuffer, nFileSystemNameSize);

CString str;

("Seria Num is %lx ",VolumeSerialNumber);

AfxMessageBox(str);

编译,链接并运行程序,单击按钮,在弹出的对话框中就是我们要的序列号。

对不对我们验证一下,进入dos窗口,打入"dir c:/p"命令,怎么样是不是和我们的程序显示的一模一样

这样我们就在功告成了。

=======cpu adapter id ===========

以下代码可以取得系统特征码(网卡MAC、硬盘序列号、CPU ID、BIOS编号)

BYTE szSystemInfo[4096]; // 在程序执行完毕后,此处存储取得的系统特征码

UINT uSystemInfoLen = 0; // 在程序执行完毕后,此处存储取得的系统特征码的长度

// 网卡 MAC 地址,注意: MAC 地址是可以在注册表中修改的

{

UINT uErrorCode = 0;

IP_ADAPTER_INFO iai;

ULONG uSize = 0;

DWORD dwResult = GetAdaptersInfo( &iai, &uSize );

if( dwResult == ERROR_BUFFER_OVERFLOW )

{

IP_ADAPTER_INFO* piai =

( IP_ADAPTER_INFO* )HeapAlloc( GetProcessHeap( ), 0, uSize );

if( piai != NULL )

{

dwResult = GetAdaptersInfo( piai, &uSize );

if( ERROR_SUCCESS == dwResult )

{

IP_ADAPTER_INFO* piai2 = piai;

while( piai2 != NULL && ( uSystemInfoLen +

piai2->AddressLength ) < 4096U )

{

CopyMemory( szSystemInfo + uSystemInfoLen,

piai2->Address, piai2->AddressLength );

uSystemInfoLen += piai2->AddressLength;

piai2 = piai2->Next;

}

}

else

{

uErrorCode = 0xF0000000U + dwResult;

}

VERIFY( HeapFree( GetProcessHeap( ), 0, piai ) );

}

else

{

return FALSE;

}

}

else

{

uErrorCode = 0xE0000000U + dwResult;

}

if( uErrorCode != 0U )

{

return FALSE;

}

}

// 硬盘序列号,注意:有的硬盘没有序列号

{

OSVERSIONINFO ovi = { 0 };

rsionInfoSize = sizeof( OSVERSIONINFO );

GetVersionEx( &ovi );

if( formId != VER_PLATFORM_WIN32_NT )

{

// Only

Windows 2000, Windows XP, Windows

return FALSE;

}

else

{

if( !WinNTHDSerialNumASPhysicalRead( szSystemInfo,

&uSystemInfoLen, 1024 ) )

{

WinNTHDSerialNumAsScsiRead( szSystemInfo, &uSystemInfoLen,

1024 );

}

}

}

// CPU ID

{

BOOL bException = FALSE;

BYTE szCpu[16] = { 0 };

UINT uCpuID = 0U;

__try

{

_asm

{

mov eax, 0

cpuid

mov dword ptr szCpu[0], ebx

mov dword ptr szCpu[4], edx

mov dword ptr szCpu[8], ecx

mov eax, 1

cpuid

mov uCpuID, edx

}

}

__except( EXCEPTION_EXECUTE_HANDLER )

{

bException = TRUE;

}

if( !bException )

{

CopyMemory( szSystemInfo + uSystemInfoLen, &uCpuID,

sizeof( UINT ) );

uSystemInfoLen += sizeof( UINT );

uCpuID = strlen( ( char* )szCpu );

CopyMemory( szSystemInfo + uSystemInfoLen, szCpu, uCpuID );

uSystemInfoLen += uCpuID;

}

}

// BIOS 编号,支持 AMI, AWARD, PHOENIX

{

SIZE_T ssize;

LARGE_INTEGER so;

t=0x000f0000;

rt=0x00000000;

ssize=0xffff;

wchar_t strPH[30]=Ldevicephysicalmemory;

DWORD ba=0;

UNICODE_STRING struniph;

=strPH;

=0x2c;

MLength =0x2e;

OBJECT_ATTRIBUTES obj_ar;

obj_utes =64;

obj_ =24;

obj_Name=&struniph;

obj_rectory=0;

obj_tyDescriptor=0;

obj_tyQualityOfService =0;

HMODULE hinstLib = LoadLibrary("");

ZWOS ZWopenS=(ZWOS)GetProcAddress(hinstLib,"ZwOpenSection");

ZWMV

ZWmapV=(ZWMV)GetProcAddress(hinstLib,"ZwMapViewOfSection");

ZWUMV

ZWunmapV=(ZWUMV)GetProcAddress(hinstLib,"ZwUnmapViewOfSection");

//调用函数,对物理内存进行映射

HANDLE hSection;

if( 0 == ZWopenS(&hSection,4,&obj_ar) &&

0 == ZWmapV(

( HANDLE )hSection, //打开Section时得到的句柄

( HANDLE )0xFFFFFFFF, //将要映射进程的句柄,

&ba, //映射的基址

0,

0xFFFF, //分配的大小

&so, //物理内存的地址

&ssize, //指向读取内存块大小的指针

1, //子进程的可继承性设定

0, //分配类型

2 //保护类型

) )

//执行后会在当前进程的空间开辟一段64k的空间,并把f000:0000到f000:ffff处的内容映射到这里

//映射的基址由ba返回,如果映射不再有用,应该用ZwUnmapViewOfSection断

开映射

{

BYTE*

PBiosSerial = ( BYTE* )ba;

UINT uBiosSerialLen = FindAwardBios( &pBiosSerial );

if( uBiosSerialLen == 0U )

{

uBiosSerialLen = FindAmiBios( &pBiosSerial );

if( uBiosSerialLen == 0U )

{

uBiosSerialLen = FindPhoenixBios( &pBiosSerial );

}

}

if( uBiosSerialLen != 0U )

{

CopyMemory( szSystemInfo + uSystemInfoLen, pBiosSerial,

uBiosSerialLen );

uSystemInfoLen += uBiosSerialLen;

}

ZWunmapV( ( HANDLE )0xFFFFFFFF, ( void* )ba );

}

}

// 完毕, 系统特征码已取得。

本文标签: 硬盘序列号映射