-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ddrawhook.dpr
108 lines (90 loc) · 2.47 KB
/
ddrawhook.dpr
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
// DirectDraw Overlay via DirectX API hooking
// Brandon Asuncion (me@brandonasuncion.tech)
library ddrawhook;
uses
SysUtils,
Windows,
DirectDraw,
GDI,
afxCodeHook;
var
hhBlt:function(lpDestRect: pointer; lpDDSrcSurface: pointer; lpSrcRect: pointer; dwFlags: DWORD; lpDDBltFx: pointer): HResult; stdcall;
plpDDSrcSurface:dword;
DC:hDC;
// This part uses Windows' GDI API
procedure Drawer;
begin
SetBkMode(DC, TRANSPARENT);
TextOut(DC, 10, 10, 'DirectDraw Overlay via API Hooks Example', 11);
TextOut(DC, 10, 20, 'by Brandon Asuncion', 11);
end;
procedure myBlt;
begin
asm
mov eax, DWORD PTR SS:[esp + 12]
mov plpDDSrcSurface, eax
pushad
end;
if (plpDDSrcSurface <> 0) then
begin
Surface:=@plpDDSrcSurface;
if Surface.GetDC(DC) = DD_OK then
begin
drawer;
Surface.ReleaseDC(DC);
end;
end;
asm
popad
jmp hhBlt
end;
end;
procedure CreateBackup(TargetFunction:pointer; var backup:pointer);
var
OldProcSize, Size, SaveSize:dword;
Next:pointer;
begin
SaveSize := 0;
Next := TargetFunction;
while SaveSize < 5 do
begin
Size := SizeOfCode(Next);
Next := pointer(longword(Next) + Size);
Inc(SaveSize, Size);
end;
OldProcSize := SaveSize + 5;
backup:=VirtualAlloc(nil, OldProcSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
Move(TargetFunction^, backup^, SaveSize);
byte(pointer(dword(backup) + SaveSize)^) := $E9;
dword(pointer(dword(backup) + SaveSize + 1)^) := dword(TargetFunction) - dword(backup) - 5;
end;
var
DD:IDirectDraw7;
surface:IDirectDrawSurface7;
surfaceDesc:_DDSURFACEDESC2;
begin
if DirectDrawCreateEx(nil, DD, IDirectDraw7, nil) <> DD_OK then
begin
MessageBox(0, 'DirectDrawCreateEx() failed!', '', MB_OK);
exit;
end;
if DD.SetCooperativeLevel(0, ddscl_normal) <> DD_OK then
begin
MessageBox(0, 'DD_SetCooperativeLevel() failed!', '', MB_OK);
exit;
end;
fillchar(SurfaceDesc, sizeof(surfaceDesc), 0);
surfaceDesc.dwSize:=sizeof(surfaceDesc);
surfaceDesc.dwFlags:=ddsd_caps;
surfaceDesc.ddsCaps.dwCaps:=ddscaps_primarysurface;
if DD.CreateSurface(surfaceDesc, surface, nil) <> DD_OK then
begin
MessageBox(0, 'DD_CreateSurface() failed!', '', MB_OK);
ExitProcess(0);
end;
addrBlt:=pdword(pdword(pdword(@surface)^)^ + $14)^;
CreateBackup(addrBlt, @hhBlt);
hook(addrBlt, @myBlt);
FlushInstructionCache(GetCurrentProcess, addrBlt, 10);
MessageBox(0, 'Injected into process', '', 0);
end.