www.pudn.com > 取硬盘物理序列号.zip > PORTDLL.CPP
#include//#include //#include //#include #include //#include #define SENDIDLENGTH sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE #define IDENTIFY_BUFFER_SIZE 512 #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 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; WORD serial[256]; DWORD OldInterruptAddress; DWORDLONG IDTR; void _stdcall ReadIdeSerialNumber(); static unsigned int WaitHardDiskIde() { BYTE xx; Waiting: __asm{ mov dx, 0x1f7 in al, dx cmp al, 0x80 jb Endwaiting jmp Waiting } Endwaiting: __asm{ mov xx, al } return xx; } void __declspec( naked ) InterruptProcess(void)//中断服务程序 { int xx; int i; WORD temp; //保存寄存器值 __asm { push eax push ebx push ecx push edx push esi } WaitHardDiskIde();//等待硬盘空闲状态 __asm{ mov dx, 0x1f6 mov al, 0xa0 out dx, al } xx = WaitHardDiskIde(); //若直接在Ring3级执行等待命令,会进入死循环 if ((xx&0x50)!=0x50) { __asm{ pop esi pop edx pop ecx pop ebx pop eax iretd } } __asm{ mov dx, 0x1f6 //命令端口1f6,选择驱动器0 mov al, 0xa0 out dx, al inc dx mov al, 0xec out dx, al //发送读驱动器参数命令 } xx = WaitHardDiskIde(); if ((xx&0x58)!=0x58) { __asm{ pop esi pop edx pop ecx pop ebx pop eax iretd } } //读取硬盘控制器的全部信息 for (i=0;i<256;i++) { __asm{ mov dx, 0x1f0 in ax, dx mov temp, ax } serial[i] = temp; } __asm{ pop esi pop edx pop ecx pop ebx pop eax iretd } //_asm iretd } int Win9xHDSerialNumRead(WORD * buffer) { int i; for(i=0;i<256;i++) buffer[i]=0; ReadIdeSerialNumber(); for(i=0;i<256;i++) buffer[i]=serial[i]; return 1; } void _stdcall ReadIdeSerialNumber() { _asm { push eax //获取修改的中断的中断描述符(中断门)地址 sidt IDTR mov eax,dword ptr [IDTR+02h] add eax,3*08h+04h cli //保存原先的中断入口地址 push ecx mov ecx,dword ptr [eax] mov cx,word ptr [eax-04h] mov dword ptr OldInterruptAddress,ecx pop ecx //设置修改的中断入口地址为新的中断处理程序入口地址 push ebx lea ebx,InterruptProcess mov word ptr [eax-04h],bx shr ebx,10h mov word ptr [eax+02h],bx pop ebx //执行中断,转到Ring 0(类似CIH病毒原理) int 3h //恢复原先的中断入口地址 push ecx mov ecx,dword ptr OldInterruptAddress mov word ptr [eax-04h],cx shr ecx,10h mov word ptr [eax+02h],cx pop ecx sti pop eax } } char *ConvertToString (WORD diskdata [256], int firstIndex, int lastIndex) { static char string [1024]; int index = 0; int position = 0; // each integer has two characters stored in it backwards for (index = firstIndex; index <= lastIndex; index++) { // get high byte for 1st character string [position] = (char) (diskdata [index] / 256); position++; // get low byte for 2nd character string [position] = (char) (diskdata [index] % 256); position++; } // end the string string [position] = '\0'; // cut off the trailing blanks for (index = position - 1; index > 0 && ' ' == string [index]; index--) string [index] = '\0'; return string; } char *ConvertToString2 (DWORD diskdata [256], int firstIndex, int lastIndex) { static char string [1024]; int index = 0; int position = 0; // each integer has two characters stored in it backwards for (index = firstIndex; index <= lastIndex; index++) { // get high byte for 1st character string [position] = (char) (diskdata [index] / 256); position++; // get low byte for 2nd character string [position] = (char) (diskdata [index] % 256); position++; } // end the string string [position] = '\0'; // cut off the trailing blanks for (index = position - 1; index > 0 && ' ' == string [index]; index--) string [index] = '\0'; return string; } int WinNTHDSerialNumAsScsiRead (DWORD * buffer) { buffer[0]='\n'; int controller = 0; // for (controller = 0; controller < 2; controller++) { HANDLE hScsiDriveIOCTL = 0; char driveName [256]; // Try to get a handle to PhysicalDrive IOCTL, report failure // and exit if can't. sprintf (driveName, "\\\\.\\Scsi%d:", controller); // driveName="\\\\.\\Scsi0"; // Windows NT, Windows 2000, any rights should do hScsiDriveIOCTL = CreateFile (driveName, 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 drive = 0; for (drive = 0; drive < 2; drive++) { char buffer [sizeof (SRB_IO_CONTROL) + SENDIDLENGTH]; SRB_IO_CONTROL *p = (SRB_IO_CONTROL *) buffer; SENDCMDINPARAMS *pin = (SENDCMDINPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); DWORD dummy; memset (buffer, 0, sizeof (buffer)); 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 = drive; if (DeviceIoControl (hScsiDriveIOCTL, IOCTL_SCSI_MINIPORT, buffer, sizeof (SRB_IO_CONTROL) + sizeof (SENDCMDINPARAMS) - 1, buffer, sizeof (SRB_IO_CONTROL) + SENDIDLENGTH, &dummy, NULL)) { SENDCMDOUTPARAMS *pOut = (SENDCMDOUTPARAMS *) (buffer + sizeof (SRB_IO_CONTROL)); IDSECTOR *pId = (IDSECTOR *) (pOut -> bBuffer); if (pId -> sModelNumber [0]) { int ijk = 0; USHORT *pIdSector = (USHORT *) pId; for (ijk = 0; ijk < 256; ijk++) buffer[ijk] =pIdSector [ijk]; // PrintIdeInfo (controller * 2 + drive, diskdata); return 1; } } } CloseHandle (hScsiDriveIOCTL); } } return -1; } 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; // Compute 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) ); } int WinNTHDSerialNumAsPhysicalRead (DWORD * buffer) { #define DFP_GET_VERSION 0x00074080 BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; int done = FALSE; int drive = 0; // for (drive = 0; drive < MAX_IDE_DRIVES; drive++) { HANDLE hPhysicalDriveIOCTL = 0; // Try to get a handle to PhysicalDrive IOCTL, report failure // and exit if can't. char driveName [256]; sprintf (driveName, "\\\\.\\PhysicalDrive%d", drive); // Windows NT, Windows 2000, must have admin rights hPhysicalDriveIOCTL = CreateFile (driveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); // if (hPhysicalDriveIOCTL == INVALID_HANDLE_VALUE) // printf ("Unable to open physical drive %d, error code: 0x%lX\n", // drive, GetLastError ()); if (hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE) { GETVERSIONOUTPARAMS VersionParams; DWORD cbBytesReturned = 0; // Get the version, etc of PhysicalDrive IOCTL memset ((void*) &VersionParams, 0, sizeof(VersionParams)); if ( ! DeviceIoControl (hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &VersionParams, sizeof(VersionParams), &cbBytesReturned, NULL) ) { // printf ("DFP_GET_VERSION failed for drive %d\n", i); // continue; } // 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; //SENDCMDOUTPARAMS OutCmd; // 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 >> drive & 0x10) ? \ IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; memset (&scip, 0, sizeof(scip)); memset (IdOutCmd, 0, sizeof(IdOutCmd)); if ( DoIDENTIFY (hPhysicalDriveIOCTL, &scip, (PSENDCMDOUTPARAMS)&IdOutCmd, (BYTE) bIDCmd, (BYTE) drive, &cbBytesReturned)) { //DWORD diskdata [256]; int ijk = 0; USHORT *pIdSector = (USHORT *) ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer; for (ijk = 0; ijk < 256; ijk++) buffer[ijk] = pIdSector [ijk]; // PrintIdeInfo (drive, diskdata); done = TRUE; } } CloseHandle (hPhysicalDriveIOCTL); } } return done; } LPCWSTR FAR HDSerialNumRead() { char buffer[256]; buffer[0]='\n'; OSVERSIONINFO OSVersionInfo; OSVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx( &OSVersionInfo); if (OSVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) { WORD m_wSeri[256]; Win9xHDSerialNumRead(m_wSeri); strcpy (buffer, ConvertToString (m_wSeri, 10, 19)); } else{ DWORD m_wStr[256]; if ( ! WinNTHDSerialNumAsPhysicalRead(m_wStr)) WinNTHDSerialNumAsScsiRead; strcpy (buffer, ConvertToString2 (m_wStr, 10, 19)); } ; return LPCWSTR(LPCSTR(buffer)); } int WEP(int nParam) { return 1; }