Subversion Repositories userdetect2

Rev

Rev 81 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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