Subversion Repositories userdetect2

Rev

Rev 81 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 daniel-mar 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