-
Notifications
You must be signed in to change notification settings - Fork 0
/
dx_overlay.cpp
161 lines (126 loc) · 5.27 KB
/
dx_overlay.cpp
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "dx_overlay.h"
#include <iostream>
#include <dwmapi.h>
#pragma comment(lib, "dwmapi.lib")
namespace forceinline {
/*
Regarding the not_topmost argument:
Some games/anti-cheats specifically check if a window has the WS_EX_TOPMOST and WS_VISIBLE flags, or has the game window as its parent.
By setting not_topmost to true, we will use a trick to make our window act similar to having the WS_EX_TOPMOST style without it actually having it,
therefore making that window harder to detect (or easier, it depends on the anti-cheat. Before doing anything you should become familiar with the
anti-cheat the game has to avoid being banned.
*/
dx_overlay::dx_overlay(std::wstring_view target_class, std::wstring_view target_window, bool not_topmost) {
m_not_topmost = not_topmost;
if (target_window.empty() && target_class.empty())
throw std::invalid_argument("kollusion: no target window! abort!");
if (!FindWindowW(target_class.empty() ? NULL : target_class.data(), target_window.empty() ? NULL : target_window.data())) {
std::string target_class_mb(target_class.begin(), target_class.end());
std::string target_window_mb(target_window.begin(), target_window.end());
throw std::invalid_argument("kollusion: application \"" + target_window_mb + "\" with module \"" + target_class_mb + "\" could not be found");
}
create_overlay(target_class, target_window);
}
dx_overlay::~dx_overlay() {
if (m_overlay_wnd)
DestroyWindow(m_overlay_wnd);
if (m_d3d)
m_d3d->Release();
if (m_device)
m_device->Release();
}
dx_renderer dx_overlay::create_renderer() {
return dx_renderer(m_device); //Return a renderer object
}
HWND dx_overlay::get_overlay_wnd() {
return m_overlay_wnd; //Return our window handle
}
bool dx_overlay::is_initialized() {
return m_initialized; //Is our overlay initialized properly?
}
void dx_overlay::create_overlay(std::wstring_view target_class, std::wstring_view target_window) {
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
//Create our window class
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = m_wnd_proc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = NULL;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = HBRUSH(RGB(0, 0, 0));
wc.lpszMenuName = "";
wc.lpszClassName = "kollusion";
wc.hIconSm = NULL;
//Register our window class
if (!RegisterClassExA(&wc))
throw std::exception("kollusion: failed to register wndclassex");
//Find our target window
m_target_wnd = FindWindowW(target_class.data(), target_window.data());
//Get the size of our target window
GetWindowRect(m_target_wnd, &m_target_wnd_size);
//Make the window transparent
DWORD ex_styles = WS_EX_LAYERED | WS_EX_TRANSPARENT;
//Add WS_EX_TOPMOST if we choose
if (!m_not_topmost)
ex_styles |= WS_EX_TOPMOST;
//Create our window
m_overlay_wnd = CreateWindowExA(ex_styles, "kollusion", "", WS_POPUP | WS_VISIBLE,
m_target_wnd_size.left, m_target_wnd_size.top, m_target_wnd_size.width(), m_target_wnd_size.height(), NULL, NULL, NULL, NULL);
if (!m_overlay_wnd)
throw std::exception("kollusion: failed to create overlay window");
//Let DWM handle our window
MARGINS m = { m_target_wnd_size.left, m_target_wnd_size.top, m_target_wnd_size.width(), m_target_wnd_size.height() };
DwmExtendFrameIntoClientArea(m_overlay_wnd, &m);
//Set window to use alpha channel
SetLayeredWindowAttributes(m_overlay_wnd, RGB(0, 0, 0), 255, LWA_ALPHA);
//Show our window
ShowWindow(m_overlay_wnd, SW_SHOW);
//Initialize DirectX
init_dx9();
}
void dx_overlay::init_dx9() {
//Create DirectX object
m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (!m_d3d)
throw std::exception("kollusion: failed to create dx3d9 object");
//Create DirectX present parameters struct
D3DPRESENT_PARAMETERS d3d_pp;
ZeroMemory(&d3d_pp, sizeof(d3d_pp));
//Set our device parameters
d3d_pp.Windowed = true;
d3d_pp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3d_pp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3d_pp.BackBufferWidth = m_target_wnd_size.width();
d3d_pp.BackBufferHeight = m_target_wnd_size.height();
d3d_pp.hDeviceWindow = m_overlay_wnd;
d3d_pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
//Create DirectX device
if (FAILED(m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_overlay_wnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3d_pp, &m_device))) {
m_d3d->Release();
throw std::exception("kollusion: failed to create device");
}
//Overlay successfully initialized
m_initialized = true;
}
bool dx_overlay::m_not_topmost = false;
HWND dx_overlay::m_target_wnd, dx_overlay::m_overlay_wnd;
LRESULT CALLBACK dx_overlay::m_wnd_proc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) {
//Imitate WS_EX_TOPMOST if specified
if (m_not_topmost) {
//Grab target window RECT
wnd_rect_t r;
GetWindowRect(m_target_wnd, &r);
//Set the target windows z position to be under our overlay
SetWindowPos(m_target_wnd, m_overlay_wnd, r.left, r.top, r.width(), r.height(), SWP_NOMOVE | SWP_NOSIZE);
}
switch (msg) {
case WM_DESTROY:
exit(0);
break;
default:
return DefWindowProc(wnd, msg, wparam, lparam);
}
}
}