View Full Version : خواندن اطلاعات از bios
majid2004
جمعه 03 خرداد 1387, 11:21 صبح
با سلام خدمت همه
كسي از دوستان هست كه بتونه يه تكه برنامه يا كد دلفي به من بده كه بشه براي بدست آوردن شماره سريال bios كه معمولا توي چند كيلو بايت اول اونه ازش استفاده كرد ؟ ضمنا اين موضوع هم مهمه كه من مي خوام توي XP بشه اين كار رو كرد .
ممنون
babak_delphi
جمعه 03 خرداد 1387, 19:18 عصر
For a simple copy-protection scheme we need to know whether the machine that is executing our application is the one where it was installed. We can save the machine data in the Windows Registry when the application is installed or executed for the first time, and then every time the application gets executed we compare the machine data with the one we saved to see if they are the same or not.
But, what machine data should we use and how do we get it? In a past issue we showed how to get the volume serial number of a logical disk drive, but normally this is not satisfying for a software developer since this number can be changed.
A better solution could be using the BIOS serial number. BIOS stands for Basic Input/Output System and basically is a chip on the motherboard of the PC that contains the initialization program of the PC (everything until the load of the boot sector of the hard disk or other boot device) and some basic device-access routines. Unfortunately, different BIOS manufacturers have placed the serial numbers and other BIOS information in different memory locations, so the code you can usually find in the net to get this information might work with some machines but not with others. However, most (if not all) BIOS manufacturers have placed the information somewhere in the last 8 Kb of the first Mb of memory, i.e. in the address space from $000FE000 to $000FFFFF. Assuming that "s" is a string variable, the following code would store these 8 Kb in it:
SetString(s, PChar(Ptr($FE000)), $2000); // $2000 = 8196
We can take the last 64 Kb to be sure we are not missing anything:
SetString(s, PChar(Ptr($F0000)), $10000); // $10000 = 65536
The problem is that it's ill-advised to store "large volumes" of data in the Windows Registry. It would be better if we could restrict to 256 bytes or less using some hashing/checksum technique. For example we can use the SHA1 unit (and optionally the Base64 unit) introduced in the issue #17 of the Pascal Newsletter:
http://www.latiumsoftware.com/en/pascal/0017.php3
The code could look like the following:
uses SHA1, Base64;
function GetHashedBiosInfo: string;
var
SHA1Context: TSHA1Context;
SHA1Digest: TSHA1Digest;
begin
// Get the BIOS data
SetString(Result, PChar(Ptr($F0000)), $10000);
// Hash the string
SHA1Init(SHA1Context);
SHA1Update(SHA1Context, PChar(Result), Length(Result));
SHA1Final(SHA1Context, SHA1Digest);
SetString(Result, PChar(@SHA1Digest), sizeof(SHA1Digest));
// Return the hash string encoded in printable characters
Result := B64Encode(Result);
end;
This way we get a short string that we can save in the Windows Registry without any problems.
The full source code example corresponding to this article is available for download:
http://www.latiumsoftware.com/download/p0020.zip
The full source code example of this article is available for download:
http://www.latiumsoftware.com/download/p0020.zip
DISPLAYING BIOS INFORMATION
---------------------------
If we wanted to display the BIOS information we should parse the bytes to extract all null-terminated strings with ASCII printable characters at least 8-characters length, as it is done in the following function:
function GetBiosInfoAsText: string;
var
p, q: pchar;
begin
q := nil;
p := PChar(Ptr($FE000));
repeat
if q <> nil then begin
if not (p^ in [#10, #13, #32..#126, #169, #184]) then begin
if (p^ = #0) and (p - q >= 8) then begin
Result := Result + TrimRight(String(q)) + #13#10;
end;
q := nil;
end;
end else
if p^ in [#33..#126, #169, #184] then
q := p;
inc(p);
until p > PChar(Ptr($FFFFF));
Result := TrimRight(Result);
end;
Then we can use the return value for example to display it in a memo:
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Text := GetBiosInfoAsText;
end;
babak_delphi
جمعه 03 خرداد 1387, 19:20 عصر
http://www.delphi3000.com/articles/article_2194.asp?SK=bios
این هم آدرس برای دانلود مثال
من امتحان نکردم ولی سایت معتبریه
مهران موسوی
جمعه 03 خرداد 1387, 22:02 عصر
اين مثال در Windows XP جواب نميده ... قبلا امتحانش كرده بودم ... خودم هم قبلا گشتم ولي نمونه ي خاصي مشاهده نكردم .
majid2004
شنبه 04 خرداد 1387, 06:53 صبح
اين مثال در Windows XP جواب نميده ... قبلا امتحانش كرده بودم ... خودم هم قبلا گشتم ولي نمونه ي خاصي مشاهده نكردم .
بله همونطور كه مهران جان گفتند توي XP جواب نميده . منم اين كد رو داشتم و واسه همينم گفتم واسه XP مي خوام . به هر حال ممنون از لطف شما
B-Vedadian
شنبه 04 خرداد 1387, 08:14 صبح
برای دسترسی به اطلاعات Bios در XP از API استفاده کنید. تو MSDN دنبال GetSystemFirmwareTable بگردید (به بقیه توابع مربوطه به گرفتن اطلاعات سیستم هم توجه کنید، با نمکن)
etedali
شنبه 04 خرداد 1387, 11:15 صبح
http://www.delphi3000.com/articles/article_2763.asp
اینجا چند تا مثال داره برو ببین
majid2004
شنبه 04 خرداد 1387, 14:11 عصر
http://www.delphi3000.com/articles/article_2763.asp
اینجا چند تا مثال داره برو ببین
خييييييييييييلييييييييييي ممنونم
مطالعه مي كنم ببينم به دردم مي خوره . اگه نخورد باز مزاحم ميشم .
بازم ممنون
majid2004
یک شنبه 05 خرداد 1387, 08:24 صبح
سلام دوست عزيز (etedali)
من اين لينك رو ديدم اما برنامش كار نمي كرد و پر از error بود . شما خودتون باهاش كار كرديد ؟ من حدس مي زنم يه چيزي شايد بايد به ليست USES اضافه بشه ك ممنون ميشم از دوستان اگه راهنماييم كنند
majid2004
دوشنبه 06 خرداد 1387, 18:40 عصر
از دوستان كسي نيست كه لينكي كه آقاي etedali دادند رو ديده باشند و منو راهنمايي كنند ؟
B_YAGHOBI
سه شنبه 07 خرداد 1387, 00:07 صبح
در ويندوز Xp تنها را مورد استفاه WMI Service ميباشد :
function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var // These are all needed for the WMI querying process
Locator: ISWbemLocator;
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
SN: string;
begin
try
Locator := CoSWbemLocator.Create; // Create the Location object
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, TempObj, Value) = S_OK) do
begin
SObject := IUnknown(tempObj) as ISWBemObject;
SProp := SObject.Properties_.Item(wmiProperty, 0);
if VarIsNull(SProp.Get_Value) then
result := ''
else
begin
SN := SProp.Get_Value;
result := SN;
end;
end;
except // Trap any exceptions (Not having WMI installed will cause one!)
on exception do
result := '';
end;
end;
براي استفاده از كد فوق يونيتهاي WbemScripting_TLB, ActiveX, ComObj, UrlMon را uses كنيد
uses
WbemScripting_TLB, ActiveX, ComObj, UrlMon
مثال :
Caption := getWMIstring('','Win32_BIOS','SerialNumber');
Caption := getWMIstring('.','Win32_BIOS','Manufacturer');
Caption := getWMIstring('','Win32_ComputerSystemProduct','Nam e');
Caption := getWMIstring('','Win32_BIOS','Status');
Caption := getWMIstring('','Win32_BIOS','SMBIOSBIOSVERSION');
tmpstr := getWMIstring('','Win32_BIOS','ReleaseDate');
if tmpstr <> '' then
begin
Y:=Copy(tmpstr,0,4);
T:=Copy(tmpstr,5,2);
M:=Copy(tmpstr,7,2);
Caption:=M+'.'+T+'.'+Y;//tmpstr
end
else
Caption:='not available';
مهران موسوی
سه شنبه 07 خرداد 1387, 00:44 صبح
كامپوننتي رو كه پيوست كردين براي انجام چه كاري مناسب هست ... ميشه توضيح بديد ؟؟
ايا مثالهايي همراه با خودش نداره ؟؟ من كه دانلود كردم ولي چيزي نديم ؟؟!!
majid2004
سه شنبه 07 خرداد 1387, 08:52 صبح
در ويندوز Xp تنها را مورد استفاه WMI Service ميباشد :
function GetWMIstring (wmiHost, wmiClass, wmiProperty : string):string;
var // These are all needed for the WMI querying process
Locator: ISWbemLocator;
Services: ISWbemServices;
SObject: ISWbemObject;
ObjSet: ISWbemObjectSet;
SProp: ISWbemProperty;
Enum: IEnumVariant;
Value: Cardinal;
TempObj: OleVariant;
SN: string;
begin
try
Locator := CoSWbemLocator.Create; // Create the Location object
// Connect to the WMI service, with the root\cimv2 namespace
Services := Locator.ConnectServer(wmiHost, 'root\cimv2', '', '', '','', 0, nil);
ObjSet := Services.ExecQuery('SELECT * FROM '+wmiClass, 'WQL',
wbemFlagReturnImmediately and wbemFlagForwardOnly , nil);
Enum := (ObjSet._NewEnum) as IEnumVariant;
while (Enum.Next(1, TempObj, Value) = S_OK) do
begin
SObject := IUnknown(tempObj) as ISWBemObject;
SProp := SObject.Properties_.Item(wmiProperty, 0);
if VarIsNull(SProp.Get_Value) then
result := ''
else
begin
SN := SProp.Get_Value;
result := SN;
end;
end;
except // Trap any exceptions (Not having WMI installed will cause one!)
on exception do
result := '';
end;
end;
براي استفاده از كد فوق يونيتهاي WbemScripting_TLB, ActiveX, ComObj, UrlMon را uses كنيد
uses
WbemScripting_TLB, ActiveX, ComObj, UrlMon
مثال :
Caption := getWMIstring('','Win32_BIOS','SerialNumber');
Caption := getWMIstring('.','Win32_BIOS','Manufacturer');
Caption := getWMIstring('','Win32_ComputerSystemProduct','Nam e');
Caption := getWMIstring('','Win32_BIOS','Status');
Caption := getWMIstring('','Win32_BIOS','SMBIOSBIOSVERSION');
tmpstr := getWMIstring('','Win32_BIOS','ReleaseDate');
if tmpstr <> '' then
begin
Y:=Copy(tmpstr,0,4);
T:=Copy(tmpstr,5,2);
M:=Copy(tmpstr,7,2);
Caption:=M+'.'+T+'.'+Y;//tmpstr
end
else
Caption:='not available';
با تشكر از شما دوست عزيز كدها رو گرفتم . روش فوق العاده اي بود و خيلي خوب جواب داد . با تشكر فراوان مشكلم رفع شد .
B_YAGHOBI
سه شنبه 07 خرداد 1387, 15:58 عصر
كامپوننتي رو كه پيوست كردين براي انجام چه كاري مناسب هست ... ميشه توضيح بديد ؟؟
ايا مثالهايي همراه با خودش نداره ؟؟ من كه دانلود كردم ولي چيزي نديم ؟؟!!
اين Import از اكتيو ايكس WMI Script مايكروسافت ميباشد.
بايد در سورس برنامه شما uses شود.
يك مثال هم قرار دادم.
مهران موسوی
سه شنبه 07 خرداد 1387, 17:46 عصر
سلام .. روش خوبي هست ولي بايد بگم روي همه ي سيستمها از جمله سيستم من كار نميكنه ... ( متاسفانه :اشتباه: )
Felony
سه شنبه 07 خرداد 1387, 18:53 عصر
بله روی سیستم من هم کار نکرد
مهران موسوی
چهارشنبه 08 خرداد 1387, 13:11 عصر
اصلا روش مطمئني نيست .. استفاده از اون در كارهاي جدي يك ريسك هست ... بهتره به همون HDD Serial راضي باشيد چون مطمئنتر هست ... البته اگه به اسمبلي تسلط داشته باشيد نمونه هايي وجود داره ...
majid2004
پنج شنبه 09 خرداد 1387, 11:55 صبح
من كه باهاش كار كردم . هم روي لپتاپم و هم روي PC جواب داد . اميدوارم كه همه جا جواب بده .
بهمن بهار
دوشنبه 31 تیر 1387, 09:39 صبح
سلام سريال هارد خيلي هم قابل اطمينان نيست و براي برنامه نويس بيشتر دردسر ميسازه و رفت و آمدهاي بيجا درست ميكنه من قبلا اين كار را كردم و نتيجه اش را هم ديدم
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.