首页
社区
课程
招聘
[分享]获取 硬盘ID/网卡MAC 的代码
发表于: 2008-9-2 13:31 26737

[分享]获取 硬盘ID/网卡MAC 的代码

2008-9-2 13:31
26737

闲来无事,整理了 获取硬盘ID/网卡MAC 的 源代码。

// =============================================================================
// xID.h - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#pragma once

#ifndef _X_ID_
#define _X_ID_

typedef struct _IDSECTOR {
        USHORT        wGenConfig;
        USHORT        wNumCyls;
        USHORT        wReserved;
        USHORT        wNumHeads;
        USHORT        wBytesPerTrack;
        USHORT        wBytesPerSector;
        USHORT        wSectorsPerTrack;
        USHORT        wVendorUnique[3];
        CHAR        sSerialNumber[20];
        USHORT        wBufferType;
        USHORT        wBufferSize;
        USHORT        wECCSize;
        CHAR        sFirmwareRev[8];
        CHAR        sModelNumber[40];
        USHORT        wMoreVendorUnique;
        USHORT        wDoubleWordIO;
        USHORT        wCapabilities;
        USHORT        wReserved1;
        USHORT        wPIOTiming;
        USHORT        wDMATiming;
        USHORT        wBS;
        USHORT        wNumCurrentCyls;
        USHORT        wNumCurrentHeads;
        USHORT        wNumCurrentSectorsPerTrack;
        ULONG        ulCurrentSectorCapacity;
        USHORT        wMultSectorStuff;
        ULONG        ulTotalAddressableSectors;
        USHORT        wSingleWordDMA;
        USHORT        wMultiWordDMA;
        BYTE        bReserved[128];
} IDSECTOR, *PIDSECTOR;

extern char xID[ 64 ];

void xGetHardDiskID();
void xGetNetCardID();

#endif

// =============================================================================
// xID.cpp - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#include "stdafx.h"

#include "xID.h"

#include <winioctl.h>

char xID[ 64 ] = { 0 };

