25 Februari 2009

Mendapatkan ID Unik Dari Suatu Komputer (Lanjutan)

Setelah dapet cara untuk mendapatkan MAC address yang bisa digunakan untuk proteksi program, si Bos pun senang. Tapi selang beberapa waktu sang Bos pun datang lagi. Kali ini minta supaya proteksinya lebih diperkuat lagi. Dia minta agar yang tadinya cuma ngambil dari MAC address saja, kali ini ditambah lagi dari hardware yang lain. Biar lebih sip katanya, lagian kalo komputernya kebetulan ga ada NIC-nya bisa tetap jalan. Ada-ada saja si Bos ini, suka banget sih nyusahin orang. Sambil menggerutu dan mengomel (tentunya dalam hati) aku kerjain juga tuh permintaannya.
Saat itu aku berpikir apa ya yang pasti ada dari komputer yang ga mungkin tidak ada. Akhirnya aku putusin prosesorlah yang jadi pilihan. Komputer masih bisa jalan tanpa NIC, tapi kalo tanpa prosesor? Komputer ghoib kali. Tapi untuk mendapatkan id dari prosesor prosesor ini ga gampang, bahkan susah bagi kebanyakan orang, soalnya ada bagian dari code-nya yang musti pake bahasa asembly. Jadi inget waktu kuliah dulu, waktu ngikuti mata kuliah mikroprosesor. Susah tapi keren tu, untuk sekarang walau udah jadi bahasa kuno, tapi masih ampuh untuk beberapa solusi masalah, bahkan ada yang musti pake bahasa kuno ini supaya bisa jalan atau lebih cepat karna kemampuannya yang bisa akses register prosesor (mungkin cuma bahasa inilah yang bisa, setidaknya setahuku).
Ya udah, kita balik lagi buat dapetin id dari prosesor. Sebenarnya sebagian besar prosesor tidak punya sesuatu yang unik yang bisa didapat dari program seperti MAC address, yang ada adalah info seperti vendor, tipe prosesor, jumlah core, clock speed, dll. Jadi dari sinilah bisa kita mainin. Dari info tersebut digabung, trus dengan suatu algoritma jadilah sebuah “id” buat prosesor.
uses Classes, SysUtils;

implementation

function GetCPUInfos: TStringList;
var
  _eax, _ebx, _ecx, _edx: Longword;
  i: Integer;
  b: Byte;
  s, s1, s2, s3, s_all: string;
