Subversion Repositories userdetect2

Rev

Rev 68 | Rev 81 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. unit PatchU;
  2.  
  3. interface
  4.  
  5. type
  6.   pPatchEvent = ^TPatchEvent;
  7.  
  8.   // "Asm" opcode hack to patch an existing routine
  9.   TPatchEvent = packed record
  10.     Jump: Byte;
  11.     Offset: Integer;
  12.   end;
  13.  
  14.   TPatchMethod = class
  15.   private
  16.     PatchedMethod, OriginalMethod: TPatchEvent;
  17.     PatchPositionMethod: pPatchEvent;
  18.     FIsPatched: boolean;
  19.   public
  20.     property IsPatched: boolean read FIsPatched;
  21.     constructor Create(const aSource, aDestination: Pointer);
  22.     destructor Destroy; override;
  23.     procedure Restore;
  24.     procedure Hook;
  25.   end;
  26.  
  27. implementation
  28.  
  29. uses
  30.   Windows, Sysutils;
  31.  
  32. { TPatchMethod }
  33.  
  34. constructor TPatchMethod.Create(const aSource, aDestination: Pointer);
  35. var
  36.   OldProtect: Cardinal;
  37. begin
  38.   PatchPositionMethod := pPatchEvent(aSource);
  39.   OriginalMethod := PatchPositionMethod^;
  40.   PatchedMethod.Jump := $E9;
  41.   PatchedMethod.Offset := Integer(PByte(aDestination)) - Integer(PByte(PatchPositionMethod)) - SizeOf(TPatchEvent);
  42.  
  43.   if not VirtualProtect(PatchPositionMethod, SizeOf(TPatchEvent), PAGE_EXECUTE_READWRITE, OldProtect) then
  44.     RaiseLastOSError;
  45.  
  46.   Hook;
  47. end;
  48.  
  49. destructor TPatchMethod.Destroy;
  50. begin
  51.   Restore;
  52.   inherited;
  53. end;
  54.  
  55. procedure TPatchMethod.Hook;
  56. begin
  57.   if FIsPatched then Exit;
  58.   FIsPatched := true;
  59.   PatchPositionMethod^ := PatchedMethod;
  60. end;
  61.  
  62. procedure TPatchMethod.Restore;
  63. begin
  64.   if not FIsPatched then Exit;
  65.   FIsPatched := false;
  66.   PatchPositionMethod^ := OriginalMethod;
  67. end;
  68.  
  69. end.
  70.  
  71.