void xGetHardDiskID()
{
        HANDLE hDevice;
        BOOL bResult;
        DWORD dwRet;

        memset( ( void* )xID,0,64 );

        hDevice = CreateFile( "\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL        );
        if( hDevice == INVALID_HANDLE_VALUE ) return;

        GETVERSIONINPARAMS vip;
        bResult = DeviceIoControl( hDevice,SMART_GET_VERSION,NULL,0,&vip,sizeof( GETVERSIONINPARAMS ),&dwRet,NULL );
        if( !bResult ) {
                CloseHandle( hDevice );
                return;
        }
        if( vip.bIDEDeviceMap == 0 ) {
                CloseHandle( hDevice );
                return;
        }

        SENDCMDINPARAMS cmdin;
        memset( ( void* )&cmdin,0,sizeof( cmdin ) );
        cmdin.irDriveRegs.bSectorCountReg = 0x01;
        cmdin.irDriveRegs.bSectorNumberReg = 0x01;
        cmdin.irDriveRegs.bFeaturesReg = 0x00;
        cmdin.bDriveNumber = 0x00;
        cmdin.irDriveRegs.bCylLowReg = 0x00;
        cmdin.irDriveRegs.bCylHighReg = 0x00;
        cmdin.irDriveRegs.bDriveHeadReg = 0xa0;
        cmdin.irDriveRegs.bCommandReg = 0xec;
        cmdin.cBufferSize = 0x200;

        BYTE cmdout[ sizeof( SENDCMDOUTPARAMS ) + 512 -1 ];
        memset( ( void* )cmdout,0,sizeof( SENDCMDOUTPARAMS ) + 512 -1 );
        SENDCMDOUTPARAMS* pcmdout = ( SENDCMDOUTPARAMS* )&cmdout;
        pcmdout->cBufferSize = 0x200;

        bResult = DeviceIoControl(  hDevice,SMART_RCV_DRIVE_DATA,( LPVOID )&cmdin,sizeof( SENDCMDINPARAMS ),cmdout,sizeof( cmdout ),&dwRet,NULL );
        if( !bResult ) {
                CloseHandle( hDevice );
                return;
        }

        IDSECTOR* pisd = ( IDSECTOR* )&cmdout[ sizeof( SENDCMDOUTPARAMS ) - 1 ];

        char tmpch1,tmpch2;
        int j = 0;
        for( int i = 0; i < sizeof( pisd->sSerialNumber ); i += 2 ) {
                tmpch1 = pisd->sSerialNumber[ i + 1 ];
                tmpch2 = pisd->sSerialNumber[ i  ];
                if( isdigit( tmpch1 ) || isalpha( tmpch1 ) ) {
                        xID[ j++ ] = tmpch1;
                }
                if( isdigit( tmpch2 ) || isalpha( tmpch2 ) ) {
                        xID[ j++ ] = tmpch2;
                }
        }

        CloseHandle( hDevice );
}

#include <Iphlpapi.h.>
#pragma comment( lib,"Iphlpapi.lib" )

void xGetNetCardID()
{
        PIP_ADAPTER_INFO pinfo;
        unsigned char buf[ 4096 ];
        unsigned long len = 4096;
        unsigned long nError = 0;

        ZeroMemory( buf,4096 );
        pinfo = ( PIP_ADAPTER_INFO )buf;

        nError = GetAdaptersInfo( pinfo,&len );
        if( nError == ERROR_SUCCESS ) {
                sprintf( xID,"%02X%02X%02X%02X%02X%02X",pinfo->Address[0],pinfo->Address[1],pinfo->Address[2],pinfo->Address[3],pinfo->Address[4],pinfo->Address[5] );
        }
}

===〉调用相应的函数,ID 保存在 xID 数组中。
===〉一般地,要从 PhysicalDrive0/PhysicalDrive1/PhysicalDrive2/PhysicalDrive3 循环获取。
===〉以下为 VBScript 代码

strComputer = "."  'Dot (.) equals local computer in WMI

Set objWMIService = GetObject("winmgmts:\\" & strComputer)
Set colServices = objWMIService.InstancesOf("Win32_PhysicalMedia")

For Each objService In colServices
    WScript.Echo "Win32_PhysicalMedia--Tag         :" & objService.Tag & vbCrLf & _
                 "                   --SerialNumber:" & Trim(objService.SerialNumber) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_Processor")

For Each objService In colServices
    WScript.Echo "Win32_Processor--ProcessorId:" & objService.ProcessorId & vbCrLf & _
                 "               --UniqueId   :" & Trim(objService.UniqueId) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_NetworkAdapter")

For Each objService In colServices
    WScript.Echo "Win32_NetworkAdapter--MACAddress:" & objService.MACAddress & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BIOS")

For Each objService In colServices
    WScript.Echo "Win32_BIOS--SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BaseBoard")

For Each objService In colServices
    WScript.Echo "Win32_BaseBoard--Tag          :" & objService.Tag & vbCrLf & _
                 "               --SerialNumber :" & objService.SerialNumber & vbCrLf
Next


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (27)
雪    币: 232
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢LZ分享,
2008-9-2 15:04
0
雪    币: 563
活跃值: (95)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
好强!! 谢谢分享
2008-9-2 22:53
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
还有人来做广告,(*^__^*) 嘻嘻……
2008-9-6 10:09
0
雪    币: 817
活跃值: (1927)
能力值: ( LV12,RANK:2670 )
在线值:
发帖
回帖
粉丝
5
// 以下代码可以取得系统特征码
//(网卡MAC、硬盘序列号、CPU ID、BIOS编号)
#include <afx.h>
#include <stdio.h>
#include <iphlpapi.h>

#define  FILE_DEVICE_SCSI              0x0000001b
#define  IOCTL_SCSI_MINIPORT_IDENTIFY  ( ( FILE_DEVICE_SCSI << 16 ) + 0x0501 )

#define  IOCTL_SCSI_MINIPORT 0x0004D008  //  see NTDDSCSI.H for definition

#define  IDENTIFY_BUFFER_SIZE  512
#define  SENDIDLENGTH  ( sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE )

#define  IDE_ATAPI_IDENTIFY  0xA1  //  Returns ID sector for ATAPI.
#define  IDE_ATA_IDENTIFY    0xEC  //  Returns ID sector for ATA.
#define  DFP_RECEIVE_DRIVE_DATA   0x0007c088

typedef struct _IDSECTOR
{
    USHORT  wGenConfig;
    USHORT  wNumCyls;
    USHORT  wReserved;
    USHORT  wNumHeads;
    USHORT  wBytesPerTrack;
    USHORT  wBytesPerSector;
    USHORT  wSectorsPerTrack;
    USHORT  wVendorUnique[3];
    CHAR    sSerialNumber[20];
    USHORT  wBufferType;
    USHORT  wBufferSize;
    USHORT  wECCSize;
    CHAR    sFirmwareRev[8];
    CHAR    sModelNumber[40];
    USHORT  wMoreVendorUnique;
    USHORT  wDoubleWordIO;
    USHORT  wCapabilities;
    USHORT  wReserved1;
    USHORT  wPIOTiming;
    USHORT  wDMATiming;
    USHORT  wBS;
    USHORT  wNumCurrentCyls;
    USHORT  wNumCurrentHeads;
    USHORT  wNumCurrentSectorsPerTrack;
    ULONG   ulCurrentSectorCapacity;
    USHORT  wMultSectorStuff;
    ULONG   ulTotalAddressableSectors;
    USHORT  wSingleWordDMA;
    USHORT  wMultiWordDMA;
    BYTE    bReserved[128];
} IDSECTOR, *PIDSECTOR;

typedef struct _DRIVERSTATUS

{
    BYTE  bDriverError;  //  Error code from driver, or 0 if no error.
    BYTE  bIDEStatus;    //  Contents of IDE Error register.
    //  Only valid when bDriverError is SMART_IDE_ERROR.
    BYTE  bReserved[2];  //  Reserved for future expansion.
    DWORD  dwReserved[2];  //  Reserved for future expansion.
} DRIVERSTATUS, *PDRIVERSTATUS, *LPDRIVERSTATUS;

typedef struct _SENDCMDOUTPARAMS
{
    DWORD         cBufferSize;   //  Size of bBuffer in bytes
    DRIVERSTATUS  DriverStatus;  //  Driver status structure.
    BYTE          bBuffer[1];    //  Buffer of arbitrary length in which to store the data read from the                                                       // drive.
} SENDCMDOUTPARAMS, *PSENDCMDOUTPARAMS, *LPSENDCMDOUTPARAMS;

