J
jieson
Unregistered / Unconfirmed
GUEST, unregistred user!
<br><br>我搜过以前的帖子,下面这个号称能获得,但是我在d6下编译有三处语法错误:<br>unit Unit1;<br><br>interface<br><br>uses<br> Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br> StdCtrls;<br><br>type<br> TForm1 = class(TForm)<br> Button1: TButton;<br> procedure Button1Click(Sender: TObject);<br> private<br> { Private declarations }<br> public<br> { Public declarations }<br> end;<br><br>var<br> Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br>type<br> TGate = record<br> Off2,op,seg,off1:WORD;<br> end;<br> LONGDWORD = INT64;<br>var<br> IDTR: LONGDWORD;<br> SavedGate:TGate;<br> OurGate: TGate;<br> dd: array [0..256] of word;<br> dsn:array [0..20] of char; //存放硬盘序列号<br><br>procedure Ring0Proc();<br>asm<br>// Wait for controller not busy<br>mov dx,01f7h<br>@1:in al,dx<br>cmp al,050h<br>jne @1<br><br>// Get first/second drive<br>dec dx<br>mov al,0a0h<br>out dx,al<br><br>// Get drive info data<br>inc dx<br>mov al,0ech<br>out dx,al<br>nop<br>nop<br><br>// Wait for data ready<br>@2:in al,dx<br>cmp al,058h<br>jne @2<br>nop<br>nop<br>// Read sector<br>xor ecx,ecx<br>mov dx,01f0h<br>@3:in ax,dx<br>mov word ptr dd[ecx*2],ax // <------这里有语法错误<br>inc ecx<br>cmp ecx,256<br>jne @3<br><br>iretd //中断返回<br>end;<br><br>procedure Change2Ring0();<br>begin<br> asm<br> mov eax, offset Ring0Proc<br> mov OurGate.off2, ax // 将 中 断 函 数 的 地 址<br> shr eax, 16 // 填 入 新 造 的 中 断 门<br> mov OurGate.off1, ax // 描 述 符<br> mov OurGate.op,0028h<br> mov OurGate.seg,0ee00h // <------这里有语法错误<br> mov ebx,offset IDTR<br> sidt [ebx]<br> // 将 中 断 描 述 符 表 寄 存 器(IDTR)的 内 容 取 出<br> mov ebx, dword ptr [IDTR+2]<br> // 取 出 中 断 描 述 符 表(IDT) 基 地 址<br> add ebx, 8*3<br> // 计 算Int 3 的 描 述 符 应 放 置 的 地 址 选 用<br> //Int3 是 因 为 它 在Win32 保 护 模 式 下 未 占 用<br> mov edi, offset SavedGate<br> mov esi, ebx<br> movsd // 保 存 原 来 的Int 9 描 述 符 到<br> movsd //SavedGate 以 便 恢 复<br><br> mov edi, ebx<br> mov esi, offset OurGate<br> cli<br> movsd // 替 换 原 来 的 中 断 门 描 述 符<br> movsd // 以 安 装 中 断 服 务 例 程<br> sti<br> mov eax,6200h<br> // 用 以 测 试 放 在EAX 中 的 数 据 能 否 正 确 传 到Ring0 中 断<br> mov ecx,0<br> // 用 以 测 试 放 在ECX 中 的 数 据<br> // 能 否 正 确 传 到Ring0 中 断<br> // 因 为 很 多VxD 服 务 都 用此二 寄 存 器 传 递 参 数<br> int 3h<br> // 人 为 触 发 中 断, 平 时 会 出 现保 护 错 误 蓝 屏 或 非 法 操<br> // 作 对 话 框, 现 在 安 装 了<br> // 中 断 服 务 例 程 后, 就 会 通 过<br> //VMM 在Ring0 调 用 中 断 服 务 例 程Ring0Proc<br> mov edi, ebx<br> mov esi, offset SavedGate<br> cli<br> movsd // 恢 复 原 来 的 中 断 门 描 述 符<br> movsd<br> sti<br> end;<br>asm<br>xor ecx,ecx<br>mov ebx,offset dd[10*2] // <------这里有语法错误<br>@4:mov ax,[ebx]<br>mov byte ptr dsn[ecx],ah<br>inc ecx<br>mov byte ptr dsn[ecx],al<br>inc ebx<br>inc ebx<br>inc ecx<br>cmp ecx,10<br>jne @4<br>end;<br> showmessage(dsn);<br>end;<br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br> change2ring0;<br><br>end;<br>end.<br><br><br><br>还有另外一个办法,可以在2000和nt下获得硬盘序列号,但是98下还需要把<br>SmartVSD.VxD拷到System/IOSubSys目录下,然后重起之后才行,我不想让人重起,下面<br><br>是代码:<br><br><br>function GetIdeDiskSerialNumber : String;<br>type<br> TSrbIoControl = packed record<br> HeaderLength : ULONG;<br> Signature : Array[0..7] of Char;<br> Timeout : ULONG;<br> ControlCode : ULONG;<br> ReturnCode : ULONG;<br> Length : ULONG;<br> end;<br> SRB_IO_CONTROL = TSrbIoControl;<br> PSrbIoControl = ^TSrbIoControl;<br><br> TIDERegs = packed record<br> bFeaturesReg : Byte; // Used for specifying SMART "commands".<br> bSectorCountReg : Byte; // IDE sector count register<br> bSectorNumberReg : Byte; // IDE sector number register<br> bCylLowReg : Byte; // IDE low order cylinder value<br> bCylHighReg : Byte; // IDE high order cylinder value<br> bDriveHeadReg : Byte; // IDE drive/head register<br> bCommandReg : Byte; // Actual IDE command.<br> bReserved : Byte; // reserved for future use. Must be zero.<br> end;<br> IDEREGS = TIDERegs;<br> PIDERegs = ^TIDERegs;<br><br> TSendCmdInParams = packed record<br> cBufferSize : DWORD; // Buffer size in bytes<br> irDriveRegs : TIDERegs; // Structure with drive register <br><br>values.<br> bDriveNumber : Byte; // Physical drive number to send <br><br>command to (0,1,2,3).<br> bReserved : Array[0..2] of Byte; // Reserved for future expansion.<br> dwReserved : Array[0..3] of DWORD; // For future use.<br> bBuffer : Array[0..0] of Byte; // Input buffer.<br> end;<br> SENDCMDINPARAMS = TSendCmdInParams;<br> PSendCmdInParams = ^TSendCmdInParams;<br><br> TIdSector = packed record<br> wGenConfig : Word;<br> wNumCyls : Word;<br> wReserved : Word;<br> wNumHeads : Word;<br> wBytesPerTrack : Word;<br> wBytesPerSector : Word;<br> wSectorsPerTrack : Word;<br> wVendorUnique : Array[0..2] of Word;<br> sSerialNumber : Array[0..19] of Char;<br> wBufferType : Word;<br> wBufferSize : Word;<br> wECCSize : Word;<br> sFirmwareRev : Array[0..7] of Char;<br> sModelNumber : Array[0..39] of Char;<br> wMoreVendorUnique : Word;<br> wDoubleWordIO : Word;<br> wCapabilities : Word;<br> wReserved1 : Word;<br> wPIOTiming : Word;<br> wDMATiming : Word;<br> wBS : Word;<br> wNumCurrentCyls : Word;<br> wNumCurrentHeads : Word;<br> wNumCurrentSectorsPerTrack : Word;<br> ulCurrentSectorCapacity : ULONG;<br> wMultSectorStuff : Word;<br> ulTotalAddressableSectors : ULONG;<br> wSingleWordDMA : Word;<br> wMultiWordDMA : Word;<br> bReserved : Array[0..127] of Byte;<br> end;<br> PIdSector = ^TIdSector;<br><br>const<br> IDE_ID_FUNCTION = $EC;<br> IDENTIFY_BUFFER_SIZE = 512;<br> DFP_RECEIVE_DRIVE_DATA = $0007c088;<br> IOCTL_SCSI_MINIPORT = $0004d008;<br> IOCTL_SCSI_MINIPORT_IDENTIFY = $001b0501;<br> DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE;<br> BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize;<br> W9xBufferSize = IDENTIFY_BUFFER_SIZE+16;<br>var<br> hDevice : THandle;<br> cbBytesReturned : DWORD;<br> pInData : PSendCmdInParams;<br> pOutData : Pointer; // PSendCmdInParams;<br> Buffer : Array[0..BufferSize-1] of Byte;<br> srbControl : TSrbIoControl absolute Buffer;<br><br> procedure ChangeByteOrder( var Data; Size : Integer );<br> var ptr : PChar;<br> i : Integer;<br> c : Char;<br> begin<br> ptr := @Data;<br> for i := 0 to (Size shr 1)-1 do<br> begin<br> c := ptr^;<br> ptr^ := (ptr+1)^;<br> (ptr+1)^ := c;<br> Inc(ptr,2);<br> end;<br> end;<br><br>begin<br> Result := '';<br> FillChar(Buffer,BufferSize,#0);<br> if Win32Platform=VER_PLATFORM_WIN32_NT then<br> begin // Windows NT, Windows 2000<br> // Get SCSI port handle<br> hDevice := CreateFile( '//./Scsi0:', GENERIC_READ or GENERIC_WRITE,<br> FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0 );<br> if hDevice=INVALID_HANDLE_VALUE then Exit;<br> try<br> srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);<br> System.Move('SCSIDISK',srbControl.Signature,8);<br> srbControl.Timeout := 2;<br> srbControl.Length := DataSize;<br> srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;<br> pInData := PSendCmdInParams(PChar(@Buffer)+SizeOf(SRB_IO_CONTROL));<br>pOutData := pInData;<br> with pInData^ do<br> begin<br> cBufferSize := IDENTIFY_BUFFER_SIZE;<br> bDriveNumber := 0;<br> with irDriveRegs do<br> begin<br> bFeaturesReg := 0;<br> bSectorCountReg := 1;<br> bSectorNumberReg := 1;<br> bCylLowReg := 0;<br> bCylHighReg := 0;<br> bDriveHeadReg := $A0;<br> bCommandReg := IDE_ID_FUNCTION;<br> end;<br> end;<br> if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, @Buffer, <br><br>BufferSize, @Buffer, BufferSize, cbBytesReturned, nil ) then Exit;<br> finally<br> CloseHandle(hDevice);<br> end;<br> end<br> else<br> begin // Windows 95 OSR2, Windows 98<br> hDevice := CreateFile( '//./SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0 );<br> if hDevice=INVALID_HANDLE_VALUE then Exit;<br>try<br> pInData := PSendCmdInParams(@Buffer);<br>pOutData := PChar(@pInData^.bBuffer);<br> with pInData^ do<br> begin<br> cBufferSize := IDENTIFY_BUFFER_SIZE;<br> bDriveNumber := 0;<br> with irDriveRegs do<br> begin<br> bFeaturesReg := 0;<br> bSectorCountReg := 1;<br> bSectorNumberReg := 1;<br> bCylLowReg := 0;<br> bCylHighReg := 0;<br> bDriveHeadReg := $A0;<br> bCommandReg := IDE_ID_FUNCTION;<br> end;<br> end;<br> if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, pInData, <br><br>SizeOf(TSendCmdInParams)-1, pOutData, W9xBufferSize, cbBytesReturned, nil ) <br><br>then Exit;<br>finally<br> CloseHandle(hDevice);<br>end;<br> end;<br> with PIdSector(PChar(pOutData)+16)^ do<br> begin<br> ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber));<br> SetString(Result,sSerialNumber,SizeOf(sSerialNumber));<br> end;<br>end;<br><br>谁有办法在98下读硬盘序列号而不用重起的?有控件也行啊!调试通过了就给分,谢谢大<br><br>家!