begin
  Result := TStringList.Create;
  asm // asm call to the CPUID inst.
    mov eax, 0 // sub. func call
    db $0F, $A2 // db $0F,$A2 = CPUID instruction
    mov _ebx, ebx
    mov _ecx, ecx
    mov _edx, edx
  end;
  for i := 0 to 3 do // extract vendor id
  begin
    b := Lo(_ebx);
    s := s + chr(b);
    b := Lo(_ecx);
    s1:= s1 + chr(b);
    b := Lo(_edx);
    s2:= s2 + chr(b);
    _ebx := _ebx shr 8;
    _ecx := _ecx shr 8;
    _edx := _edx shr 8;
  end;
  Result.Add('CPU' + '');
  Result.Add(' - ' + 'Vendor ID: ' + s + s2 + s1);
  asm
    mov eax, 1
    db $0F, $A2
    mov _eax, eax
    mov _ebx, ebx
    mov _ecx, ecx
    mov _edx, edx
  end;
  b := Lo(_eax) and 15;
  Result.Add(' - ' + 'Stepping ID: ' + IntToStr(b));
  b := Lo(_eax) shr 4;
  Result.Add(' - ' + 'Model Number: ' + IntToHex(b, 1));
  b := Hi(_eax) and 15;
  Result.Add(' - ' + 'Family Code: ' + IntToStr(b));
  b := Hi(_eax) shr 4;
  Result.Add(' - ' + 'Processor Type: ' + IntToStr(b));
  b := Lo((_eax shr 16)) and 15;
  Result.Add(' - ' + 'Extended Model: ' + IntToStr(b));
  b := Lo((_eax shr 20));
  Result.Add(' - ' + 'Extended Family: ' + IntToStr(b));
  b := Lo(_ebx);
  Result.Add(' - ' + 'Brand ID: ' + IntToStr(b));
  b := Hi(_ebx);
  Result.Add(' - ' + 'Chunks: ' + IntToStr(b));
  b := Lo(_ebx shr 16);
  Result.Add(' - ' + 'Count: ' + IntToStr(b));
  b := Hi(_ebx shr 16);
  Result.Add(' - ' + 'APIC ID: ' + IntToStr(b));
  if (_edx and $40000) = $40000 then // is serial number enabled?
    Result.Add(' - ' + 'Serial Number ' + 'Enabled')
  else
    Result.Add(' - ' + 'Serial Number ' + 'Disabled');
  s := IntToHex(_eax, 8);
  asm // determine the serial number
    mov eax, 3
    db $0F, $A2
    mov _ecx, ecx
    mov _edx, edx
  end;
  s1 := IntToHex(_edx, 8);
  s2 := IntToHex(_ecx, 8);
  Insert('-', s, 5);
  Insert('-', s1, 5);
  Insert('-', s2, 5);
  Result.Add(' - ' + 'Serial Number: ' + s + '-' + s1 + '-' + s2);
  asm
    mov eax, 1
    db $0F, $A2
    mov _edx, edx
  end;
  if (_edx and $800000) = $800000 then
    Result.Add('MMX ' + 'Supported')
  else
    Result.Add('MMX ' + 'Not Supported');
  if (_edx and $01000000) = $01000000 then
    Result.Add('FXSAVE & FXRSTOR Instructions ' + 'Supported')
  else
    Result.Add('FXSAVE & FXRSTOR Instructions Not ' + 'Supported');
  if (_edx and $02000000) = $02000000 then
    Result.Add('SSE ' + 'Supported')
  else
    Result.Add('SSE ' + 'Not Supported');
  if (_edx and $04000000) = $04000000 then
    Result.Add('SSE2 ' + 'Supported')
  else
    Result.Add('SSE2 ' + 'Not Supported');
  asm // execute the extended CPUID inst.
    mov eax, $80000000 // sub. func call
    db $0F, $A2
    mov _eax, eax
  end;
  if _eax > $80000000 then // any other sub. funct avail. ?
  begin
    Result.Add('Extended CPUID: ' + 'Supported');
    Result.Add(' - Largest Function Supported: ' + IntToStr(_eax - $80000000));
    asm // get brand ID
      mov eax, $80000002
      db $0F
      db $A2
      mov _eax, eax
      mov _ebx, ebx
      mov _ecx, ecx
      mov _edx, edx
    end;
    s := '';
    s1 := '';
    s2 := '';
    s3 := '';
    for i := 0 to 3 do
    begin
      b := Lo(_eax);
      s3:= s3 + chr(b);
      b := Lo(_ebx);
      s := s + chr(b);
      b := Lo(_ecx);
      s1 := s1 + chr(b);
      b := Lo(_edx);
      s2 := s2 + chr(b);
      eax := _eax shr 8;
      _ebx := _ebx shr 8;
      _ecx := _ecx shr 8;
      _edx := _edx shr 8;
    end;
    s_all := s3 + s + s1 + s2;
    asm
      mov eax, $80000003
      db $0F
      db $A2
      mov _eax, eax
      mov _ebx, ebx
      mov _ecx, ecx
      mov _edx, edx
    end;
    s := '';
    s1 := '';
    s2 := '';
    s3 := '';
    for i := 0 to 3 do
    begin
      b := Lo(_eax);
      s3 := s3 + chr(b);
      b := Lo(_ebx);
      s := s + chr(b);
      b := Lo(_ecx);
      s1 := s1 + chr(b);
      b := Lo(_edx);
      s2 := s2 + chr(b);
      _eax := _eax shr 8;
      _ebx := _ebx shr 8;
      _ecx := _ecx shr 8;
      _edx := _edx shr 8;
    end;
    s_all := s_all + s3 + s + s1 + s2;
    asm
      mov eax, $80000004
      db $0F
      db $A2
      mov _eax, eax
      mov _ebx, ebx
      mov _ecx, ecx
      mov _edx, edx
    end;
    s := '';
    s1 := '';
    s2 := '';
    s3 := '';
    for i := 0 to 3 do
    begin
      b := Lo(_eax);
      s3 := s3 + chr(b);
      b := Lo(_ebx);
      s := s + chr(b);
      b := Lo(_ecx);
      s1 := s1 + chr(b);
      b := Lo(_edx);
      s2 := s2 + chr(b);
      _eax := _eax shr 8;
      _ebx := _ebx shr 8;
      _ecx := _ecx shr 8;
      _edx := _edx shr 8;
    end;
    Result.Add('Brand String: ' + '');
    if s2[Length(s2)] = #0 then setlength(s2, Length(s2) - 1);
    Result.Add('' + ' - ' + s_all + s3 + s + s1 + s2);
  end
  else
    Result.Add(' - Extended CPUID ' + 'Not Supported.');
end;

Tidak ada komentar:

Posting Komentar