(Gast)
n/a Beiträge
|
Re: vergleichen von zwei librarys im speicher
7. Jul 2005, 15:42
Ich habe einen kleinen Detection-Code für den Target geschrieben, die darauf basiert, dass die Protection einer Speicherseite der Exporte (glBegin) PAGE_EXECUTE_READWRITE ist...
Delphi-Quellcode:
////////////////////////////////////////////////////////////////////////////////
// GetOpenGL32Infos
type
POpenGL32Infos = ^TOpenGL32Infos;
TOpenGL32Infos = record
BaseOfCode: Longword;
SizeOfCode: Longword;
end;
function GetOpenGL32Infos(var Info: TOpenGL32Infos): Boolean;
const
INVALID_FILE_SIZE = DWORD(-1);
INVALID_SET_FILE_POINTER = DWORD(-1);
opengl32lib = '\opengl32.dll';
var
FileName: array [0..MAX_PATH + Length(opengl32lib)] of Char;
FileHandle: THandle;
DosHeader: TImageDosHeader;
BytesRead: DWORD;
NtHeaders: TImageNtHeaders;
begin
Result := False;
GetSystemDirectory(FileName, MAX_PATH);
StrCat(FileName, opengl32lib);
FileHandle := CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, nil,
OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, THandle(nil));
if INVALID_HANDLE_VALUE = FileHandle then
Exit;
try
with DosHeader, NtHeaders, NtHeaders.FileHeader, NtHeaders.OptionalHeader do
begin
// Get Headers
if not ReadFile(FileHandle, DosHeader, SizeOf(TImageDosHeader), BytesRead,
nil) or (BytesRead <> SizeOf(TImageDosHeader)) or
(e_magic <> IMAGE_DOS_SIGNATURE) or
(_lfanew < SizeOf(TImageDosHeader)) or
(INVALID_SET_FILE_POINTER = SetFilePointer(FileHandle,
_lfanew - SizeOf(TImageDosHeader), nil, FILE_CURRENT)) or
not ReadFile(FileHandle, NtHeaders, SizeOf(TImageNtHeaders), BytesRead,
nil) or (BytesRead <> SizeOf(TImageNtHeaders)) or
(Signature <> IMAGE_NT_SIGNATURE) or (NumberOfSections <= 0) or
(SizeOfOptionalHeader < SizeOf(TImageOptionalHeader)) then
Exit;
// Write Infos
Info.BaseOfCode := ImageBase + BaseOfCode;
Info.SizeOfCode := SizeOfCode;
Result := True;
end;
finally
CloseHandle(FileHandle);
end;
end;
////////////////////////////////////////////////////////////////////////////////
// DetectOpenGL32Patch
var
OpenGL32InfosValid: Boolean;
OpenGL32Infos: TOpenGL32Infos;
OpenGL32Modul: HMODULE;
OpenGL32Begin: Pointer;
function DetectOpenGL32Patch: Boolean;
var
Adr: Cardinal;
Mbi: TMemoryBasicInformation;
begin
Result := False;
if not OpenGL32InfosValid or
(HMODULE(nil) = OpenGL32Modul) or
(nil = OpenGL32Begin) then
Exit;
Adr := Cardinal(OpenGL32Begin);
Result :=
// check if opengl32!glBegin is outside of the code section...
(Adr < OpenGL32Infos.BaseOfCode) or
(Adr > OpenGL32Infos.BaseOfCode + OpenGL32Infos.SizeOfCode) or
// check if the memory page of opengl32!glBegin is writable...
(
(VirtualQuery(Pointer(Adr), Mbi, SizeOf(Mbi)) = SizeOf(Mbi)) and
(Mbi.Protect = PAGE_EXECUTE_READWRITE)
);
end;
function DetectOpenGL32PatchEx(ProcessId: DWORD): Boolean;
var
Prc: THandle;
Mbi: TMemoryBasicInformation;
begin
Result := False;
if not OpenGL32InfosValid or
(HMODULE(nil) = OpenGL32Modul) or
(nil = OpenGL32Begin) then
Exit;
Prc := OpenProcess(PROCESS_QUERY_INFORMATION, False, ProcessId);
if THandle(nil) = Prc then
Exit;
try
Result :=
// check if the memory page of opengl32!glBegin is writable...
(VirtualQueryEx(Prc, OpenGL32Begin, Mbi, SizeOf(Mbi)) = SizeOf(Mbi)) and
(Mbi.Protect = PAGE_EXECUTE_READWRITE);
finally
CloseHandle(Prc);
end;
end;
////////////////////////////////////////////////////////////////////////////////
// Check
procedure TForm1.Button1Click(Sender: TObject);
begin
ShowMessage(BoolToStr(DetectOpenGL32Patch, True));
end;
////////////////////////////////////////////////////////////////////////////////
// Init
initialization
OpenGL32InfosValid := GetOpenGL32Infos(OpenGL32Infos);
OpenGL32Modul := LoadLibrary('opengl32.dll');
OpenGL32Begin := GetProcAddress(OpenGL32Modul, 'glBegin');
Mögliches Problem: die Seite könnte absichtlich PAGE_EXECUTE_READWRITE sein (unwahrscheinlich ohne Manipulation).
Gruß Nico
|
|
Zitat
|