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 |