AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Umleiten von Funktionsaufrufen

Ein Thema von CalganX · begonnen am 5. Mai 2004
Antwort Antwort
CalganX

Registriert seit: 21. Jul 2002
Ort: Bonn
5.403 Beiträge
 
Turbo Delphi für Win32
 
#1

Umleiten von Funktionsaufrufen

  Alt 5. Mai 2004, 18:44
User shmia hat ein Stück SourceCode veröffentlicht, das es ermöglicht eine Funktion auf eine andere umzuleiten:
Delphi-Quellcode:
procedure RedirectProcedureCall(oldfunc, newfunc: Pointer);
type
  ba = array[0..4] of Byte;
  Pba = ^ba;
var
  oldprotect: DWORD;
  mbi: TMemoryBasicInformation;
  i : Integer;
begin
  if oldfunc = newfunc then
    exit;
  if (oldfunc=nil) or (newfunc=nil) then
    exit;

  // the JMP instruction needs 5 bytes
  for i := 0 to 4 do
  begin
    if Pba(oldfunc)[i] = $C3 then // C3 = RET instruction
      raise Exception.Create('RedirectProcedureCall: procedure or function is too short !');
  end;

  VirtualQuery(oldfunc, mbi, sizeof(mbi));

  // program code memory is write protected
  VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_EXECUTE_READWRITE, oldProtect);

  // patch the old procedure/function
  asm
    push ebx
    mov eax, oldfunc // oldfunc points to handler being replaced
    mov ebx, newfunc // newfunc points to a new handler
    mov byte ptr [eax], $E9 //JMP instruction
    sub ebx, eax
    sub ebx, 5 // sizeof(JMP xxx)
    mov dword ptr [eax + 1], ebx
    pop ebx
  end;


  FlushInstructionCache(GetCurrentProcess, oldfunc, 6);

  VirtualProtect(mbi.BaseAddress, mbi.RegionSize, OldProtect, OldProtect);
end;
Anwendungsbeispiel:
Delphi-Quellcode:
procedure NewShowMessage(const s:string);
begin
  MessageDlg('Hinweis: '+s, mtWarning, [mbYes, mbNo, mbOK, mbCancel], 0)
end;

{...}

begin
  // neue Procedure installieren
  RedirectProcedureCall(@ShowMessage, @NewShowMessage);
  // und ausprobieren
  ShowMessage('Hello World !');
end;
Ein Beispiel, wo dies nützlich sein kann, stammt ebenfalls von shmia:
Beispiel
In meiner Anwendung hatte ich öfters mal die Fehlermeldung "Klasse nicht registriert.";
natürlich nur bei Kunden, die von Computern keine Ahnung haben und mir bei der Fehlersuche nicht helfen konnten.
Na super, welche Klasse????

Also habe ich die Funktion ProgIDToClassID selbst geschrieben:
Delphi-Quellcode:
function ProgIDToClassID(const ProgID: string): TGUID;
var
  ErrorCode : HRESULT;
begin
  ErrorCode := CLSIDFromProgID(PWideChar(WideString(ProgID)), Result);
  if not Succeeded(ErrorCode) then
    raise EOleSysError.Create('ProgID: '+ProgID+#13#10+HResultToErrorMessage(ErrorCode), ErrorCode, 0);
end;
Und jetzt wäre es natürlich gut, wenn jeder Aufruf auf ComObj.ProgIDToClassID
auf meiner neuen Funktion landen würde. (Denn ProgIDToClassID wird von der Funktion CreateOleObject benützt)


[edit=Matze]Code formatiert. Mfg, Matze[/edit]
  Mit Zitat antworten Zitat
Antwort Antwort

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:40 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz