?? bioshelp.pas
字號:
Unit BiosHelp;
{$ALIGN ON}
{$MINENUMSIZE 4}
Interface
Uses
Windows;
Type
PRomBiosDump = ^TRomBiosDump;
TRomBiosDump = Array[$000F0000..$000FFFFF] Of byte;
Type
TReadRomBiosMethod = (
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;
Function GetmotherboradKey: String; //取得系統系列號
Function Getmotherboradver: String; //BIOS 版本
Function Getmotherboraddate: String; //BIOS日期
Function Getmotherboradverxx: String; //BIOS 版權信息
Function Getmotherboradname: String; //BIOS 名稱
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 }
Type
PRomDumpCodeInfo = ^TRomDumpCodeInfo;
TRomDumpCodeInfo = (rdciStart, rdciEnd, rdciSize);
Function _RomDumpCode(Info: TRomDumpCodeInfo): Pointer;
Var
CodeStart : Pointer;
CodeEnd : Pointer;
Begin
Asm
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 @@End
End;
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;
Var
ComFile : THandle;
Size : cardinal;
Begin
result := false;
ComFile := CreateFile(pchar(FileName), GENERIC_WRITE, FILE_SHARE_READ, Nil,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
If ComFile <> INVALID_HANDLE_VALUE Then Try
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;
Var
ComSpec : String;
si : TStartupInfo;
Pi : TProcessInformation;
Begin
result := false;
SetLength(ComSpec, MAX_PATH);
SetLength(ComSpec,
GetEnvironmentVariable('ComSpec', pchar(@ComSpec[1]), MAX_PATH));
If Length(ComSpec) > 0 Then Begin
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;
Var
Attr : dword;
Begin
Attr := 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;
Const
TempSub = '~RomDmp';
ComName = 'RomDump.com';
DmpName = 'Rom.dmp';
Var
TempPath : String;
TempDir : String;
TempIdx : integer;
TempIdxStr : String;
ComFile : String;
DmpFile : String;
DmpHandle : THandle;
Written : dword;
Begin
result := false;
SetLength(TempPath, MAX_PATH);
SetLength(TempPath, GetTempPath(MAX_PATH, pchar(@TempPath[1])));
If Length(TempPath) > 0 Then Begin
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;
Begin
result := false;
Try
FillChar(Buffer, SizeOf(TRomBiosDump), 0);
Move(Pointer(Low(TRomBiosDump))^, Buffer, SizeOf(TRomBiosDump));
result := true;
Except
// ignore exceptions
End
End;
{##############################################################################
#
# #
# PHYSICAL MEMORY METHOD (WinNT) #
# #
# On Windows NT the ROM BIOS is only available through the named kernel object
#
# '\Device\PhysicalMemory'. 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
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -