分享

读取硬盘的ID

 心不留意外尘 2016-05-30
  http://blog.csdn.net/educast/article/details/8364498
2012

Win32 API函数(GetVolumeInformation),因为他得到的是硬盘逻辑分区的那个序列号,格式化以后就变了。很多加密软件都用到硬盘这个唯一的硬件序列号。

C/C++里面用宏汇编就可以得到,查询它的硬件中断!!

PS:好像这样不能读SATA硬盘的序列号,不知道为什么?

  1. // Windows9X/ME系统下读取硬盘序列号  
  2. void _stdcall CGetHDSerial::Win9xReadHDSerial(WORD * buffer)  
  3. {      
  4.     int i;          
  5.     for(i=0;i<256;i++)  
  6.         buffer[i]=0;  
  7.     _asm  
  8.     {  
  9.           push eax          
  10.         //获取修改的中断的中断描述符(中断门)地址  
  11.         sidt m_IDTR      
  12.         mov eax,dword ptr [m_IDTR+02h]          
  13.         add eax,3*08h+04h  
  14.         cli  
  15.         //保存原先的中断入口地址  
  16.         push ecx  
  17.         mov ecx,dword ptr [eax]  
  18.         mov cx,word ptr [eax-04h]  
  19.         mov dword ptr m_OldInterruptAddress,ecx  
  20.         pop ecx  
  21.         //设置修改的中断入口地址为新的中断处理程序入口地址  
  22.         push ebx  
  23.         lea ebx,InterruptProcess      
  24.         mov word ptr [eax-04h],bx  
  25.         shr ebx,10h  
  26.         mov word ptr [eax+02h],bx  
  27.         pop ebx  
  28.         //执行中断,转到Ring 0(类似CIH病毒原理)  
  29.         int 3h  
  30.         //恢复原先的中断入口地址  
  31.         push ecx  
  32.         mov ecx,dword ptr m_OldInterruptAddress  
  33.         mov word ptr [eax-04h],cx  
  34.         shr ecx,10h  
  35.         mov word ptr [eax+02h],cx  
  36.         pop ecx  
  37.         sti  
  38.         pop eax  
  39.     }  
  40.     for(i=0;i<256;i++)          
  41.         buffer[i]=m_serial[i];  
  42. }  
  43.   
  44. // Windows 9x/ME系统下,将字类型(WORD)的硬盘信息转换为字符类型(char)  
  45. char * CGetHDSerial::WORDToChar (WORD diskdata [256], int firstIndex, int lastIndex)  
  46. {  
  47.    static char string [1024];  
  48.    int index = 0;  
  49.    int position = 0;  
  50.   
  51.    // 按照高字节在前,低字节在后的顺序将字数组diskdata 中内容存入到字符串string中  
  52.    for (index = firstIndex; index <= lastIndex; index++)  
  53.    {  
  54.       // 存入字中的高字节  
  55.       string [position] = (char) (diskdata [index] / 256);  
  56.       position++;  
  57.       // 存入字中的低字节  
  58.       string [position] = (char) (diskdata [index] % 256);  
  59.       position++;  
  60.    }  
  61.    //  添加字符串结束标志  
  62.    string [position] = '';  
  63.   
  64.    //  删除字符串中空格  
  65.    for (index = position - 1; index > 0 && ' ' == string [index]; index--)  
  66.       string [index] = '';  
  67.   
  68.    return string;  
  69. }  
  70.   
  71. // Windows NT/2000/XP系统下,将双字类型(DWORD)的硬盘信息转换为字符类型(char)  
  72. char* CGetHDSerial::DWORDToChar (DWORD diskdata [256], int firstIndex, int lastIndex)  
  73. {  
  74.    static char string [1024];  
  75.    int index = 0;  
  76.    int position = 0;  
  77.   
  78.    // 按照高字节在前,低字节在后的顺序将双字中的低字存入到字符串string中  
  79.    for (index = firstIndex; index <= lastIndex; index++)  
  80.    {  
  81.       // 存入低字中的高字节  
  82.       string [position] = (char) (diskdata [index] / 256);  
  83.       position++;  
  84.       // 存入低字中的低字节  
  85.       string [position] = (char) (diskdata [index] % 256);  
  86.       position++;  
  87.    }  
  88.    //  添加字符串结束标志  
  89.    string [position] = '';  
  90.   
  91.    //  删除字符串中空格  
  92.    for (index = position - 1; index > 0 && ' ' == string [index]; index--)  
  93.       string [index] = '';  
  94.   
  95.    return string;  
  96. }  
  97.   
  98. // Windows NT/2000/XP下读取IDE硬盘序列号  
  99. BOOL CGetHDSerial::WinNTReadIDEHDSerial(DWORD * buffer)  
  100. {  
  101.    BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];  
  102.    BOOL bFlag = FALSE;  
  103.    int  drive = 0;  
  104.    char driveName [256];  
  105.    HANDLE hPhysicalDriveIOCTL = 0;      
  106.         
  107.    sprintf (driveName, "\\.\PhysicalDrive%d", drive);  
  108.    //  Windows NT/2000/XP下创建文件需要管理员权限  
  109.    hPhysicalDriveIOCTL = CreateFile (driveName,  
  110.                             GENERIC_READ | GENERIC_WRITE,  
  111.                             FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,  
  112.                             OPEN_EXISTING, 0, NULL);  
  113.   
  114.    if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE)  
  115.    {  
  116.        GETVERSIONOUTPARAMS VersionParams;  
  117.        DWORD               cbBytesReturned = 0;  
  118.   
  119.        // 得到驱动器的IO控制器版本  
  120.        memset ((void*) &VersionParams, 0, sizeof(VersionParams));  
  121.        if(DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_VERSION,  
  122.                                NULL, 0, &VersionParams,  
  123.                                sizeof(VersionParams),  
  124.                                &cbBytesReturned, NULL) )  
  125.        {          
  126.           if (VersionParams.bIDEDeviceMap > 0)  
  127.           {  
  128.               BYTE             bIDCmd = 0;   // IDE或者ATAPI识别命令  
  129.               SENDCMDINPARAMS  scip;  
  130.   
  131.               // 如果驱动器是光驱,采用命令IDE_ATAPI_IDENTIFY, command,  
  132.               // 否则采用命令IDE_ATA_IDENTIFY读取驱动器信息  
  133.               bIDCmd = (VersionParams.bIDEDeviceMap >> drive & 0x10)?  
  134.                       IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;  
  135.   
  136.               memset (&scip, 0, sizeof(scip));  
  137.               memset (IdOutCmd, 0, sizeof(IdOutCmd));  
  138.               // 获取驱动器信息  
  139.               if (WinNTGetIDEHDInfo (hPhysicalDriveIOCTL,  
  140.                                       &scip,  
  141.                                       (PSENDCMDOUTPARAMS)&IdOutCmd,  
  142.                                       (BYTE) bIDCmd,  
  143.                                       (BYTE) drive,  
  144.                                       &cbBytesReturned))  
  145.               {  
  146.                   int m = 0;  
  147.                   USHORT *pIdSector = (USHORT *)  
  148.                              ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;  
  149.   
  150.                   for (m = 0; m < 256; m++)  
  151.                        buffer[m] = pIdSector [m];  
  152.                   bFlag = TRUE;  // 读取硬盘信息成功  
  153.               }  
  154.           }  
  155.        }  
  156.        CloseHandle (hPhysicalDriveIOCTL);  // 关闭句柄  
  157.    }  
  158.    return bFlag;  
  159. }  
  160.   
  161. // WindowsNT/2000/XP系统下读取SCSI硬盘序列号  
  162. BOOL CGetHDSerial::WinNTReadSCSIHDSerial (DWORD * buffer)  
  163. {      
  164.       buffer[0]='n';  
  165.       int controller = 0;  
  166.       HANDLE hScsiDriveIOCTL = 0;  
  167.       char   driveName [256];  
  168.       sprintf (driveName, "\\.\Scsi%d:", controller);  
  169.      //  Windows NT/2000/XP下任何权限都可以进行  
  170.       hScsiDriveIOCTL = CreateFile (driveName,  
  171.                                GENERIC_READ | GENERIC_WRITE,  
  172.                                FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,  
  173.                                OPEN_EXISTING, 0, NULL);  
  174.   
  175.       if (hScsiDriveIOCTL != INVALID_HANDLE_VALUE)  
  176.       {  
  177.          int drive = 0;  
  178.          DWORD dummy;  
  179.          for (drive = 0; drive < 2; drive++)  
  180.          {  
  181.             char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH];  
  182.             SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer;  
  183.             SENDCMDINPARAMS *pin =  
  184.                    (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));            
  185.             // 准备参数  
  186.             memset (buffer, 0, sizeof (buffer));  
  187.             p -> HeaderLength = sizeof (SRB_IO_CONTROL);  
  188.             p -> Timeout = 10000;  
  189.             p -> Length = SENDIDLENGTH;  
  190.             p -> ControlCode = IOCTL_SCSI_MINIPORT_IDENTIFY;  
  191.             strncpy ((char *) p -> Signature, "SCSIDISK", 8);    
  192.             pin -> irDriveRegs.bCommandReg = IDE_ATA_IDENTIFY;  
  193.             pin -> bDriveNumber = drive;  
  194.             // 得到SCSI硬盘信息  
  195.             if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT,  
  196.                                  buffer,  
  197.                                  sizeof (SRB_IO_CONTROL) +  
  198.                                          sizeof (SENDCMDINPARAMS) - 1,  
  199.                                  buffer,  
  200.                                  sizeof (SRB_IO_CONTROL) + SENDIDLENGTH,  
  201.                                  &dummy, NULL))  
  202.             {  
  203.                SENDCMDOUTPARAMS *pOut =  
  204.                     (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL));  
  205.                IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer);  
  206.                if (pId -> sModelNumber [0])  
  207.                {  
  208.                   int n = 0;  
  209.                   USHORT *pIdSector = (USHORT *) pId;  
  210.             
  211.                   for (n = 0; n < 256; n++)  
  212.                       buffer[n] =pIdSector [n];  
  213.                   return TRUE;  // 读取成功                                
  214.                }  
  215.             }  
  216.          }  
  217.          CloseHandle (hScsiDriveIOCTL);  // 关闭句柄  
  218.       }  
  219.    return FALSE;   // 读取失败  
  220. }  
  221.   
  222. // Windows NT/2000/XP下读取IDE设备信息  
  223. BOOL CGetHDSerial::WinNTGetIDEHDInfo (HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP,  
  224.                  PSENDCMDOUTPARAMS pSCOP, BYTE bIDCmd, BYTE bDriveNum,  
  225.                  PDWORD lpcbBytesReturned)  
  226. {  
  227.    // 为读取设备信息准备参数  
  228.    pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;  
  229.    pSCIP -> irDriveRegs.bFeaturesReg = 0;  
  230.    pSCIP -> irDriveRegs.bSectorCountReg = 1;  
  231.    pSCIP -> irDriveRegs.bSectorNumberReg = 1;  
  232.    pSCIP -> irDriveRegs.bCylLowReg = 0;  
  233.    pSCIP -> irDriveRegs.bCylHighReg = 0;  
  234.   
  235.    // 计算驱动器位置  
  236.    pSCIP -> irDriveRegs.bDriveHeadReg = 0xA0 | ((bDriveNum & 1) << 4);  
  237.   
  238.    // 设置读取命令  
  239.    pSCIP -> irDriveRegs.bCommandReg = bIDCmd;  
  240.    pSCIP -> bDriveNumber = bDriveNum;  
  241.    pSCIP -> cBufferSize = IDENTIFY_BUFFER_SIZE;  
  242.     
  243.    // 读取驱动器信息  
  244.    return ( DeviceIoControl (hPhysicalDriveIOCTL, IOCTL_GET_DRIVE_INFO,  
  245.                (LPVOID) pSCIP,  
  246.                sizeof(SENDCMDINPARAMS) - 1,  
  247.                (LPVOID) pSCOP,  
  248.                sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1,  
  249.                lpcbBytesReturned, NULL) );  
  250. }  


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多