typedef struct _SRB_IO_CONTROL
{
    ULONG HeaderLength;
    UCHAR Signature[8];
    ULONG Timeout;
    ULONG ControlCode;
    ULONG ReturnCode;
    ULONG Length;
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;

typedef struct _IDEREGS
{
    BYTE bFeaturesReg;       // Used for specifying SMART "commands".
    BYTE bSectorCountReg;    // IDE sector count register
    BYTE bSectorNumberReg;   // IDE sector number register
    BYTE bCylLowReg;         // IDE low order cylinder value
    BYTE bCylHighReg;        // IDE high order cylinder value
    BYTE bDriveHeadReg;      // IDE drive/head register
    BYTE bCommandReg;        // Actual IDE command.
    BYTE bReserved;          // reserved for future use.  Must be zero.
} IDEREGS, *PIDEREGS, *LPIDEREGS;

typedef struct _SENDCMDINPARAMS
{
    DWORD     cBufferSize;   //  Buffer size in bytes
    IDEREGS   irDriveRegs;   //  Structure with drive register values.
    BYTE bDriveNumber;       //  Physical drive number to send
    //  command to (0,1,2,3).
    BYTE bReserved[3];       //  Reserved for future expansion.
    DWORD     dwReserved[4]; //  For future use.
    BYTE      bBuffer[1];    //  Input buffer.
} SENDCMDINPARAMS, *PSENDCMDINPARAMS, *LPSENDCMDINPARAMS;

typedef struct _GETVERSIONOUTPARAMS
{
    BYTE bVersion;      // Binary driver version.
    BYTE bRevision;     // Binary driver revision.
    BYTE bReserved;     // Not used.
    BYTE bIDEDeviceMap; // Bit map of IDE devices.
    DWORD fCapabilities; // Bit mask of driver capabilities.
    DWORD dwReserved[4]; // For future use.
} GETVERSIONOUTPARAMS, *PGETVERSIONOUTPARAMS, *LPGETVERSIONOUTPARAMS;

//////////////////////////////////////////////////////////////////////

//结构定义
typedef struct _UNICODE_STRING
{
    USHORT  Length;//长度
    USHORT  MaximumLength;//最大长度
    PWSTR  Buffer;//缓存指针
} UNICODE_STRING,*PUNICODE_STRING;

typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;//长度 18h
    HANDLE RootDirectory;//  00000000
    PUNICODE_STRING ObjectName;//指向对象名的指针
    ULONG Attributes;//对象属性00000040h
    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR,0
    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE,0
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

//函数指针变量类型
typedef DWORD  (__stdcall *ZWOS )( PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES);
typedef DWORD  (__stdcall *ZWMV )( HANDLE,HANDLE,PVOID,ULONG,ULONG,PLARGE_INTEGER,PSIZE_T,DWORD,ULONG,ULONG);
typedef DWORD  (__stdcall *ZWUMV )( HANDLE,PVOID);

BOOL WinNTHDSerialNumAsScsiRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )
{
    BOOL bInfoLoaded = FALSE;
   
    for( int iController = 0; iController < 4; ++ iController )
    {
        HANDLE hScsiDriveIOCTL = 0;
        char   szDriveName[256];
        
        //  Try to get a handle to PhysicalDrive IOCTL, report failure
        //  and exit if can't.
        sprintf( szDriveName, "\\\\.\\Scsi%d:", iController );

        //  Windows NT, Windows 2000, any rights should do
        hScsiDriveIOCTL = CreateFile( szDriveName,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING, 0, NULL);

        // if (hScsiDriveIOCTL == INVALID_HANDLE_VALUE)
        //    printf ("Unable to open SCSI controller %d, error code: 0x%lX\n",
        //            controller, GetLastError ());
        
        if( hScsiDriveIOCTL != INVALID_HANDLE_VALUE )
        {
            int iDrive = 0;
            for( iDrive = 0; iDrive < 16; ++ iDrive )
            {
                char szBuffer[sizeof( SRB_IO_CONTROL ) + SENDIDLENGTH] = { 0 };

                SRB_IO_CONTROL* p = ( SRB_IO_CONTROL* )szBuffer;
                SENDCMDINPARAMS* pin = ( SENDCMDINPARAMS* )( szBuffer + sizeof( SRB_IO_CONTROL ) );
                DWORD dwResult;

                p->HeaderLength = sizeof( SRB_IO_CONTROL );
                p->Timeout = 10000;
                p->Length = SENDIDLENGTH;
                p->ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;
                strncpy( ( char* )p->Signature, "SCSIDISK", 8 );

                pin->irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;
                pin->bDriveNumber = iDrive;
               
                if( DeviceIoControl( hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,
                    szBuffer,
                    sizeof( SRB_IO_CONTROL ) + sizeof( SENDCMDINPARAMS ) - 1,
                    szBuffer,
                    sizeof( SRB_IO_CONTROL ) + SENDIDLENGTH,
                    &dwResult, NULL ) )
                {
                    SENDCMDOUTPARAMS* pOut = ( SENDCMDOUTPARAMS* )( szBuffer + sizeof( SRB_IO_CONTROL ) );
                    IDSECTOR* pId = ( IDSECTOR* )( pOut->bBuffer );
                    if( pId->sModelNumber[0] )
                    {
                        if( * puSerialLen + 20U <= uMaxSerialLen )
                        {
                            // 序列号
                            CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 10, 20 );

                            // Cut off the trailing blanks
                            for( UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )
                            {}
                            * puSerialLen += i;

                            // 型号
                            CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )pId ) + 27, 40 );
                            // Cut off the trailing blanks
                            for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )
                            {}
                            * puSerialLen += i;

                            bInfoLoaded = TRUE;
                        }
                        else
                        {
                            ::CloseHandle( hScsiDriveIOCTL );
                            return bInfoLoaded;
                        }
                    }
                }
            }
            ::CloseHandle( hScsiDriveIOCTL );
        }
    }
    return bInfoLoaded;
}

