现在的位置: 首页 > 综合 > 正文

怎样得到CPU的序列号

2013年12月19日 ⁄ 综合 ⁄ 共 2717字 ⁄ 字号 评论关闭

怎样得到CPU的序列号 

在带有注册功能的软件里经常需要获取CPU ID,硬盘ID(非盘区ID),网卡MAC地址等等,这些ID由于是硬件固有的,即使操作系统重装也不会改变它们,所以拿它们做因子来生成PC的唯一码成为可能(虽然它们还是可能被修改,比如网卡MAC地址就可以被修改,但比较复杂,总的来说是足够安全的)。
unit Main;

interface

uses
  Windows,
  Messages,
  SysUtils,
  Classes,
  Graphics,
  Controls,
  Forms,
  Dialogs,
  ExtCtrls,
  StdCtrls,
  Buttons;

type
  TDemoForm = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    GetButton: TBitBtn;
    CloseButton: TBitBtn;
    Bevel1: TBevel;
    Label5: TLabel;
    FLabel: TLabel;
    MLabel: TLabel;
    PLabel: TLabel;
    SLabel: TLabel;
    PValue: TLabel;
    FValue: TLabel;
    MValue: TLabel;
    SValue: TLabel;
    procedure GetButtonClick(Sender: TObject);
  end;

var
  DemoForm: TDemoForm;

implementation

{$R *.DFM}

const
 ID_BIT = $200000;   // EFLAGS ID bit
type
 TCPUID = array[1..4] of Longint;
 TVendor = array [0..11] of char;

function IsCPUID_Available : Boolean; register;
asm
 PUSHFD       {direct access to flags no possible, only via stack}
  POP     EAX     {flags to EAX}
  MOV     EDX,EAX   {save current flags}
  XOR     EAX,ID_BIT {not ID bit}
  PUSH    EAX     {onto stack}
  POPFD        {from stack to flags, with not ID bit}
  PUSHFD       {back to stack}
  POP     EAX     {get back to EAX}
  XOR     EAX,EDX   {check if ID bit affected}
  JZ      @exit    {no, CPUID not availavle}
  MOV     AL,True   {Result=True}
@exit:
end;

function GetCPUID : TCPUID; assembler; register;
asm
  PUSH    EBX         {Save affected register}
  PUSH    EDI
  MOV     EDI,EAX    
{@Resukt}
  MOV     EAX,1
  DW      $A20F       {CPUID Command}
  STOSD             {CPUID[1]}
  MOV     EAX,EBX
  STOSD               {CPUID[2]}
  MOV     EAX,ECX
  STOSD               {CPUID[3]}
  MOV     EAX,EDX
  STOSD               {CPUID[4]}
  POP     EDI     {Restore registers}
  POP     EBX
end;

function GetCPUVendor : TVendor; assembler; register;
asm
  PUSH    EBX     {Save affected register}
  PUSH    EDI
  MOV     EDI,EAX  
{@Result (TVendor)}
  MOV     EAX,0
  DW      $A20F    {CPUID Command}
  MOV     EAX,EBX
  XCHG  EBX,ECX     {save ECX result}
  MOV   ECX,4
@1:
  STOSB
  SHR     EAX,8
  LOOP    @1
  MOV     EAX,EDX
  MOV   ECX,4
@2:
  STOSB
  SHR     EAX,8
  LOOP    @2
  MOV     EAX,EBX
  MOV   ECX,4
@3:
  STOSB
  SHR     EAX,8
  LOOP    @3
  POP     EDI     {Restore registers}
  POP     EBX
end;

procedure TDemoForm.GetButtonClick(Sender: TObject);
var
  CPUID : TCPUID;
  I     : Integer;
  S   : TVendor;
begin
 for I := Low(CPUID) to High(CPUID)  do CPUID[I] := -1;
  if IsCPUID_Available then begin
   CPUID := GetCPUID;
   Label1.Caption := 'CPUID[1] = ' + IntToHex(CPUID[1],8);
   Label2.Caption := 'CPUID[2] = ' + IntToHex(CPUID[2],8);
   Label3.Caption := 'CPUID[3] = ' + IntToHex(CPUID[3],8);
   Label4.Caption := 'CPUID[4] = ' + IntToHex(CPUID[4],8);
   PValue.Caption := IntToStr(CPUID[1] shr 12 and 3);
   FValue.Caption := IntToStr(CPUID[1] shr 8 and $f);
   MValue.Caption := IntToStr(CPUID[1] shr 4 and $f);
   SValue.Caption := IntToStr(CPUID[1] and $f);
   S := GetCPUVendor;
   Label5.Caption := 'Vendor: ' + S; end
  else begin
   Label5.Caption := 'CPUID not available';
  end;
end;

end.

【上篇】
【下篇】

抱歉!评论已关闭.