Delphi windows serial number

Delphi windows serial number

Member Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору Где-то я это уже видел. У тебя хобби, чтоли?
Читай мануал по win api Всего записей: 243 | Зарегистр. 16-12-2004 | Отправлено: 00:01 22-02-2007

nstankovsky

Newbie

Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Необходимо защитить базу данных, приложения, развернутых на сервере SQL 2005, от возможности переноса на другой компьютер, даже с помощью создания образов дисков, для этого, по всей видимости нужно привязать сервер к серийным номерам физических устройств, вот как это сделать — проблема. Если есть возможные варианты, решения — подскажите, буду очень благодарен.
Всего записей: 29 | Зарегистр. 15-02-2007 | Отправлено: 09:58 22-02-2007
VladimirV111

Newbie

Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору серийный номер процессора можешь получить из следующего кода

Код:

//Sometimes u need to know some information about the CPU
//like: brand id, factory speed, wich instruction set supported etc.
//If so, than u can use this code.
//2002 by -=LTi=-

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

type
Tfrm_main = class(TForm)
img_info: TImage;
procedure FormShow(Sender: TObject);
private
< Private declarations >
public
< Public declarations >
procedure info(s1, s2: string);
end;

var
frm_main: Tfrm_main;
gn_speed_y: Integer;
gn_text_y: Integer;
const
gn_speed_x: Integer = 8;
gn_text_x: Integer = 15;
gl_start: Boolean = True;

procedure Tfrm_main.FormShow(Sender: TObject);
var
_eax, _ebx, _ecx, _edx: Longword;
i: Integer;
b: Byte;
b1: Word;
s, s1, s2, s3, s_all: string;
begin
//Set the startup colour of the image
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.FillRect(rect(0, 0, img_info.Width, img_info.Height));

