首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

取得主機板 BIOS 資訊完整方案:序列號、Award 密碼、完整傾印、日期讀取

     編輯:Delphi

方案一:SHA1 雜湊取得唯一 BIOS 指紋(防偽/授權綁定)

uses SHA1, Base64;

function GetHashedBIOSInfo: String;
var
  Ctx: TSHA1Context;
  Dig: TSHA1Digest;
begin
  SetString(Result, PChar(Ptr($F0000)), $10000); // 讀取 F000:0000 - F000:FFFF
  SHA1Init(Ctx);
  SHA1Update(Ctx, PChar(Result), Length(Result));
  SHA1Final(Ctx, Dig);
  SetString(Result, PChar(@Dig), SizeOf(Dig));
  Result := B64Encode(Result); // 可列印字元編碼
end;

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
          Result := Result + TrimRight(String(Q)) + #13#10;
        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;

方案二:讀取 Award BIOS 密碼(僅 Win9x,需 CMOS 埠存取)

unit AwardBIOS;
interface uses Windows, SysUtils;
function GetAwardBIOSPassword: String;
implementation
function CalcPossiblePassword(Value: Word): String;
var I: Byte; C: Char; S: String[8];
begin
  I := 0;
  while Value <> 0 do begin
    Inc(I);
    if Value < $263 then begin
      if Value < $80 then S[I] := Char(Value)
      else if Value < $B0 then S[I] := Char(Value and $77)
      else if Value < $11D then S[I] := Char($30 or (Value and $0F))
      else if Value < $114 then begin
        S[I] := Char($64 or (Value and $0F));
        if S[I] < '0' then S[I] := Char(Byte(S[I]) + 8);
      end
      else if Value < $1C2 then S[I] := Char($70 or (Value and $03))
      else if Value < $1E4 then S[I] := Char($30 or (Value and $03))
      else begin
        S[I] := Char($70 or (Value and $0F));
        if S[I] > 'z' then S[I] := Char(Byte(S[I]) - 8);
      end;
    end else
      S[I] := Char($30 or (Value and $03));
    Value := (Value - Byte(S[I])) shr 2;
  end;
  S[0] := Char(I);
  Value := I shr 1;
  while Value < I do begin
    C := S[Byte(S[0]) - I + 1];
    S[Byte(S[0]) - I + 1] := S[I];
    S[I] := C;
    Dec(I);
  end;
  Result := S;
end;

function ReadCMOS(Offset: Byte): Byte;
var V: Byte;
begin
  asm
    xor ax, ax
    mov al, Offset
    out 70h, al
    in al, 71h
    mov V, al
  end;
  Result := V;
end;

function GetAwardBIOSPassword: String;
var SuperPW, UserPW: Word;
begin
  if Win32Platform <> VER_PLATFORM_WIN32_NT then begin
    PChar(@SuperPW)[0] := Char(ReadCMOS($1C));
    PChar(@SuperPW)[1] := Char(ReadCMOS($1D));
    PChar(@UserPW)[0] := Char(ReadCMOS($64));
    PChar(@UserPW)[1] := Char(ReadCMOS($65));
    Result := '超級用戶密碼: ' + CalcPossiblePassword(SuperPW) + #13#10 +
              '用戶密碼: ' + CalcPossiblePassword(UserPW);
  end else
    Result := 'NT 系統無法讀取 CMOS 密碼';
end;
end.

方案三:完整 BIOS ROM 傾印(跨平台:Win9x 直接讀取、NT 透過 \Device\PhysicalMemory)

unit BIOSHelp;
{ 完整單元碼略,核心 API: }
function ReadRomBIOS(var Dump: TRomBIOSDump; Method: TReadRomBIOSMethod; Timeout: DWord = INFINITE): Boolean;
{ Method: rrbmAutomatic(自動)、rrbmGeneric(16bit COM)、rrbmMemory(Win9x 記憶體)、rrbmPhysical(NT 物理記憶體) }
{ 輔助函數: GetRomBIOSString/DWord/Word/Byte/Buffer/LongLong }
end.

使用範例:

var Dump: TRomBIOSDump; I: Integer;
begin
  ReadRomBIOS(Dump, rrbmAutomatic);
  for I := 0 to High(Dump) do
    Memo1.Lines.Add(IntToHex(Dump[I], 2));
end;

方案四:讀取 BIOS 日期字串

function GetBIOSDate1: String;
var Buf: array[0..8] of Char; N: DWord;
begin
  ReadProcessMemory(GetCurrentProcess, Ptr($FFFF5), @Buf, 8, N);
  Buf[8] := #0;
  Result := StrPas(Buf);
end;

function GetBIOSDate2: String;
begin
  Result := String(PChar(Ptr($FFFF5)));
end;

適用場景對照

需求推薦方案平台限制
軟體授權綁定唯一硬體指紋方案一 (SHA1 指紋)全平台
維修/管理需讀取 BIOS 設定密碼方案二 (Award CMOS)僅 Win9x,非 NT
完整 BIOS 程式碼分析/備份方案三 (ROM 傾印)全平台 (自動選擇方法)
快速取得 BIOS 發布日期方案四 (日期字串)Win9x/2K 推測適用,需權限

注意事項

  • 直接記憶體讀取 (Ptr($F0000) 等) 在受保護模式下可能需特殊權限或導致異常,方案三封裝了平台差異最穩健。
  • CMOS 埠存取 (70h/71h) 僅在實模式/DOS/Win9x VDM 有效,NT 內核禁止使用者模式存取。
  • BIOS 記憶體映射位址因主機板而異,上述位址為傳統 PC 相容標準區域。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved