Einzelnen Beitrag anzeigen

Benutzerbild von Memnarch
Memnarch

Registriert seit: 24. Sep 2010
737 Beiträge
 
#1

Brauche verständnishilfe für folgenden Detourcode

  Alt 14. Feb 2014, 14:37
Tag allerseits,
Habene ebdn durch zufall auf Stackoverflow folgenden Artikel entdeckt:
http://stackoverflow.com/questions/6...-notifications

Dort ist folgender code zum umleiten von methoden angegeben:
Delphi-Quellcode:
type
  THookedForm = class(TCustomForm)
    procedure HookedDoCreate;
  end;

  THookedFrame = class(TCustomFrame)
    constructor Create(AOwner: TComponent); override;
  end;

  PPatchEvent = ^TPatchEvent;
  /// asm opcode hack to patch an existing routine
  TPatchEvent = packed record
    Jump: byte;
    Offset: integer;
  end;

var
  PatchForm, OriginalForm: TPatchEvent;
  PatchPositionForm: PPatchEvent = nil;
  PatchFrame, OriginalFrame: TPatchEvent;
  PatchPositionFrame: PPatchEvent = nil;

procedure PatchCreate;
var ov: cardinal;
begin
  // hook TForm:
  PatchPositionForm := PPatchEvent(@THookedForm.DoCreate);
  OriginalForm := PatchPositionForm^;
  PatchForm.Jump := $E9; // Jmp opcode
  PatchForm.Offset := PtrInt(@THookedForm.HookedDoCreate)-PtrInt(PatchPositionForm)-5;
  if not VirtualProtect(PatchPositionForm, 5, PAGE_EXECUTE_READWRITE, @ov) then
    RaiseLastOSError;
  PatchPositionForm^ := PatchForm; // enable Hook
  // hook TFrame:
  PatchPositionFrame := PPatchEvent(@TCustomFrame.Create);
  OriginalFrame := PatchPositionFrame^;
  PatchFrame.Jump := $E9; // Jmp opcode
  PatchFrame.Offset := PtrInt(@THookedFrame.Create)-PtrInt(PatchPositionFrame)-5;
  if not VirtualProtect(PatchPositionFrame, 5, PAGE_EXECUTE_READWRITE, @ov) then
    RaiseLastOSError;
  PatchPositionFrame^ := PatchFrame; // enable Hook
end;

{ THookedForm }

procedure THookedForm.HookedDoCreate;
var i: integer;
begin
  // enumerate all labels, then set Transparent := true
  for i := 0 to Components.Count-1 do
    if Components[i] is TLabel then
      TLabel(Components[i]).Transparent := true;
  DoCreate; // call initial code
end;

{ THookedFrame }

constructor THookedFrame.Create(AOwner: TComponent);
var i: integer;
begin
  // enumerate all labels, then set Transparent := true
  for i := 0 to Components.Count-1 do
    if Components[i] is TLabel then
      TLabel(Components[i]).Transparent := true;
  inherited Create(AOwner); // call normal constructor
end;

....

initialization
  PatchCreate;
Seh ich das richtig, wird nicht die ursprüngliche Methode zerstört? Delphi-routinen haben doch keine Nops für Detours wie die WInapi, oder?.

Wenn ich dass doch rrichtig verstehe, wird ganz normal an den Anfang der zu patchenden Methode der rel-jump in die eigene gesetzt. Das überschreibt für gewönlich den Prolog einer routine. Also wie soll das funktionieren, dass er bei sich einfach DoCreate aufruft, und damit den ursprünglichen code aufruft? Eigentlich müsste dass doch nun wieder in seiner methode landen?

EDIT: also zumindest die implementierung von TCustomForm.DOCreate sollte nicht mehr nutzbar sein, oder?

Grüße
Memnarch
Da man Trunc nicht auf einen Integer anwenden kann, muss dieser zuerst in eine Float kopiert werden

Geändert von Memnarch (14. Feb 2014 um 14:39 Uhr)
  Mit Zitat antworten Zitat