gn_text_y := 5; //position of the 1st text

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;
info(‘CPU’, »);
info(‘ — ‘ + ‘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;
//06B1
//|0000| |0000 0000| |0000| |00| |00| |0110| |1011| |0001|
b := lo(_eax) and 15;
info(‘ — ‘ + ‘Stepping ID: ‘, IntToStr(b));
b := lo(_eax) shr 4;
info(‘ — ‘ + ‘Model Number: ‘, IntToHex(b, 1));
b := hi(_eax) and 15;
info(‘ — ‘ + ‘Family Code: ‘, IntToStr(b));
b := hi(_eax) shr 4;
info(‘ — ‘ + ‘Processor Type: ‘, IntToStr(b));
//31. 28. 27. 24. 23. 20. 19. 16.
// 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
b := lo((_eax shr 16)) and 15;
info(‘ — ‘ + ‘Extended Model: ‘, IntToStr(b));

b := lo((_eax shr 20));
info(‘ — ‘ + ‘Extended Family: ‘, IntToStr(b));

b := lo(_ebx);
info(‘ — ‘ + ‘Brand ID: ‘, IntToStr(b));
b := hi(_ebx);
info(‘ — ‘ + ‘Chunks: ‘, IntToStr(b));
b := lo(_ebx shr 16);
info(‘ — ‘ + ‘Count: ‘, IntToStr(b));
b := hi(_ebx shr 16);
info(‘ — ‘ + ‘APIC ID: ‘, IntToStr(b));

//Bit 18 =? 1 //is serial number enabled?
if (_edx and $40000) = $40000 then
info(‘ — ‘ + ‘Serial Number ‘, ‘Enabled’)
else
info(‘ — ‘ + ‘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);
info(‘ — ‘ + ‘Serial Number: ‘, s + ‘-‘ + s1 + ‘-‘ + s2);

asm
mov eax,1
db $0F,$A2
mov _edx,edx
end;
info(», »);
//Bit 23 =? 1
if (_edx and $800000) = $800000 then
info(‘MMX ‘, ‘Supported’)
else
info(‘MMX ‘, ‘Not Supported’);

//Bit 25 =? 1
if (_edx and $02000000) = $02000000 then
info(‘SSE ‘, ‘Supported’)
else
info(‘SSE ‘, ‘Not Supported’);

//Bit 26 =? 1
if (_edx and $04000000) = $04000000 then
info(‘SSE2 ‘, ‘Supported’)
else
info(‘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
info(‘Extended CPUID: ‘, ‘Supported’);
info(‘ — 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;
info(‘Brand String: ‘, »);
if s2[Length(s2)] = #0 then setlength(s2, Length(s2) — 1);
info(», ‘ — ‘ + s_all + s3 + s + s1 + s2);
end
else
info(‘ — Extended CPUID ‘, ‘Not Supported.’);
end;

procedure Tfrm_main.info(s1, s2: string);
begin
if s1 <> » then
begin
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.Font.Color := clyellow;
img_info.Canvas.TextOut(gn_text_x, gn_text_y, s1);
end;
if s2 <> » then
begin
img_info.Canvas.Brush.Color := clblue;
img_info.Canvas.Font.Color := clWhite;
img_info.Canvas.TextOut(gn_text_x + img_info.Canvas.TextWidth(s1), gn_text_y, s2);
end;
Inc(gn_text_y, 13);
end;

Добавлено:
серийный номер BIOS можно получить следующим образом:

Зависимости:
Автор: Gua, fbsdd@ukr.net, ICQ:141585495, Simferopol
Copyright:
Дата: 03 мая 2002 г.
***************************************************** >

function GetBiosNumber: string;
begin
result := string(pchar(ptr($FEC71)));
end;

Всего записей: 8 | Зарегистр. 18-02-2007 | Отправлено: 08:51 25-02-2007
VladimirVladim

Newbie

Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Серийный номер тома можно получить следующим образом:

Код:

function GetHardDiskSerial(const DriveLetter: Char): string;
var
NotUsed: DWORD;
VolumeFlags: DWORD;
VolumeInfo: array[0..MAX_PATH] of Char;
VolumeSerialNumber: DWORD;
begin
GetVolumeInformation(PChar(DriveLetter + ‘:\’),
nil, SizeOf(VolumeInfo), @VolumeSerialNumber, NotUsed,
VolumeFlags, nil, 0);
Result := Format(‘Label = %s VolSer = %8.8X’,
[VolumeInfo, VolumeSerialNumber])
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(GetHardDiskSerial(‘c’));
end;

А вот серийный номер физического жесткого диска — гораздо сложнее. Для этого нужен низкоуровневый драйвер.

Всего записей: 1 | Зарегистр. 25-02-2007 | Отправлено: 09:05 25-02-2007
nstankovsky

Newbie

Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору Спасибо за ответы.
Дело в том, что функция API GetVolumeInformation — определяет номер логического диска,
а мне необходимо — получить номер физического диска. Я пробовал переносить образы диска
на другой компьютер и при переносе логические диски на новом компе получали номера
старого компа, т.ч. к этим данным нельзя привязывать защиту программы.
Но я попробовал использовать код модуля IdeInfo2 (ссылки на него имеются во многих местах) и у меня вроде получилось.

При определении номера BIOS происходит обращение к памяти по адресу $FEC71, а в не
16-ричных ОС этот адрес «закрыт» и поэтому эта функция не работает.

Я сейчас попробую код по определению номера процессора и о результатах отпишу.

How to generate unique serial number of machine in Delphi?

I have question how to generate unique serial number of machine in Delphi? I tried to do this using the ID the motherboard or processor, but unfortunately it’s unfortunately supported. Partition serial numbers, etc. fall off, because it is changing after the formatted. I’m looking for something that doesn’t change after the formatted. Has anyone any idea?

7 Answers 7

Inside JCL library, there are several functions very usefull for this topic:

What you’re after is actually some sort of «hardware fingerprint», not an «serial number». The problem with this approach is that it’s not 100% reliable. Proof: Microsoft didn’t manage to find a way to properly limit OEM software to any single computer, you can actually re-install a OEM license on a new computer after a while! Once you agree there can’t be a perfect solution you may look at your options and try getting something that’s good enough.

For my applications I’m creating a fingerprint based on info returned by GetSystemInfo, GetVolumeInformation and (for the ‘C:’ partition) and a selection of registry keys from HKLM\HARDWARE (lots of registry keys actually, everything but usb, keyboard and mouse stuff). I’m reading hardware information from the registry because a Windows application can’t really access hardware directly (DOS-style approaches can’t work), and because I don’t have time to figure out ways to determine hardware-related information for many different devices.

My approach has the following disadvantages:

  • Uses the partition serial number, as set up by Format. An format would clearly change the fingerprint.
  • Uses information about the installed drivers. Updating an driver might actually change the fingerprint! Moving a card from one PCI port to an other might change the fingerprint.

None the less, even with all of this changing information taken into account, I get collisions: Something like 1/1000 computers! There are several factors at work here:

  • Big OEM build many computers using the same hardware. They also clone HDD’s in order to speed up software installation so different PC’s might get the same partition serial number.
  • I’m building a very short hash from all that information, short enough so people can read it to me on the phone without too many mistakes.

This system works for me, but it will not work for you if you expect to re-identify computers once they’re reinstalled.

Уникальный идентификатор (Hardware ID)

Уважаемые программисты подскажите как можно составить уникальный идентификатор компьютера, точнее из чего — из ID/SerialNumber каких устройств (мат плата, процессор, жесткий диск и т.д.) можно составить уникальный идентификатор?

З.Ы. MAC-адрес не предлагать

uses
ActiveX ,
Windows , Messages , SysUtils , Variants , Classes , Graphics , Controls , Forms ,
Dialogs , StdCtrls ;

type
TForm1 = class( TForm )
Memo1 : TMemo ;
procedure FormCreate ( Sender : TObject );
private
< Private declarations >
public
< Public declarations >
end ;

var
Form1 : TForm1 ;

procedure TForm1 . FormCreate ( Sender : TObject );
var
guid : TGUID ;
i : Integer ;
begin
for i := 1 to 255 do
begin
CoCreateGuid ( guid );
Memo1 . Lines . Add ( GUIDToString ( guid ));
end ;
end ;

uses
ActiveX ,
Windows , Messages , SysUtils , Variants , Classes , Graphics , Controls , Forms ,
Dialogs , StdCtrls ;

type
TForm1 = class( TForm )
Memo1 : TMemo ;
procedure FormCreate ( Sender : TObject );
private
< Private declarations >
public
< Public declarations >
end ;

var
Form1 : TForm1 ;

procedure TForm1 . FormCreate ( Sender : TObject );
var
guid : TGUID ;
i : Integer ;
begin
for i := 1 to 255 do
begin
CoCreateGuid ( guid );
Memo1 . Lines . Add ( GUIDToString ( guid ));
end ;
end ;

GUID не подходит в качестве Harware ID, т.к. он меняется из раза в раз. Где-то читал что для его генерации используется время.

Далее, можно от полученного MD5 «отрезать» половину (или вырезать символы через один) и юзать, подобрать такой hash будет невозможно

P.S. MD5 Unit прилагается во вложении.

Вложения

md5.zip (5.9 Кбайт, 251 просмотров)

__________________
Коли навчався в школі я — в мені росли мозгЫ. КудИж вони поділися? гы-гы гы-гы гы-гы.


ICQ: 593977748
Nick: Marvel

Спасибо за код, но у меня несколько вопросов:

  1. Разве читать инфу из реестра это есть хорошо? Она же может быть легко изменена.
  2. GetVolumeInformation — получает серийный номер логического диска, насколько я знаю, он не обладает свойством уникальности, в отличие от номера физического диска
  3. про MD5 Hash еще не разбирал, но разве хеширование (иногда) не дает одинаковые результаты при разных входных сообщениях? Т.е. не будут ли два разных компа с одинаковыми HardwareID (а тем более если отрезать от полученного хеща половину или брать через букву)?
Читайте также:  Почему вместо букв вопросительные знаки windows 10
Оцените статью