Einzelnen Beitrag anzeigen

NicoDE
(Gast)

n/a Beiträge
 
#29

Re: vergleichen von zwei librarys im speicher

  Alt 7. Jul 2005, 14: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
  Mit Zitat antworten Zitat