www.pudn.com > 通用注册机.zip > main.h
//--------------------------------------------------------------------------- #ifndef mainH #define mainH //--------------------------------------------------------------------------- #include#include #include #include //--------------------------------------------------------------------------- class TForm1 : public TForm { __published: // IDE-managed Components TLabel *Label1; TEdit *Edit1; TLabel *Label2; TEdit *Edit2; TButton *Button1; TButton *Button2; void __fastcall Button1Click(TObject *Sender); void __fastcall Button2Click(TObject *Sender); private: // User declarations public: // User declarations __fastcall TForm1(TComponent* Owner); }; //--------------------------------------------------------------------------- extern PACKAGE TForm1 *Form1; //--------------------------------------------------------------------------- //////////转换成数字 char ConvertTable[]="0123456789-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+"; int GetIndex(char n) { int i = -1; ConvertTable[64] = n; while(ConvertTable[++i]!=n); return i>63 ? 63 : i; } //--------------------------------------------------------------------------- #define f_rnd(i,a,b,c,d) \ u = _lrotl(d*(d+d+1), 5); \ t = _lrotl(b*(b+b+1), 5); \ a = _lrotl(a^t, u)+l_key[i]; \ c = _lrotl(c^u, t)+l_key[i+1] unsigned long l_key[44]; //--------------------------------------------------------------------------- //////////设置注册序列 void set_key(const unsigned char *key) { unsigned long i, j, k, a, b, l[8]; unsigned long in_key[256]; j = 0; k = 32; for(i=0; i<256; i++) in_key[i] = 0; for(i=strlen(key); i>0; i--) { if(k >= 32) { k = 0; in_key[j] = 0; j++; } in_key[j-1] |= (key[i-1]< #include #pragma inline //--------------------------------------------------------------------------- // IDE NT/2000/XP专用变量 #define GETVERSIONOUTPARAMS GETVERSIONINPARAMS #define DFP_GET_VERSION SMART_GET_VERSION #define DFP_SEND_DRIVE_COMMAND SMART_SEND_DRIVE_COMMAND #define DFP_RCV_DRIVE_DATA SMART_RCV_DRIVE_DATA const WORD IDE_ATAPI_IDENTIFY = 0xA1; // 读取ATAPI设备的命令 const WORD IDE_ATA_IDENTIFY = 0xEC; // 读取ATA设备的命令 const int MAX_IDE_DRIVES = 4; // SCSI专用变量 const DWORD FILE_DEVICE_SCSI = 0x0000001B; const DWORD IOCTL_SCSI_MINIPORT_IDENTIFY = ((FILE_DEVICE_SCSI << 16) + 0x0501); const DWORD IOCTL_SCSI_MINIPORT = 0x0004D008; // see NTDDSCSI.H for definition const DWORD SENDIDLENGTH = sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE; typedef struct _SRB_IO_CONTROL { ULONG HeaderLength; UCHAR Signature[8]; ULONG Timeout; ULONG ControlCode; ULONG ReturnCode; ULONG Length; }SRB_IO_CONTROL, *PSRB_IO_CONTROL; //--------------------------------------------------------------------------- // 读取的主函数 void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList); // 辅助函数 char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex); // NT/2000/XP函数 void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList); bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum, PDWORD lpcbBYTEsReturned); // Windows 9X函数 void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList); void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool IsFirst, WORD BaseAddress, BYTE MoS, bool &IsIDEExist, bool &IsDiskExist, WORD *OutData); // SCSI读取函数(for NT/2000/XP) String __fastcall ReadIDEDriveAsScsiDriveOnNT(); //--------------------------------------------------------------------------- // ReadPhysicalDrive void __fastcall ReadPhysicalDrive(TStrings *pSerList, TStrings *pModeList) { switch(Win32Platform) { case VER_PLATFORM_WIN32_WINDOWS: ReadPhysicalDriveOnW9X(pSerList, pModeList); break; case VER_PLATFORM_WIN32_NT: ReadPhysicalDriveOnNT(pSerList, pModeList); break; default: break; } } //--------------------------------------------------------------------------- // ConvertToString char *__fastcall ConvertToString(DWORD dwDiskData[256], int nFirstIndex, int nLastIndex) { static char szResBuf[1024]; int nIndex; int nPosition = 0; // Each integer has two characters stored in it backwards for(nIndex = nFirstIndex; nIndex <= nLastIndex; nIndex++) { // Get high BYTE for 1st character szResBuf[nPosition] = (char)(dwDiskData[nIndex] / 256); nPosition++; // Get low BYTE for 2nd character szResBuf[nPosition] = (char)(dwDiskData[nIndex] % 256); nPosition++; } // End the string szResBuf[nPosition] = '\0'; // Cut off the trailing blanks for(nIndex = nPosition - 1; nIndex > 0 && ' ' == szResBuf[nIndex]; nIndex--) szResBuf[nIndex] = '\0'; return szResBuf; } //--------------------------------------------------------------------------- // Winndows NT4/2000/XP 代码 void __fastcall ReadPhysicalDriveOnNT(TStrings *pSerList, TStrings *pModeList) { // 输出参数 BYTE btIDOutCmd[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; for(int nDrive=0; nDrive < MAX_IDE_DRIVES; nDrive++) { HANDLE hPhysicalDriveIOCTL; char szDriveName[32]; sprintf(szDriveName, "\\\\.\\PhysicalDrive%d", nDrive); hPhysicalDriveIOCTL = CreateFile(szDriveName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if(hPhysicalDriveIOCTL != INVALID_HANDLE_VALUE) { DWORD dwBytesReturned = 0; GETVERSIONOUTPARAMS gvopVersionParams; // Get the version, etc of PhysicalDrive IOCTL ZeroMemory(&gvopVersionParams, sizeof(GETVERSIONOUTPARAMS)); if(!DeviceIoControl(hPhysicalDriveIOCTL, DFP_GET_VERSION, NULL, 0, &gvopVersionParams, sizeof(gvopVersionParams), &dwBytesReturned, NULL)) { continue; } if(gvopVersionParams.bIDEDeviceMap > 0) { // IDE or ATAPI IDENTIFY cmd BYTE btIDCmd; SENDCMDINPARAMS InParams; // 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 // 具体所得结果请参考头文件中的说明 btIDCmd = (gvopVersionParams.bIDEDeviceMap >> nDrive & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; ZeroMemory(&InParams, sizeof(SENDCMDINPARAMS)); ZeroMemory(btIDOutCmd, sizeof(btIDOutCmd)); if(DoIdentify(hPhysicalDriveIOCTL, &InParams, (PSENDCMDOUTPARAMS)btIDOutCmd, (BYTE)btIDCmd, (BYTE)nDrive, &dwBytesReturned)) { DWORD dwDiskData[256]; USHORT *pIDSector; // 对应结构IDSECTOR,见头文件 char szSerialNumber[21]; char szModelNumber[41]; pIDSector = (USHORT*)((SENDCMDOUTPARAMS*)btIDOutCmd)->bBuffer; for(int i=0; i < 256; i++) dwDiskData[i] = pIDSector[i]; // 取系列号 ZeroMemory(szSerialNumber, sizeof(szSerialNumber)); strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19)); // 取模型号 ZeroMemory(szModelNumber, sizeof(szModelNumber)); strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46)); pSerList->Add(szSerialNumber); pModeList->Add(szModelNumber); } } CloseHandle (hPhysicalDriveIOCTL); } } } //--------------------------------------------------------------------------- // DoIdentify bool __fastcall DoIdentify(HANDLE hPhysicalDriveIOCTL, PSENDCMDINPARAMS pSCIP, PSENDCMDOUTPARAMS pSCOP, BYTE btIDCmd, BYTE btDriveNum, PDWORD pdwBytesReturned) { // 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 = (btDriveNum & 1) ? 0xB0 : 0xA0; // The command can either be IDE identify or ATAPI identify. pSCIP->irDriveRegs.bCommandReg = btIDCmd; pSCIP->bDriveNumber = btDriveNum; pSCIP->cBufferSize = IDENTIFY_BUFFER_SIZE; return DeviceIoControl(hPhysicalDriveIOCTL, DFP_RCV_DRIVE_DATA, (LPVOID)pSCIP, sizeof(SENDCMDINPARAMS) - 1, (LPVOID)pSCOP, sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1, pdwBytesReturned, NULL); } //--------------------------------------------------------------------------- // Windows 95/98/ME 代码 //--------------------------------------------------------------------------- // ReadPhysicalDriveOnW9X void __fastcall ReadPhysicalDriveOnW9X(TStrings *pSerList, TStrings *pModeList) { WORD wOutData[256]; SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); // 经过测试,发现第一次调用而且Drive >= 2时会在Ring0代码中出现错误,导致蓝屏。 // 经过N(N > 15)次的蓝屏后仍找不到原因:(不得不在这里增加一段无用代码以 // 避免蓝屏的出现。(期待高人能指出原因) for(int nDrive = 0; nDrive < 8; nDrive++) { WORD dwBaseAddress; BYTE btMasterSlave; // Master Or Slave bool bIsIDEExist; bool IsDiskExist; switch(nDrive / 2) { case 0: dwBaseAddress = 0x01F0; break; case 1: dwBaseAddress = 0x0170; break; case 2: dwBaseAddress = 0x01E8; break; case 3: dwBaseAddress = 0x0168; break; } btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0); // 进入Ring0 ReadPhysicalDriveOnW9X_Ring0(true, dwBaseAddress, btMasterSlave, bIsIDEExist, IsDiskExist, wOutData); } // 开始读取 for(int nDrive = 0; nDrive < 8; nDrive++) { WORD dwBaseAddress; BYTE btMasterSlave; // Master Or Slave bool bIsIDEExist; bool bIsDiskExist; switch(nDrive / 2) { case 0: dwBaseAddress = 0x01F0; break; case 1: dwBaseAddress = 0x0170; break; case 2: dwBaseAddress = 0x01E8; break; case 3: dwBaseAddress = 0x0168; break; } btMasterSlave = (BYTE)(((nDrive % 2) == 0) ? 0xA0 : 0xB0); // 进入Ring0 bIsIDEExist = false; bIsDiskExist = false; ZeroMemory(wOutData, sizeof(wOutData)); ReadPhysicalDriveOnW9X_Ring0(false, dwBaseAddress, btMasterSlave, bIsIDEExist, bIsDiskExist, wOutData); if(bIsIDEExist && bIsDiskExist) { DWORD dwDiskData[256]; char szSerialNumber[21]; char szModelNumber[41]; for(int k=0; k < 256; k++) dwDiskData[k] = wOutData[k]; // 取系列号 ZeroMemory(szSerialNumber, sizeof(szSerialNumber)); strcpy(szSerialNumber, ConvertToString(dwDiskData, 10, 19)); // 取模型号 ZeroMemory(szModelNumber, sizeof(szModelNumber)); strcpy(szModelNumber, ConvertToString(dwDiskData, 27, 46)); pSerList->Add(szSerialNumber); pModeList->Add(szModelNumber); } } SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); } //--------------------------------------------------------------------------- // ReadPhysicalDriveOnW9X_Ring0() // // dwBaseAddress = IDE(0,1,2,3) : 1F0h, 170h, 1E8h, 168h // btMasterSlave = Master(0xA0) Or Slave(0xB0) //--------------------------------------------------------------------------- void __fastcall ReadPhysicalDriveOnW9X_Ring0(bool bIsFirst, WORD dwBaseAddress, BYTE btMasterSlave, bool &bIsIDEExist, bool &bIsDiskExist, WORD *pOutData) { BYTE btIDTR1[6]; DWORD dwOldExceptionHook; const int nHookExceptionNo = 5; BYTE btIsIDEExist = 0; BYTE btIsDiskExist = 0; WORD wOutDataBuf[256]; BYTE btIsFirst = (BYTE)bIsFirst; const BYTE btBit00 = 0x01; // const BYTE btBit02 = 0x04; const BYTE btBit06 = 0x40; const BYTE btBit07 = 0x80; // const BYTE btERR = btBit00; const BYTE btBusy = btBit07; const BYTE btAtaCmd = 0xEC; const BYTE btAtapiCmd = 0xA1; __asm { // 必须先执行这条语句 JMP EnterRing0 // 定义过程 // 等待IDE设备直到其不为忙为止 WaitWhileBusy proc MOV EBX, 100000 MOV DX, dwBaseAddress ADD DX, 7 LoopWhileBusy: DEC EBX CMP EBX, 0 JZ Timeout in AL, DX TEST AL, btBusy JNZ LoopWhileBusy JMP DriveReady // 超时,直接退出 Timeout: JMP LeaveRing0 DriveReady: RET ENDP // End of WaitWhileBusy Procedure // 设置主盘和从盘标志 SelectDevice proc MOV DX, dwBaseAddress ADD DX, 6 MOV AL, btMasterSlave out DX, AL RET ENDP // End of SelectDevice Procedure // 向IDE设备发送存取指令 SendCmd proc MOV DX, dwBaseAddress ADD DX, 7 MOV AL, BL // BL是主从盘标识,在过程外设置 out DX, AL RET ENDP // End of SendCmd Procedure // Ring0代码 Ring0Proc: PUSHAD // 查询IDE设备是否存在 MOV DX, dwBaseAddress ADD DX, 7 in AL,DX // 当AL的值是0xFF或者0x7F时,IDE设备不存在,这时候直接返回 CMP AL,0xFF JZ LeaveRing0 CMP AL, 0x7F JZ LeaveRing0 // 设置IDE设备存在标志 MOV btIsIDEExist, 1 // 查询IDE设备上的驱动器是否存在(有IDE插槽在主板上,但是却不一定有硬盘插在上面) CALL WaitWhileBusy CALL SelectDevice // 如果是第一次调用,则直接返回,否则执行下行语句时会出现蓝屏 CMP btIsFirst, 1 JZ LeaveRing0 // 第一次调用时,如果执行这行语句会导致蓝屏,Why??? CALL WaitWhileBusy // AL的值等于cBit06时,不存在驱动器,直接返回 TEST AL, btBit06 JZ LeaveRing0 // 设置驱动器存在标志 MOV btIsDiskExist, 1 // 发送存取端口命令 // 无法像NT/2000/XP那样可以通过查询VERSION的值得到驱动器的类型, // 所以只能一步一步地测试,如果不是ATA设备,再尝试使用ATAPI设备命令 CALL WaitWhileBusy CALL SelectDevice // 设置主从盘标识 MOV BL, btAtaCmd // 发送读取命令 CALL SendCmd CALL WaitWhileBusy // 检查是否出错 MOV DX, dwBaseAddress ADD DX, 7 in AL, DX TEST AL, btBit00 JZ RetrieveInfo // 没有错误时则读数据 // 如果出错,则进一步尝试使用ATAPI设备命令 CALL WaitWhileBusy CALL SelectDevice MOV BL, btAtapiCmd CALL SendCmd CALL WaitWhileBusy // 检查是否还出错 MOV DX, dwBaseAddress ADD DX, 7 in AL, DX TEST AL, btBit00 JZ RetrieveInfo // 没有错误时则读数据 JMP LeaveRing0 // 如果还是出错,直接返回 // 读取数据 RetrieveInfo: LEA EDI, wOutDataBuf MOV ECX, 256 MOV DX, dwBaseAddress CLD REP INSW // 退出Ring0代码 LeaveRing0: POPAD IRETD // 激活Ring0代码 EnterRing0: // 修改中断门 SIDT FWORD PTR btIDTR1 MOV EAX, DWORD PTR btIDTR1 + 02h ADD EAX, nHookExceptionNo * 08h + 04h CLI // 保存原异常处理例程入口 MOV ECX, DWORD PTR [EAX] MOV CX, WORD PTR [EAX-04h] MOV dwOldExceptionHook, ECX // 指定新入口 LEA EBX, Ring0Proc MOV WORD PTR [EAX-04h],BX SHR EBX, 10h MOV WORD PTR[EAX+02h], BX // 激活Ring0代码 INT nHookExceptionNo // 复原入口 MOV ECX,dwOldExceptionHook MOV WORD PTR[EAX-04h], CX SHR ECX,10h MOV WORD PTR[EAX+02h], CX STI } if(!bIsFirst) { bIsIDEExist = (bool)btIsIDEExist; bIsDiskExist = (bool)btIsDiskExist; CopyMemory(pOutData, wOutDataBuf, sizeof(wOutDataBuf)); } } //--------------------------------------------------------------------------- bool GetFirstHDDSerial(char *buf) { TStringList *SerialList = new TStringList(); TStringList *ModelList = new TStringList(); ReadPhysicalDrive(SerialList, ModelList); if(SerialList->Count) strcpy(buf, SerialList->Strings[0].c_str()); else strcpy(buf, ""); delete SerialList; delete ModelList; if(*buf) { int i, k=0; unsigned char temp[256]; unsigned char mask[12]={0x4e,0x24,0x69,0xf7,0xe1,0xa6,0x53,0x46,0x2d,0x74,0x3e,0xb1}; for(i=0; buf[i]; i++) { buf[i] = GetIndex(buf[i]); k += buf[i]; } k /= i; while(i<16) buf[i++] = k; i = k = 0; while(i<12) { temp[i++] = buf[k]|buf[k+1]<<6; temp[i++] = buf[k+1]>>2|buf[k+2]<<4; temp[i++] = buf[k+2]>>4|buf[k+3]<<2; k += 4; } for(i=0; i<12; i++) temp[i] = ~temp[i]^mask[i]; i = k = 0; while(i<16) { buf[i++] = ConvertTable[temp[k]&0x3f]; buf[i++] = ConvertTable[(temp[k]>>6|temp[k+1]<<2)&0x3f]; buf[i++] = ConvertTable[(temp[k+1]>>4|temp[k+2]<<4)&0x3f]; buf[i++] = ConvertTable[temp[k+2]>>2]; k += 3; } buf[16] = 0; return true; } return false; } //--------------------------------------------------------------------------- //////////判断是否为正确的序列号 bool CheckSerial(const unsigned char *serial, const unsigned char *key) { unsigned long a, b, c, d, t, u; unsigned char _tin[16], _tout[16]; unsigned long in_blk[4], out_blk[4]; int i, k; char tin[32]; i = k = 0; GetFirstHDDSerial(tin); while(i<12) { _tin[i++] = GetIndex(tin[k])|GetIndex(tin[k+1])<<6; _tin[i++] = GetIndex(tin[k+1])>>2|GetIndex(tin[k+2])<<4; _tin[i++] = GetIndex(tin[k+2])>>4|GetIndex(tin[k+3])<<2; k += 4; } _tin[12] = _tin[13] = _tin[14] = _tin[15] = 0; in_blk[0] = _tin[0]|(_tin[1]<<8)|(_tin[2]<<16)|(_tin[3]<<24); in_blk[1] = _tin[4]|(_tin[5]<<8)|(_tin[6]<<16)|(_tin[7]<<24); in_blk[2] = _tin[8]|(_tin[9]<<8)|(_tin[10]<<16)|(_tin[11]<<24); in_blk[3] = _tin[12]|(_tin[13]<<8)|(_tin[14]<<16)|(_tin[15]<<24); set_key(key); a = in_blk[0]; b = in_blk[1]+l_key[0]; c = in_blk[2]; d = in_blk[3]+l_key[1]; f_rnd( 2,a,b,c,d); f_rnd( 4,b,c,d,a); f_rnd( 6,c,d,a,b); f_rnd( 8,d,a,b,c); f_rnd(10,a,b,c,d); f_rnd(12,b,c,d,a); f_rnd(14,c,d,a,b); f_rnd(16,d,a,b,c); f_rnd(18,a,b,c,d); f_rnd(20,b,c,d,a); f_rnd(22,c,d,a,b); f_rnd(24,d,a,b,c); f_rnd(26,a,b,c,d); f_rnd(28,b,c,d,a); f_rnd(30,c,d,a,b); f_rnd(32,d,a,b,c); f_rnd(34,a,b,c,d); f_rnd(36,b,c,d,a); f_rnd(38,c,d,a,b); f_rnd(40,d,a,b,c); out_blk[0] = a+l_key[42]; out_blk[1] = b; out_blk[2] = c+l_key[43]; out_blk[3] = d; _tout[0] = out_blk[0]&0x000000ff; _tout[1] = (out_blk[0]>>8)&0x000000ff; _tout[2] = (out_blk[0]>>16)&0x000000ff; _tout[3] = (out_blk[0]>>24)&0x000000ff; _tout[4] = out_blk[1]&0x000000ff; _tout[5] = (out_blk[1]>>8)&0x000000ff; _tout[6] = (out_blk[1]>>16)&0x000000ff; _tout[7] = (out_blk[1]>>24)&0x000000ff; _tout[8] = out_blk[2]&0x000000ff; _tout[9] = (out_blk[2]>>8)&0x000000ff; _tout[10] = (out_blk[2]>>16)&0x000000ff; _tout[11] = (out_blk[2]>>24)&0x000000ff; _tout[12] = out_blk[3]&0x000000ff; _tout[13] = (out_blk[3]>>8)&0x000000ff; _tout[14] = (out_blk[3]>>16)&0x000000ff; _tout[15] = (out_blk[3]>>24)&0x000000ff; k = 0; for(i=0; i<16; i++) k += (GetIndex(serial[i])-(_tout[i]&0x3f)); return !k; } //--------------------------------------------------------------------------- #endif