BOOL DoIdentify( HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,
                 PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,
                 PDWORD lpcbBytesReturned )
{
    // Set up data structures for IDENTIFY command.
    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;
   
    // calc the drive number.
    pSCIP->irDriveRegs.bDriveHeadReg = 0xA0 | ( ( bDriveNum & 1 ) << 4 );

    // The command can either be IDE identify or ATAPI identify.
    pSCIP->irDriveRegs.bCommandReg = bIDCmd;
    pSCIP->bDriveNumber = bDriveNum;
    pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE;
   
    return DeviceIoControl( hPhysicalDriveIOCTL, DFP_RECEIVE_DRIVE_DATA,
        ( LPVOID ) pSCIP,
        sizeof( SENDCMDINPARAMS ) - 1,
        ( LPVOID ) pSCOP,
        sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1,
        lpcbBytesReturned, NULL );
}

BOOL WinNTHDSerialNumAsPhysicalRead( BYTE* dwSerial, UINT* puSerialLen, UINT uMaxSerialLen )
{
#define  DFP_GET_VERSION          0x00074080
    BOOL bInfoLoaded = FALSE;

    for( UINT uDrive = 0; uDrive < 4; ++ uDrive )
    {
        HANDLE hPhysicalDriveIOCTL = 0;

        //  Try to get a handle to PhysicalDrive IOCTL, report failure
        //  and exit if can't.
        char szDriveName [256];
        sprintf( szDriveName, "\\\\.\\PhysicalDrive%d", uDrive );

        //  Windows NT, Windows 2000, must have admin rights
        hPhysicalDriveIOCTL = CreateFile( szDriveName,
            GENERIC_READ | GENERIC_WRITE,
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING, 0, NULL);

        if( hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE )
        {
            GETVERSIONOUTPARAMS VersionParams = { 0 };
            DWORD               cbBytesReturned = 0;

            // Get the version, etc of PhysicalDrive IOCTL
            if( DeviceIoControl( hPhysicalDriveIOCTL, DFP_GET_VERSION,
                NULL,
                0,
                &VersionParams,
                sizeof( GETVERSIONOUTPARAMS ),
                &cbBytesReturned, NULL ) )
            {
                // If there is a IDE device at number "i" issue commands
                // to the device
                if( VersionParams.bIDEDeviceMap != 0 )
                {
                    BYTE             bIDCmd = 0;   // IDE or ATAPI IDENTIFY cmd
                    SENDCMDINPARAMS  scip = { 0 };

                    // Now, get the ID sector for all IDE devices in the system.
                    // If the device is ATAPI use the IDE_ATAPI_IDENTIFY command,
                    // otherwise use the IDE_ATA_IDENTIFY command
                    bIDCmd = ( VersionParams.bIDEDeviceMap >> uDrive & 0x10 ) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
                    BYTE IdOutCmd[sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1] = { 0 };

                    if( DoIdentify( hPhysicalDriveIOCTL,
                        &scip,
                        ( PSENDCMDOUTPARAMS )&IdOutCmd,
                        ( BYTE )bIDCmd,
                        ( BYTE )uDrive,
                        &cbBytesReturned ) )
                    {
                        if( * puSerialLen + 20U <= uMaxSerialLen )
                        {
                            CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )( ( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer ) ) + 10, 20 );  // 序列号

                            // Cut off the trailing blanks
                            for( UINT i = 20; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  {}
                            * puSerialLen += i;

                            CopyMemory( dwSerial + * puSerialLen, ( ( USHORT* )( ( ( PSENDCMDOUTPARAMS )IdOutCmd )->bBuffer ) ) + 27, 40 ); // 型号

                            // Cut off the trailing blanks
                            for( i = 40; i != 0U && ' ' == dwSerial[* puSerialLen + i - 1]; -- i )  {}
                            * puSerialLen += i;

                            bInfoLoaded = TRUE;
                        }
                        else
                        {
                            ::CloseHandle( hPhysicalDriveIOCTL );
                            return bInfoLoaded;
                        }
                    }
                }
            }
            CloseHandle( hPhysicalDriveIOCTL );
        }
    }
    return bInfoLoaded;
}

UINT FindAwardBios( BYTE** ppBiosAddr )
{
    BYTE* pBiosAddr = * ppBiosAddr + 0xEC71;

    BYTE szBiosData[128];
    CopyMemory( szBiosData, pBiosAddr, 127 );
    szBiosData[127] = 0;
   
    int iLen = lstrlen( ( char* )szBiosData );
    if( iLen > 0 && iLen < 128 )
    {
        //AWard:         07/08/2002-i845G-ITE8712-JF69VD0CC-00
        //Phoenix-Award: 03/12/2002-sis645-p4s333
        if( szBiosData[2] == '/' && szBiosData[5] == '/' )
        {
            BYTE* p = szBiosData;
            while( * p )
            {
                if( * p < ' ' || * p >= 127 )
                {
                    break;
                }
                ++ p;
            }
            if( * p == 0 )
            {
                * ppBiosAddr = pBiosAddr;
                return ( UINT )iLen;
            }
        }
    }
    return 0;
}

UINT FindAmiBios( BYTE** ppBiosAddr )
{
    BYTE* pBiosAddr = * ppBiosAddr + 0xF478;
   
    BYTE szBiosData[128];
    CopyMemory( szBiosData, pBiosAddr, 127 );
    szBiosData[127] = 0;
   
    int iLen = lstrlen( ( char* )szBiosData );
    if( iLen > 0 && iLen < 128 )
    {
        // Example: "AMI: 51-2300-000000-00101111-030199-"
        if( szBiosData[2] == '-' && szBiosData[7] == '-' )
        {
            BYTE* p = szBiosData;
            while( * p )
            {
                if( * p < ' ' || * p >= 127 )
                {
                    break;
                }
                ++ p;
            }
            if( * p == 0 )
            {
                * ppBiosAddr = pBiosAddr;
                return ( UINT )iLen;
            }
        }
    }
    return 0;
}

UINT FindPhoenixBios( BYTE** ppBiosAddr )
{
    UINT uOffset[3] = { 0x6577, 0x7196, 0x7550 };
    for( UINT i = 0; i < 3; ++ i )
    {
        BYTE* pBiosAddr = * ppBiosAddr + uOffset[i];

        BYTE szBiosData[128];
        CopyMemory( szBiosData, pBiosAddr, 127 );
        szBiosData[127] = 0;

        int iLen = lstrlen( ( char* )szBiosData );
        if( iLen > 0 && iLen < 128 )
        {
            // Example: Phoenix "NITELT0.86B.0044.P11.9910111055"
            if( szBiosData[7] == '.' && szBiosData[11] == '.' )
            {
                BYTE* p = szBiosData;
                while( * p )
                {
                    if( * p < ' ' || * p >= 127 )
                    {
                        break;
                    }
                    ++ p;
                }
                if( * p == 0 )
                {
                    * ppBiosAddr = pBiosAddr;
                    return ( UINT )iLen;
                }
            }
        }
    }
    return 0;
}

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

// 网卡 MAC 地址,注意: MAC 地址是可以在注册表中修改的
BOOL GetMAC()
{
    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;
    }

        return uErrorCode != 0U ? FALSE : TRUE;
}

// 硬盘序列号,注意:有的硬盘没有序列号
BOOL GetHdSn()
{
    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 ) )
        {
            return WinNTHDSerialNumAsScsiRead( szSystemInfo, &uSystemInfoLen, 1024 );
        }
                else
                        return TRUE;
    }
}

// CPU ID
BOOL GetCpuId()
{
    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;

                return TRUE;
    }
        else
                return FALSE;
}

// BIOS 编号,支持 AMI, AWARD, PHOENIX
BOOL GetBiosSn()
{
        BOOL ret = FALSE;

    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;

                        ret = TRUE;
        }

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

        return ret;
}

