📄 main.h
字号:
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -