-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathunMainForm.pas
134 lines (111 loc) · 3.09 KB
/
unMainForm.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
unit unMainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Injector, ExtCtrls;
type
TMainForm = class(TForm)
btnApply: TButton;
Label1: TLabel;
Label2: TLabel;
btnUnapply: TButton;
btnExecute: TButton;
rgMethod: TRadioGroup;
procedure btnUnapplyClick(Sender: TObject);
procedure btnExecuteClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure btnApplyClick(Sender: TObject);
private
FVCLHijack: TInjector;
FHijack: TInjector;
procedure MyMethod;
procedure MyMethodHijacker;
procedure ApplyToSelf;
procedure ApplyToVCL;
procedure UnapplytoVCL;
procedure UnapplyToSelf;
public
procedure ExecuteMethod;
end;
TWinControlPatch = class helper for TWinControl
public
procedure UpdateShowingPatch;
end;
var
MainForm: TMainForm;
implementation
{$R *.dfm}
const
TARGET_CALL_OPCODE: array[0..4] of byte = (
$E8, $9B, $FE, $FF, $FF
);
{ TWinControlPatch }
procedure TMainForm.FormCreate(Sender: TObject);
begin
Label1.Caption := EmptyStr;
end;
procedure TMainForm.btnApplyClick(Sender: TObject);
begin
case rgMethod.ItemIndex of
0: ApplyToVCL;
1: ApplyToSelf;
end;
end;
procedure TMainForm.ApplyToVCL;
begin
//Private method hijack
//Note: code changes result in address changes.
//For a private method, you must search for a public method that uses the target method
//and get it's address by opcode (machine code).
//Invoke Self.UpdateControlState to find UpdateShowing opcode;
//Run this cocde withou changes and look at the debugger window for method opcode.
Self.UpdateControlState; //Find UpdateShowing call opcode, than change TARGET_CALL_OPCODE constant
if not Assigned(FVCLHijack) then begin //Offset calc
FVCLHijack := TInjector.Create(TInjector.GetAddresOfByACallNearRel(@TMainForm.UpdateControlState, TARGET_CALL_OPCODE), @TMainForm.UpdateShowingPatch);
end;
end;
procedure TMainForm.ApplyToSelf;
begin
if not Assigned(FHijack) then begin
FHijack := TInjector.Create(@TMainForm.MyMethod, @TMainForm.MyMethodHijacker);
end;
end;
procedure TMainForm.btnUnapplyClick(Sender: TObject);
begin
case rgMethod.ItemIndex of
0: UnapplytoVCL;
1: UnapplyToSelf;
end;
end;
procedure TMainForm.UnapplyToSelf;
begin
if Assigned(FHijack) then
FreeAndNil(FHijack);
end;
procedure TMainForm.UnapplytoVCL;
begin
if Assigned(FVCLHijack) then
FreeAndNil(FVCLHijack);
end;
procedure TMainForm.btnExecuteClick(Sender: TObject);
begin
ExecuteMethod;
UpdateControlState;
end;
procedure TMainForm.ExecuteMethod;
begin
MyMethod;
end;
procedure TMainForm.MyMethod;
begin
Label1.Caption := 'Default MyMethod';
end;
procedure TMainForm.MyMethodHijacker;
begin
Label1.Caption := 'MyMethod hijacked';
end;
procedure TWinControlPatch.UpdateShowingPatch;
begin
MainForm.Label1.Caption := 'VCL hijacked!';
end;
end.