Get Hard Disk Serial Number (100分)

  • 主题发起人 主题发起人 swjg
  • 开始时间 开始时间
S

swjg

Unregistered / Unconfirmed
GUEST, unregistred user!
GetVolumeInformation 得到的是windows软系列号,怎样才能得到硬盘的硬系列号。
 
我在一个叫XX编程的网站见过,斑竹叫陆麟
 
看看http://www.delphibbs.com/delphibbs/DispQ.asp?LID=450556,我以前回答过的
 
多谢djdsz。但在98下不行。
 
利用 Vxd 的方式,可以做到。<br><br>Smartvsd.Vxd<br>可在国外网站 DownLoad ..
 
一个console程序;<br>在Win9x下需要有 smartvsd.vxd,把他从/windows/system/拷贝到<br>/windows/system/iosubsys/重启 <br><br>program IdeSN; <br><br>{$APPTYPE CONSOLE} <br><br>uses <br>&nbsp; Windows, <br>&nbsp; SysUtils; // only for Win32Platform and SysErrorMessage <br><br>//------------------------------------------------------------- <br>function GetIdeDiskSerialNumber : String; <br>type <br>&nbsp; TSrbIoControl = packed record <br>&nbsp; &nbsp; HeaderLength : ULONG; <br>&nbsp; &nbsp; Signature &nbsp; &nbsp;: Array[0..7] of Char; <br>&nbsp; &nbsp; Timeout &nbsp; &nbsp; &nbsp;: ULONG; <br>&nbsp; &nbsp; ControlCode &nbsp;: ULONG; <br>&nbsp; &nbsp; ReturnCode &nbsp; : ULONG; <br>&nbsp; &nbsp; Length &nbsp; &nbsp; &nbsp; : ULONG; <br>&nbsp; end; <br>&nbsp; SRB_IO_CONTROL = TSrbIoControl; <br>&nbsp; PSrbIoControl = ^TSrbIoControl; <br><br>&nbsp; TIDERegs = packed record <br>&nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; : Byte; // Used for specifying SMART "commands". <br>&nbsp; &nbsp; bSectorCountReg &nbsp;: Byte; // IDE sector count register <br>&nbsp; &nbsp; bSectorNumberReg : Byte; // IDE sector number register <br>&nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; : Byte; // IDE low order cylinder value <br>&nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;: Byte; // IDE high order cylinder value <br>&nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;: Byte; // IDE drive/head register <br>&nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;: Byte; // Actual IDE command. <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp; &nbsp; &nbsp;: Byte; // reserved. &nbsp;Must be zero. <br>&nbsp; end; <br>&nbsp; IDEREGS &nbsp; = TIDERegs; <br>&nbsp; PIDERegs &nbsp;= ^TIDERegs; <br><br>&nbsp; TSendCmdInParams = packed record <br>&nbsp; &nbsp; cBufferSize &nbsp;: DWORD; <br>&nbsp; &nbsp; irDriveRegs &nbsp;: TIDERegs; <br>&nbsp; &nbsp; bDriveNumber : Byte; <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp;: Array[0..2] of Byte; <br>&nbsp; &nbsp; dwReserved &nbsp; : Array[0..3] of DWORD; <br>&nbsp; &nbsp; bBuffer &nbsp; &nbsp; &nbsp;: Array[0..0] of Byte; <br>&nbsp; end; <br>&nbsp; SENDCMDINPARAMS &nbsp; = TSendCmdInParams; <br>&nbsp; PSendCmdInParams &nbsp;= ^TSendCmdInParams; <br><br>&nbsp; TIdSector = packed record <br>&nbsp; &nbsp; wGenConfig &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wNumCyls &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wReserved &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumHeads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wBytesPerTrack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wBytesPerSector &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wSectorsPerTrack &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wVendorUnique &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..2] of Word; <br>&nbsp; &nbsp; sSerialNumber &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..19] of Char; <br>&nbsp; &nbsp; wBufferType &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wBufferSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wECCSize &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; sFirmwareRev &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Array[0..7] of Char; <br>&nbsp; &nbsp; sModelNumber &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Array[0..39] of Char; <br>&nbsp; &nbsp; wMoreVendorUnique &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wDoubleWordIO &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wCapabilities &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wReserved1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wPIOTiming &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wDMATiming &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wBS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumCurrentCyls &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; wNumCurrentHeads &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wNumCurrentSectorsPerTrack : Word; <br>&nbsp; &nbsp; ulCurrentSectorCapacity &nbsp; &nbsp;: ULONG; <br>&nbsp; &nbsp; wMultSectorStuff &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; ulTotalAddressableSectors &nbsp;: ULONG; <br>&nbsp; &nbsp; wSingleWordDMA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : Word; <br>&nbsp; &nbsp; wMultiWordDMA &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Word; <br>&nbsp; &nbsp; bReserved &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: Array[0..127] of Byte; <br>&nbsp; end; <br>&nbsp; PIdSector = ^TIdSector; <br><br>const <br>&nbsp; IDE_ID_FUNCTION = $EC; <br>&nbsp; IDENTIFY_BUFFER_SIZE &nbsp; &nbsp; &nbsp; = 512; <br>&nbsp; DFP_RECEIVE_DRIVE_DATA &nbsp; &nbsp; &nbsp; &nbsp;= $0007c088; <br>&nbsp; IOCTL_SCSI_MINIPORT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = $0004d008; <br>&nbsp; IOCTL_SCSI_MINIPORT_IDENTIFY &nbsp;= $001b0501; <br>&nbsp; DataSize = sizeof(TSendCmdInParams)-1+IDENTIFY_BUFFER_SIZE; <br>&nbsp; BufferSize = SizeOf(SRB_IO_CONTROL)+DataSize; <br>&nbsp; W9xBufferSize = IDENTIFY_BUFFER_SIZE+16; <br>var <br>&nbsp; hDevice : THandle; <br>&nbsp; cbBytesReturned : DWORD; <br>&nbsp; pInData : PSendCmdInParams; <br>&nbsp; pOutData : Pointer; // PSendCmdOutParams <br>&nbsp; Buffer : Array[0..BufferSize-1] of Byte; <br>&nbsp; srbControl : TSrbIoControl absolute Buffer; <br><br>&nbsp; procedure ChangeByteOrder( var Data; Size : Integer ); <br>&nbsp; var ptr : PChar; <br>&nbsp; &nbsp; &nbsp; i : Integer; <br>&nbsp; &nbsp; &nbsp; c : Char; <br>&nbsp; begin <br>&nbsp; &nbsp; ptr := @Data; <br>&nbsp; &nbsp; for i := 0 to (Size shr 1)-1 do <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; c := ptr^; <br>&nbsp; &nbsp; &nbsp; ptr^ := (ptr+1)^; <br>&nbsp; &nbsp; &nbsp; (ptr+1)^ := c; <br>&nbsp; &nbsp; &nbsp; Inc(ptr,2); <br>&nbsp; &nbsp; end; <br>&nbsp; end; <br><br>begin <br>&nbsp; Result := ''; <br>&nbsp; FillChar(Buffer,BufferSize,#0); <br>&nbsp; if Win32Platform=VER_PLATFORM_WIN32_NT then <br>&nbsp; &nbsp; begin // Windows NT, Windows 2000 <br>&nbsp; &nbsp; &nbsp; // Get SCSI port handle <br>&nbsp; &nbsp; &nbsp; hDevice := CreateFile( '//./Scsi0:', <br>&nbsp; &nbsp; &nbsp; &nbsp; GENERIC_READ or GENERIC_WRITE, <br>&nbsp; &nbsp; &nbsp; &nbsp; FILE_SHARE_READ or FILE_SHARE_WRITE, <br>&nbsp; &nbsp; &nbsp; &nbsp; nil, OPEN_EXISTING, 0, 0 ); <br>&nbsp; &nbsp; &nbsp; if hDevice=INVALID_HANDLE_VALUE then Exit; <br>&nbsp; &nbsp; &nbsp; try <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL); <br>&nbsp; &nbsp; &nbsp; &nbsp; System.Move('SCSIDISK',srbControl.Signature,8); <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.Timeout &nbsp; &nbsp; &nbsp;:= 2; <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.Length &nbsp; &nbsp; &nbsp; := DataSize; <br>&nbsp; &nbsp; &nbsp; &nbsp; srbControl.ControlCode &nbsp;:= IOCTL_SCSI_MINIPORT_IDENTIFY; <br>&nbsp; &nbsp; &nbsp; &nbsp; pInData := PSendCmdInParams(PChar(@Buffer) <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;+SizeOf(SRB_IO_CONTROL)); <br>&nbsp; &nbsp; &nbsp; &nbsp; pOutData := pInData; <br>&nbsp; &nbsp; &nbsp; &nbsp; with pInData^ do <br>&nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cBufferSize &nbsp;:= IDENTIFY_BUFFER_SIZE; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveNumber := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with irDriveRegs do <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorCountReg &nbsp;:= 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorNumberReg := 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;:= 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;:= $A0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;:= IDE_ID_FUNCTION; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; if not DeviceIoControl( hDevice, IOCTL_SCSI_MINIPORT, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Buffer, BufferSize, @Buffer, BufferSize, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cbBytesReturned, nil ) then Exit; <br>&nbsp; &nbsp; &nbsp; finally <br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hDevice); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; end <br>&nbsp; else <br>&nbsp; &nbsp; begin // Windows 95 OSR2, Windows 98 <br>&nbsp; &nbsp; &nbsp; hDevice := CreateFile( '//./SMARTVSD', 0, 0, nil, <br>&nbsp; &nbsp; &nbsp; &nbsp; CREATE_NEW, 0, 0 ); <br>&nbsp; &nbsp; &nbsp; if hDevice=INVALID_HANDLE_VALUE then Exit; <br>&nbsp; &nbsp; &nbsp; try <br>&nbsp; &nbsp; &nbsp; &nbsp; pInData := PSendCmdInParams(@Buffer); <br>&nbsp; &nbsp; &nbsp; &nbsp; pOutData := @pInData^.bBuffer; <br>&nbsp; &nbsp; &nbsp; &nbsp; with pInData^ do <br>&nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cBufferSize &nbsp;:= IDENTIFY_BUFFER_SIZE; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveNumber := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; with irDriveRegs do <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bFeaturesReg &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorCountReg &nbsp;:= 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bSectorNumberReg := 1; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylLowReg &nbsp; &nbsp; &nbsp; := 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCylHighReg &nbsp; &nbsp; &nbsp;:= 0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bDriveHeadReg &nbsp; &nbsp;:= $A0; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bCommandReg &nbsp; &nbsp; &nbsp;:= IDE_ID_FUNCTION; <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; &nbsp; &nbsp; if not DeviceIoControl( hDevice, DFP_RECEIVE_DRIVE_DATA, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pInData, SizeOf(TSendCmdInParams)-1, pOutData, <br>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; W9xBufferSize, cbBytesReturned, nil ) then Exit; <br>&nbsp; &nbsp; &nbsp; finally <br>&nbsp; &nbsp; &nbsp; &nbsp; CloseHandle(hDevice); <br>&nbsp; &nbsp; &nbsp; end; <br>&nbsp; &nbsp; end; <br>&nbsp; &nbsp; with PIdSector(PChar(pOutData)+16)^ do <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; ChangeByteOrder(sSerialNumber,SizeOf(sSerialNumber)); <br>&nbsp; &nbsp; &nbsp; SetString(Result,sSerialNumber,SizeOf(sSerialNumber)); <br>&nbsp; &nbsp; end; <br>end; <br><br><br>//============================================================= <br>var s : String; <br>&nbsp; &nbsp; rc : DWORD; <br>begin <br>&nbsp; s := GetIdeDiskSerialNumber; <br>&nbsp; if s='' then <br>&nbsp; &nbsp; begin <br>&nbsp; &nbsp; &nbsp; rc := GetLastError; <br>&nbsp; &nbsp; &nbsp; if rc=0 then WriteLn('IDE drive is not support SMART feature') <br>&nbsp; &nbsp; &nbsp; else WriteLn(SysErrorMessage(rc)); <br>&nbsp; &nbsp; end <br>&nbsp; else WriteLn('Disk serial number: ''', s,''''); <br>end.<br>
 
