..

解决方案 »

  1.   

    以下代码可以取得系统特征码(网卡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\\device\\physicalmemory;         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 );
            }
        }