1、读取主板序列号
2、AWard Bios密码读取
3、读取BIOS信息
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)4、获取BIOS日期信息
=========================================
1、读取主板序列号
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;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;procedure TForm1.FormCreate(Sender: TObject);begin Memo1.Lines.Text := GetBiosInfoAsText;end;
==========================================
2、AWard Bios密码读取(应该是jingtao的文章,但是ID没有记录)
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)Unit AwardBiosPas;//Write by lovejingtao//http://www.138soft.cominterfaceuses windows,SysUtils;function My_GetBiosPassword:String;implementationfunction CalcPossiblePassword(PasswordValue: WORD): string;varI: BYTE;C: CHAR;S: string[8];beginI := 0;while PasswordValue 0 do begin Inc(I); if $263 PasswordValue then begin if $80 PasswordValue then S[I] := CHAR(PasswordValue) else if $B0 PasswordValue then S[I] := CHAR(PasswordValue and $77) else if $11D PasswordValue then S[I] := CHAR($30 or (PasswordValue and $0F)) else if $114 PasswordValue then begin S[I] := CHAR($64 or (PasswordValue and $0F)); if '0' S[I] then S[I] := CHAR(BYTE(S[I]) + 8); end else if $1C2 PasswordValue then S[I] := CHAR($70 or (PasswordValue and $03)) else if $1E4 PasswordValue then S[I] := CHAR($30 or (PasswordValue and $03)) else begin S[I] := CHAR($70 or (PasswordValue and $0F)); if 'z' S[I] then S[I] := CHAR(BYTE(S[I]) - 8); end; end else S[I] := CHAR($30 or (PasswordValue and $3)); PasswordValue := (PasswordValue - BYTE(S[I])) shr 2; end;S[0] := CHAR(I);PasswordValue := I shr 1;while PasswordValue I do begin {this is to do because award starts calculating with the last letter} C := S[BYTE(S[0]) - I + 1]; S[BYTE(S[0]) - I + 1] := S[I]; S[I] := C; Dec(I); end;CalcPossiblePassword := S;end;function readcmos(off: byte): byte;varvalue: byte;beginasm xor ax, ax mov al, off out 70h, al in al, 71h mov value, alend;readcmos := value;end;function My_GetBiosPassword:String;varsuperpw, userpw: word;S:String;beginif Win32Platform VER_PLATFORM_WIN32_NT then //不是NTbeginpchar(@superpw)[0] := char(readcmos($1C));pchar(@superpw)[1] := char(readcmos($1D));pchar(@userpw)[0] := char(readcmos($64));pchar(@userpw)[1] := char(readcmos($65));S:='超级用户密码为:'+CalcPossiblePassword(superpw)+#13+'用户密码为:'+CalcPossiblePassword(userpw);Result:=S;endelseResult:='用户系统为NT,无法获取BISO密码!';end;end.
==========================================
3、读取BIOS信息
(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/){程序使用Windows 95/2000平台,自动检测系统类型,然后进行不同调用}
uses BiosHelp;procedure TForm1.Button1Click(Sender: TObject);varDump: TRomBiosDump;i: Integer;beginReadRomBios(Dump, rrbmAutomatic);for i := 1 to $000FFFFF - $000F0000 - 1 do Memo1.Lines.Add(IntToHex(Dump[i + $000FFFFF], 2));end;(******************************************************************************** ** BIOS Help - read ROM BIOS on Windows 95/98/SE/ME/NT/2K/XP ** ** Copyright (C) 2001, Nico Bendlin (nico@bendlin.de) ** ** Compiler: Delphi 4.03/5.01/6.00 ** Version: 1.03, 2001-09-02 ** ********************************************************************************){ postum scriptum: sorry for the bad english, i wrote it in a hurry }unit BiosHelp;{$ALIGN ON}{$MINENUMSIZE 4}interfaceusesWindows;typePRomBiosDump = ^TRomBiosDump;TRomBiosDump = array[$000F0000..$000FFFFF] of Byte;typeTReadRomBiosMethod = ( rrbmAutomatic, { Autodetect OS type and use proper method } rrbmGeneric, { Use 16-bit COM program to dump the BIOS } rrbmMemory, { Read from memory (Win9x) } rrbmPhysical { Read from physical memory object (WinNT) } );function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;Timeout: DWORD = INFINITE): Boolean;function GetRomBiosBuffer(const Dump: TRomBiosDump; Address: Pointer;var Buffer; BufferSize: Cardinal): Cardinal;function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer): string;function GetRomBiosLongLong(const Dump: TRomBiosDump; Address: Pointer): LONGLONG;function GetRomBiosDWord(const Dump: TRomBiosDump; Address: Pointer): DWORD;function GetRomBiosWord(const Dump: TRomBiosDump; Address: Pointer): Word;function GetRomBiosByte(const Dump: TRomBiosDump; Address: Pointer): Byte;implementation{################################################################################ ## GENERIC METHOD ## ## Create an temporary folder, save an 16bit COM program (RomDump.com) into it, ## execute program redirected to an file (Rom.dmp, RomDump.com simply dumps the ## memory range F000:0000-F000:FFFF to STDOUT), read dump file into the buffer, ## and finally cleanup all temporary files and directories. ## ## (the function RomDumpCode is x86 specific, which i wrote to generate 16-bit ## code with the help of the 23-bit Delphi compiler, never try to execute the ## pseudo-code in your program! it will not work in 32-bit protected mode) ## ################################################################################}{ *INTERNAL* - Pseudo 16-bit code }typePRomDumpCodeInfo = ^TRomDumpCodeInfo;TRomDumpCodeInfo = (rdciStart, rdciEnd, rdciSize);function _RomDumpCode(Info: TRomDumpCodeInfo): Pointer;varCodeStart: Pointer;CodeEnd: Pointer;beginasm JMP @@End { *BEGIN* 16-bit code } { -- never use it in your program! -- } { COM which writes ROM-BIOS to StdOut }@@Start: { Dump F000:0000-F000:FFFE } XOR eDX, eDX // DS = 0xF000 ; Data segment MOV DH, 0F0h MOV DS, eDX XOR eDX, eDX // DX = 0x0000 ; Data offset XOR eCX, eCX // CX = 0xFFFF ; Data length DEC eCX XOR eBX, eBX // BX = 0x0001 ; STDOUT (file handle) INC eBX MOV AH, 40h // DosCall(0x40) ; INT21, DOS_WRITE_TO_HANDLE INT 21h JC @@Exit // On error exit ; AL = Error code { Dump F000:FFFF } XOR eDX, eDX // DS = 0xF000 ; Data segment MOV DH, 0F0h MOV DS, eDX XOR eDX, eDX // DX = 0xFFFF ; Data offset DEC eDX XOR eCX, eCX // CX = 0x0001 ; Data length INC eCX MOV eBX, eCX // BX = 0x0001 ; STDOUT (file handle) MOV AH, 40h // DosCall(0x40) ; INT21, DOS_WRITE_TO_HANDLE INT 21h JC @@Exit // On error exit ; AL = Error code MOV AL, 0 // no error ; AL = 0@@Exit: MOV AH, 4Ch // DosCall(0x4C) ; INT21, DOS_TERMINATE_EXE INT 21h@@End: { *END* 16-bit code } MOV CodeStart, OFFSET @@Start MOV CodeEnd, OFFSET @@Endend;case Info of rdciStart: Result := CodeStart; rdciEnd: Result := CodeEnd; rdciSize: Result := Pointer(Cardinal(CodeEnd) - Cardinal(CodeStart));else Result := nil;end;end;{ *INTERNAL* - Save 16-bit code to file }function _RomDumpCodeToFile(const Filename: string): Boolean;varComFile: THandle;Size: Cardinal;beginResult := False;ComFile := CreateFile(PChar(Filename), GENERIC_WRITE, FILE_SHARE_READ, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);if ComFile INVALID_HANDLE_VALUE thentry Result := WriteFile(ComFile, _RomDumpCode(rdciStart)^, Cardinal(_RomDumpCode(rdciSize)), Size, nil) and (Size = Cardinal(_RomDumpCode(rdciSize))); if not Result then DeleteFile(PChar(Filename));finally CloseHandle(ComFile);end;end;{ *INTERNAL* - Execute 16-bit code redirected to file }function _RomDumpCodeExecute(const Com, Dmp: string; Timeout: DWORD): Boolean;varComSpec: string;si: TStartupInfo;pi: TProcessInformation;beginResult := False;SetLength(ComSpec, MAX_PATH);SetLength(ComSpec, GetEnvironmentVariable('ComSpec', PChar(@ComSpec[1]), MAX_PATH));if Length(ComSpec) 0 thenbegin FillChar(si, SizeOf(TStartupInfo), 0); si.cb := SizeOf(TStartupInfo); si.dwFlags := STARTF_USESHOWWINDOW; si.wShowWindow := SW_HIDE; if CreateProcess(nil, PChar(ComSpec + ' /C ' + Com + ' ' + Dmp), nil, nil, False, CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP, nil, nil, si, pi) then try Result := WaitForSingleObject(pi.hProcess, Timeout) WAIT_TIMEOUT; finally CloseHandle(pi.hProcess); CloseHandle(pi.hThread); end;end;end;function DirectoryExists(const Dir: string): Boolean;varAttr: DWORD;beginAttr := GetFileAttributes(PChar(Dir));Result := (Attr $FFFFFFFF) and (Attr and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY);end;{ Get BIOS dump the generic way }function ReadRomBios16(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;constTempSub = '~RomDmp';ComName = 'RomDump.com';DmpName = 'Rom.dmp';varTempPath: string;TempDir: string;TempIdx: Integer;TempIdxStr: string;ComFile: string;DmpFile: string;DmpHandle: THandle;Written: DWORD;beginResult := False;SetLength(TempPath, MAX_PATH);SetLength(TempPath, GetTempPath(MAX_PATH, PChar(@TempPath[1])));if Length(TempPath) 0 thenbegin if (TempPath[Length(TempPath)] '') then TempPath := TempPath + ''; TempIdx := 0; repeat Inc(TempIdx); Str(TempIdx, TempIdxStr); TempDir := TempPath + TempSub + TempIdxStr; until not DirectoryExists(TempDir); if CreateDirectory(PChar(TempDir), nil) then try TempDir := TempDir + ''; ComFile := TempDir + ComName; DmpFile := TempDir + DmpName; if _RomDumpCodeToFile(ComFile) then try if _RomDumpCodeExecute(ComFile, DmpFile, Timeout) then begin DmpHandle := CreateFile(PChar(DmpFile), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0); if DmpHandle INVALID_HANDLE_VALUE then try FillChar(Buffer, SizeOf(TRomBiosDump), 0); Result := ReadFile(DmpHandle, Buffer, SizeOf(TRomBiosDump), Written, nil) and (Written = SizeOf(TRomBiosDump)); finally CloseHandle(DmpHandle); end; end; finally DeleteFile(PChar(DmpFile)); DeleteFile(PChar(ComFile)); end; finally RemoveDirectory(PChar(TempDir)); end;end;end;{################################################################################ ## DIRECT METHOD (Win9x) ## ## Due to the fact that Windows 95/98/ME maps the BIOS into every Win32 process ## for read access it is very simple to fill the buffer from memory. ## ################################################################################}function ReadRomBios9x(var Buffer: TRomBiosDump): Boolean;beginResult := False;try FillChar(Buffer, SizeOf(TRomBiosDump), 0); Move(Pointer(Low(TRomBiosDump))^, Buffer, SizeOf(TRomBiosDump)); Result := True;except // ignore exceptionsendend;{################################################################################ ## PHYSICAL MEMORY METHOD (WinNT) ## ## On Windows NT the ROM BIOS is only available through the named kernel object ## 'DevicePhysicalMemory'. Because it is impossible to open kernel objects in ## user mode with standard Win32 API functions we make use of NT's nativeAPI in ## NtDll.dll ("NT-Layer") namely ZwOpenSection. ## ## (note: mostly there are two versions of every function ZwXxx and NtXxx. The ## only difference in kernel mode is that the NtXxx version works in conside- ## ration to security while ZwXxx not. But in user mode both work like NtXxx.) ## ## At first the section is opened with ZwOpenSection. Normally we would proceed ## ZwMapViewOfSection, ZwUnmapViewOfSection, and NtClose. But the functions are ## more complex and there is no needing for it. With the handle (because we are ## in the "very simple" user mode =) we now use MapViewOfFile, UnmapViewOfFile, ## and CloseHandle to map an memory window (the ROM BIOS) into our process. ## ## Due to the fact that ZwOpenSection returns NT error-codes in case of failure ## we have to translate it to an Win32 error-code (RtlNtStatusToDosError). ## All NT specific functions are dynamically loaded -- because the applications ## should start on Win9x systems =) ## ################################################################################}{ For more information see Windows 2000/XP DDK }{ It works on Windows NT 4.0 too, use NtDll.dll }typeNTSTATUS = Integer;constSTATUS_SUCCESS = NTSTATUS(0);STATUS_INVALID_HANDLE = NTSTATUS($C0000008);STATUS_ACCESS_DENIED = NTSTATUS($C0000022);typePUnicodeString = ^TUnicodeString;TUnicodeString = packed record Length: Word; MaximumLength: Word; Buffer: PWideChar;end;constOBJ_INHERIT = $00000002;OBJ_PERMANENT = $00000010;OBJ_EXCLUSIVE = $00000020;OBJ_CASE_INSENSITIVE = $00000040;OBJ_OPENIF = $00000080;OBJ_OPENLINK = $00000100;OBJ_KERNEL_HANDLE = $00000200;OBJ_VALID_ATTRIBUTES = $000003F2;typePObjectAttributes = ^TObjectAttributes;TObjectAttributes = record Length: ULONG; RootDirectory: THandle; ObjectName: PUnicodeString; Attributes: ULONG; SecurityDescriptor: PSecurityDescriptor; SecurityQualityOfService: PSecurityQualityOfService;end;constObjectPhysicalMemoryDeviceName = 'DevicePhysicalMemory';ObjectPhysicalMemoryName: TUnicodeString = ( Length: Length(ObjectPhysicalMemoryDeviceName) * 2; MaximumLength: Length(ObjectPhysicalMemoryDeviceName) * 2 + 2; Buffer: ObjectPhysicalMemoryDeviceName; );ObjectPhysicalMemoryAccessMask: ACCESS_MASK = SECTION_MAP_READ;ObjectPhysicalMemoryAttributes: TObjectAttributes = ( Length: SizeOf(TObjectAttributes); RootDirectory: 0; ObjectName: @ObjectPhysicalMemoryName; Attributes: OBJ_CASE_INSENSITIVE; SecurityDescriptor: nil; SecurityQualityOfService: nil; );typeTFNZwOpenSection = function(out SectionHandle: THandle; DesiredAccess: ACCESS_MASK; ObjectAttributes: PObjectAttributes): NTSTATUS;stdcall;TFNRtlNtStatusToDosError = function(Status: NTSTATUS): DWORD; stdcall;constntdll = 'ntdll.dll';varZwOpenSection: TFNZwOpenSection;RtlNtStatusToDosError: TFNRtlNtStatusToDosError;function ReadRomBiosNt(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;varNtLayer: HMODULE;Status: NTSTATUS;Section: THandle;View: Pointer;beginResult := False;NtLayer := GetModuleHandle(ntdll);if NtLayer = 0 then SetLastError(ERROR_CALL_NOT_IMPLEMENTED)elsebegin if not Assigned(ZwOpenSection) then ZwOpenSection := GetProcAddress(NtLayer, 'ZwOpenSection'); if not Assigned(RtlNtStatusToDosError) then RtlNtStatusToDosError := GetProcAddress(NtLayer, 'RtlNtStatusToDosError'); if not (Assigned(ZwOpenSection) and Assigned(RtlNtStatusToDosError)) then SetLastError(ERROR_CALL_NOT_IMPLEMENTED) else begin Status := ZwOpenSection(Section, ObjectPhysicalMemoryAccessMask, @ObjectPhysicalMemoryAttributes); case Status of STATUS_SUCCESS: try View := MapViewOfFile(Section, ObjectPhysicalMemoryAccessMask, 0, Low(TRomBiosDump), SizeOf(TRomBiosDump)); if Assigned(View) then try FillChar(Buffer, SizeOf(TRomBiosDump), 0); Move(View^, Buffer, SizeOf(TRomBiosDump)); Result := True; finally UnmapViewOfFile(View); end; finally CloseHandle(Section); end; STATUS_ACCESS_DENIED: Result := ReadRomBios16(Buffer, Timeout); else SetLastError(RtlNtStatusToDosError(Status)) end; end;end;end;{################################################################################ ## ReadRomBios ## ################################################################################}function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;Timeout: DWORD = INFINITE): Boolean;beginResult := False;case Method of rrbmAutomatic: if (Integer(GetVersion) 0) then try Result := ReadRomBios9x(Dump); except Result := ReadRomBios16(Dump, Timeout); end else Result := ReadRomBiosNt(Dump, Timeout); rrbmGeneric: Result := ReadRomBios16(Dump, Timeout); rrbmMemory: Result := ReadRomBios9x(Dump); rrbmPhysical: Result := ReadRomBiosNt(Dump, Timeout);else SetLastError(ERROR_INVALID_PARAMETER);end;end;{################################################################################ ## Utilities to simplify the access to data as generic standard types ## ################################################################################}function GetRomBiosBuffer(const Dump: TRomBiosDump; Address: Pointer;var Buffer; BufferSize: Cardinal): Cardinal;beginResult := 0;if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump)) thenbegin Result := BufferSize; if (Cardinal(Address) + BufferSize High(TRomBiosDump)) then Result := High(TRomBiosDump) - Cardinal(Address) + 1; Move(Dump[Cardinal(Address)], Buffer, Result);end;end;function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer): string;beginResult := '';if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump)) then Result := string(PChar(@Dump[Cardinal(Address)]));end;function GetRomBiosLongLong(const Dump: TRomBiosDump; Address: Pointer): LONGLONG;typePLongLong = ^LONGLONG;beginResult := 0;if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump) - SizeOf(LONGLONG) + 1) then Result := PLongLong(@Dump[Cardinal(Address)])^;end;function GetRomBiosDWord(const Dump: TRomBiosDump; Address: Pointer): DWORD;beginResult := 0;if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump) - SizeOf(DWORD) + 1) then Result := PDWORD(@Dump[Cardinal(Address)])^;end;function GetRomBiosWord(const Dump: TRomBiosDump; Address: Pointer): Word;beginResult := 0;if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump) - SizeOf(Word) + 1) then Result := PWord(@Dump[Cardinal(Address)])^;end;function GetRomBiosByte(const Dump: TRomBiosDump; Address: Pointer): Byte;beginResult := 0;if (Cardinal(Address) = Low(TRomBiosDump)) and (Cardinal(Address) = High(TRomBiosDump) - SizeOf(Byte) + 1) then Result := PByte(@Dump[Cardinal(Address)])^;end;end.
==========================================
4、获取BIOS日期信息
{--------------------------------------------------------------------------}{获取BIOS的日期信息,估计可能在2000下适用,但是可能需要获取权限}function GetBiosDate1: String;varBuffer: Array[0..8] Of Char;N: DWORD;beginReadProcessMemory(GetCurrentProcess, Ptr($FFFF5), @Buffer, 8, N);Buffer[8] := #0;result := StrPas(Buffer)end;function GetBiosDate2: String;beginresult := string(pchar(ptr($FFFF5)));end;