YTH说的方法不错,可以实现读取硬盘序列号,实际上目前来说,读取硬盘序列号的方法<br>有两种:<br>&nbsp; 1,通过VXD方法实现读取,如YTH的方法,或者用其余的控件实现,如Smallport控件,该控件<br>在很多网站都有下载,实现的代码如下:<br>procedure TForm2.Button1Click(Sender: TObject);<br>const<br>&nbsp; DiskA=$1f0;<br>&nbsp; DiskB=$170;<br>var<br>&nbsp; buffer:array[0..255] of word;<br>&nbsp; i:integer;<br>&nbsp; s:string;<br>&nbsp; disk:integer;<br>begin<br>&nbsp; If SpinEdit2.Value=0 then Disk:=DiskA else Disk:=DiskB;<br>&nbsp; With SmallPort1 do<br>&nbsp; &nbsp; begin<br>&nbsp; &nbsp; &nbsp; OpenDriver;<br>&nbsp; &nbsp; &nbsp; while (ReadByte(Disk+7)&lt;&gt;$50) do inc(i);<br>&nbsp; &nbsp; &nbsp; WriteByte(Disk+6,$a0+SpinEdit1.Value*$10);<br>&nbsp; &nbsp; &nbsp; WriteByte(Disk+7,$ec);<br>&nbsp; &nbsp; &nbsp; while (ReadByte(Disk+7)&lt;&gt;$58) do inc(i);<br>&nbsp; &nbsp; &nbsp; for i:=0 to 255 do buffer:=ReadWord(Disk);<br>&nbsp; &nbsp; &nbsp; s:='';<br>&nbsp; &nbsp; &nbsp; for i:=10 to 19 do<br>&nbsp; &nbsp; &nbsp; &nbsp; s:=s+chr(buffer shr 8)+chr(buffer and $ff);<br>&nbsp; &nbsp; &nbsp; CloseDriver;<br>&nbsp; &nbsp; &nbsp; Edit1.Text:=s;<br>&nbsp; &nbsp; end;<br>end;<br><br>&nbsp; 2,不用控件,直接编程实现,也就是直接在程序中进入RING0执行指令得到,代码如下:<br><br>unit SNU;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,<br>&nbsp; StdCtrls, BiosInfo;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; MainBoardBiosInformation1: TMainBoardBiosInformation;<br>&nbsp; &nbsp; Edit1: TEdit;<br>&nbsp; &nbsp; Edit2: TEdit;<br>&nbsp; &nbsp; Label1: TLabel;<br>&nbsp; &nbsp; Label2: TLabel;<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; { Private declarations }<br>&nbsp; public<br>&nbsp; &nbsp; { Public declarations }<br>&nbsp; end;<br><br>var<br>&nbsp; Form1: TForm1;<br><br>implementation<br><br>{$R *.DFM}<br>type<br>&nbsp;TGate = record<br>&nbsp; &nbsp; &nbsp;Off2,op,seg,off1:WORD;<br>&nbsp;end;<br>&nbsp;LONGDWORD = INT64;<br>var<br>&nbsp; IDTR: LONGDWORD;<br>&nbsp; SavedGate:TGate;<br>&nbsp; OurGate: TGate;<br>&nbsp; dd: array [0..256] of word;<br>&nbsp; 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 &nbsp;@1<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 &nbsp;@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 &nbsp;//中断返回<br>end;<br><br>FUNCTION Change2Ring0:PCHAR;<br>begin<br>&nbsp; asm<br>&nbsp; &nbsp; &nbsp; mov &nbsp; eax, offset Ring0Proc<br>&nbsp; &nbsp; &nbsp; mov &nbsp; OurGate.off2, ax &nbsp;// 将 中 断 函 数 的 地 址<br>&nbsp; &nbsp; &nbsp; shr &nbsp; eax, 16 &nbsp; // 填 入 新 造 的 中 断 门<br>&nbsp; &nbsp; &nbsp; mov &nbsp; OurGate.off1, ax // 描 述 符<br>&nbsp; &nbsp; &nbsp; mov &nbsp; OurGate.op,0028h<br>&nbsp; &nbsp; &nbsp; mov &nbsp; OurGate.seg,0ee00h<br>&nbsp; &nbsp; &nbsp; mov &nbsp; ebx,offset IDTR<br>&nbsp; &nbsp; &nbsp; sidt &nbsp;[ebx]<br>&nbsp; &nbsp; &nbsp; // 将 中 断 描 述 符 表 寄 存 器(IDTR)的 内 容 取 出<br>&nbsp; &nbsp; &nbsp; mov &nbsp; ebx, dword ptr [IDTR+2]<br>&nbsp; &nbsp; &nbsp; // 取 出 中 断 描 述 符 表(IDT) 基 地 址<br>&nbsp; &nbsp; &nbsp; add &nbsp; ebx, 8*3<br>&nbsp; &nbsp; &nbsp; // 计 算Int 3 的 描 述 符 应 放 置 的 地 址 选 用<br>&nbsp; &nbsp; &nbsp; //Int3 是 因 为 它 在Win32 保 护 模 式 下 未 占 用<br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; &nbsp;edi, offset SavedGate<br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; &nbsp;esi, ebx<br>&nbsp; &nbsp; &nbsp; movsd &nbsp; // 保 存 原 来 的Int 9 描 述 符 到<br>&nbsp; &nbsp; &nbsp; movsd &nbsp;//SavedGate 以 便 恢 复<br><br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; &nbsp;edi, ebx<br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp; &nbsp;esi, offset OurGate<br>&nbsp; &nbsp; &nbsp; cli<br>&nbsp; &nbsp; &nbsp; movsd &nbsp;// 替 换 原 来 的 中 断 门 描 述 符<br>&nbsp; &nbsp; &nbsp; movsd &nbsp;// 以 安 装 中 断 服 务 例 程<br>&nbsp; &nbsp; &nbsp; sti<br>&nbsp; &nbsp; &nbsp; mov &nbsp; eax,6200h<br>&nbsp; &nbsp; &nbsp;// 用 以 测 试 放 在EAX 中 的 数 据 &nbsp;能 否 正 确 传 到Ring0 中 断<br>&nbsp; &nbsp; &nbsp; mov &nbsp; ecx,0<br>&nbsp; &nbsp; &nbsp;// 用 以 测 试 放 在ECX 中 的 数 据<br>&nbsp; &nbsp; &nbsp;// &nbsp;能 否 正 确 传 到Ring0 中 断<br>&nbsp; &nbsp; &nbsp; // 因 为 很 多VxD 服 务 都 用此二 寄 存 器 传 递 参 数<br>&nbsp; &nbsp; &nbsp;int 3h<br>&nbsp; &nbsp; &nbsp;// 人 为 触 发 中 断, 平 时 会 出 现保 护 错 误 蓝 屏 或 非 法 操<br>&nbsp; &nbsp; &nbsp;// 作 对 话 框, 现 在 安 装 了<br>&nbsp; &nbsp; &nbsp;// 中 断 服 务 例 程 后, 就 会 通 过<br>&nbsp; &nbsp; &nbsp;//VMM 在Ring0 调 用 中 断 服 务 例 程Ring0Proc<br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp;edi, ebx<br>&nbsp; &nbsp; &nbsp; mov &nbsp; &nbsp;esi, offset SavedGate<br>&nbsp; &nbsp; &nbsp; cli<br>&nbsp; &nbsp; &nbsp; movsd // 恢 复 原 来 的 中 断 门 描 述 符<br>&nbsp; &nbsp; &nbsp; movsd<br>&nbsp; &nbsp; &nbsp; sti<br>&nbsp; end;<br>asm<br>&nbsp; xor ecx,ecx<br>&nbsp; mov ebx,offset dd[10*2]<br>&nbsp; @4:mov ax,[ebx]<br>&nbsp; mov byte ptr dsn[ecx],ah<br>&nbsp; inc ecx<br>&nbsp; mov byte ptr dsn[ecx],al<br>&nbsp; inc ebx<br>&nbsp; inc ebx<br>&nbsp; inc ecx<br>&nbsp; cmp ecx,10<br>&nbsp; jne @4<br>end;<br>&nbsp; RESULT:=dsn;<br>end;<br><br><br>procedure TForm1.Button1Click(Sender: TObject);<br>VAR S:PCHAR;<br>&nbsp; StrA: string;<br>begin<br>&nbsp; &nbsp; S:=change2ring0;<br>&nbsp; &nbsp; showmessage(s);<br>&nbsp; &nbsp; EDIT1.TEXT:=STRPAS(S); &nbsp;//该指令一执行就出错,不知为什么<br>end;<br><br>&nbsp; 你的程序如果是想通过硬盘序列号作为共享软件的注册密钥,当然是第二种方法好,因<br>为对于第一种方法如果破解了VXD文件,就没戏了,不过第二种方法我所列出的代码可能有<br>问题,如果有哪位高手能指出错误原因,不用感谢<br><br><br><br><br>
 
不好意思啊。<br>我只是想要这个问题的列表<br>但没办法收藏这个问题。只好这样了。
 
留下你的E-Mail<br>or Mail to WiseAnt@263.net
 
接受答案了.
 

Similar threads

D
回复
0
查看
881
DelphiTeacher的专栏
D
D
回复
0
查看
851
DelphiTeacher的专栏
D
后退
顶部