转载]取硬盘ID的API实现

系统特征码

================================
以下代码可以取得系统特征码(网卡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 };
       ovi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
       GetVersionEx( &ovi );
       
       if( ovi.dwPlatformId != VER_PLATFORM_WIN32_NT )
       {
           // Only Windows 2000, Windows XP, Windows Server 2003...
           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;
       so.LowPart=0x000f0000;
       so.HighPart=0x00000000;
       ssize=0xffff;
       wchar_t strPH[30]=L"devicephysicalmemory";

       DWORD ba=0;

       UNICODE_STRING struniph;
       struniph.Buffer=strPH;
       struniph.Length=0x2c;
       struniph.MaximumLength =0x2e;

       OBJECT_ATTRIBUTES obj_ar;
       obj_ar.Attributes =64;
       obj_ar.Length =24;
       obj_ar.ObjectName=&struniph;
       obj_ar.RootDirectory=0;
       obj_ar.SecurityDescriptor=0;
       obj_ar.SecurityQualityOfService =0;

       HMODULE hinstLib = LoadLibrary("ntdll.dll");
       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 );
       }
    }
    // 完毕, 系统特征码已取得。

原文地址:https://www.cnblogs.com/mjgw/p/12555410.html