int main(int argc, char ** argv)
{
        BOOL ret;
        ret = GetMAC();
        printf("\nGetMAC returned %d", ret);
        ret = GetHdSn();
        printf("\nGetHdSn returned %d", ret);
        ret = GetCpuId();
        printf("\nGetCpuId returned %d", ret);
        ret = GetBiosSn();
        printf("\nGetBiosSn returned %d", ret);

        printf("\nChar:\n");
        for(UINT i = 0; i < uSystemInfoLen; i++)
                printf("%c", szSystemInfo[i], szSystemInfo[i]);

        printf("\nHex:\n");
        for(UINT i = 0; i < uSystemInfoLen; i++)
                printf("%x ", szSystemInfo[i], szSystemInfo[i]);

        return 0;
}
// 完毕, 系统特征码已取得。
2008-9-7 09:58
0
雪    币: 227
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
回复楼上  :

上面那段代码    最后2个 printf   有定义重复  i

然后头文件里面要加一句#pragma   comment(lib,   "Iphlpapi")

在我电脑上面bios 无法返回值  return0
2008-9-7 13:39
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
to KuNgBiM  前辈:

    该代码在VISTA下取不到相关硬件信息,如何解决。
2008-9-7 14:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
期待楼主优化下代码,现在的代码问题多多
2008-9-7 17:39
0
雪    币: 11155
活跃值: (3110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
期待KuNgBiM能搞完善点的,最好是DLL
我小菜一个只会E,手上有个小软件正好需要一个。。。
谢了!
2008-11-2 16:28
0
雪    币: 107
活跃值: (36)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
10
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

这个获取CPUID的方法就不对啊,“CPU的序列号用一个96bit的串表示,格式是连续的6个WORD值:XXXX-XXXX-XXXX-XXX-XXXX-XXXX。    获得序列号需要两个步骤,首先用eax = 1做参数,返回的eax中存储序列号的高两个WORD。用eax = 3做参数,返回ecx和edx按从低位到高位的顺序存储前4个WORD。”
http://www.weste.net/2006/6-12/11380593215-2.html
http://www.codeguru.com/cpp/w-p/system/hardwareinformation/article.php/c9087__2/
不过还是要谢谢LZ的,呵呵
2008-11-24 11:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
gry
11
谢谢LZ分享
2008-11-24 12:03
0
雪    币: 411
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢楼主和KuNgBiM的分享。
2008-11-25 11:28
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
谢谢!!!!!!!
2008-11-26 01:28
0
雪    币: 184
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
Vista 下 用户模式 ZwOpenSection 无法打开 内存对象.
如果想获取而不修改的BIOS数据的可以使用 WMI 的 Win32_BIOS 对象
另:
Vista 用户模式下增加了两个新的函数函数可以读取 BIOS 具体函数名忘了.
2008-12-1 02:42
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
好强!! 谢谢分享
2008-12-2 14:56
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
真强
努力中
2008-12-2 15:20
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
17
除了CPUID
其他的都可以通过各种方法改掉
2008-12-2 19:43
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
稳定性 如何 ?
2008-12-3 12:56
0
雪    币: 200
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
感谢楼主分享
2009-4-29 21:43
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
20
for asm..
2009-4-29 22:53
0
雪    币: 112
活跃值: (51)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
谢谢分享。。好东西
2009-4-30 22:45
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
22
tag : Get HardwareInfo
2009-5-1 16:46
0
雪    币: 212
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
还行
不过在2003以后版本中包括VISTA, IOCTL_SCSI_XXX, 无效.
2009-5-1 22:40
0
雪    币: 152
活跃值: (106)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
24
相当无聊的代码。
2009-5-1 23:22
0
雪    币: 152
活跃值: (106)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
25
三个字,是垃圾。发出来的东西根本就不是特征,关键是你没明白特征的定义。可以伪造的东西,都是垃圾。所谓的特征是不可以伪造的唯一。
2009-5-1 23:28
0
游客
登录 | 注册 方可回帖
返回
//