├── README.md └── ThreadHijacking.cpp /README.md: -------------------------------------------------------------------------------- 1 | # ThreadHijackingInjector 2 | Yt video of me making this and explaining how it works here https://www.youtube.com/watch?v=69JINSmgml4 3 | -------------------------------------------------------------------------------- /ThreadHijacking.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | #pragma comment(lib, "ntdll.lib") 9 | 10 | extern "C" NTSTATUS NTAPI RtlAdjustPrivilege(ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled); 11 | 12 | #define SE_DEBUG_PRIVILEGE 20 13 | 14 | char shell_code[] = 15 | { 16 | 0x60, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x81, 0xEB, 0x06, 0x00, 0x00, 17 | 0x00, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0x8D, 0x93, 0x22, 0x00, 0x00, 0x00, 18 | 0x52, 0xFF, 0xD0, 0x61, 0x68, 0xCC, 0xCC, 0xCC, 0xCC, 0xC3 19 | }; 20 | 21 | void get_proc_id(const char* window_title, DWORD &process_id) 22 | { 23 | GetWindowThreadProcessId(FindWindow(NULL, window_title), &process_id); 24 | } 25 | 26 | void error(const char* error_title, const char* error_message) 27 | { 28 | MessageBox(NULL, error_message, error_title, NULL); 29 | exit(-1); 30 | } 31 | 32 | bool file_exists(string file_name) 33 | { 34 | struct stat buffer; 35 | return (stat(file_name.c_str(), &buffer) == 0); 36 | } 37 | 38 | int main() 39 | { 40 | LPBYTE ptr; 41 | HANDLE h_process, h_thread, h_snap; 42 | PVOID allocated_memory, buffer; 43 | DWORD proc_id; 44 | BOOLEAN buff; 45 | 46 | THREADENTRY32 te32; 47 | CONTEXT ctx; 48 | 49 | char dll_path[MAX_PATH]; 50 | const char* dll_name = "TestDLL.dll"; 51 | const char* window_title = "Counter-Strike: Global Offensive"; 52 | 53 | te32.dwSize = sizeof(te32); 54 | ctx.ContextFlags = CONTEXT_FULL; 55 | 56 | RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &buff); 57 | 58 | if (!file_exists(dll_name)) 59 | { 60 | error("file_exists", "File doesn't exist"); 61 | } 62 | 63 | if (!GetFullPathName(dll_name, MAX_PATH, dll_path, nullptr)) 64 | { 65 | error("GetFullPathName", "Failed to get full path"); 66 | } 67 | 68 | get_proc_id(window_title, proc_id); 69 | if (proc_id == NULL) 70 | { 71 | error("get_proc_id", "Failed to get process ID"); 72 | } 73 | 74 | h_process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, proc_id); 75 | if (!h_process) 76 | { 77 | error("OpenProcess", "Failed to open a handle to the process"); 78 | } 79 | 80 | h_snap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, NULL); 81 | 82 | Thread32First(h_snap, &te32); 83 | 84 | while (Thread32Next(h_snap, &te32)) 85 | { 86 | if (te32.th32OwnerProcessID == proc_id) 87 | { 88 | break; 89 | } 90 | } 91 | 92 | CloseHandle(h_snap); 93 | 94 | allocated_memory = VirtualAllocEx(h_process, NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); 95 | if (!allocated_memory) 96 | { 97 | CloseHandle(h_process); 98 | error("VirtualAllocEx", "Failed to allocate memory"); 99 | } 100 | 101 | h_thread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID); 102 | if (!h_thread) 103 | { 104 | VirtualFreeEx(h_process, allocated_memory, NULL, MEM_RELEASE); 105 | CloseHandle(h_process); 106 | error("OpenThread", "Failed to open a handle to the thread"); 107 | } 108 | 109 | SuspendThread(h_thread); 110 | GetThreadContext(h_thread, &ctx); 111 | 112 | buffer = VirtualAlloc(NULL, 65536, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); 113 | ptr = (LPBYTE)buffer; 114 | 115 | memcpy(buffer, shell_code, sizeof(shell_code)); 116 | 117 | while (1) 118 | { 119 | if (*ptr == 0xb8 && *(PDWORD)(ptr + 1) == 0xCCCCCCCC) 120 | { 121 | *(PDWORD)(ptr + 1) = (DWORD)LoadLibraryA; 122 | } 123 | 124 | if (*ptr == 0x68 && *(PDWORD)(ptr + 1) == 0xCCCCCCCC) 125 | { 126 | *(PDWORD)(ptr + 1) = ctx.Eip; 127 | } 128 | 129 | if (*ptr == 0xc3) 130 | { 131 | ptr++; 132 | break; 133 | } 134 | 135 | ptr++; 136 | } 137 | 138 | strcpy((char*)ptr, dll_path); 139 | 140 | if (!WriteProcessMemory(h_process, allocated_memory, buffer, sizeof(shell_code) + strlen((char*)ptr), nullptr)) 141 | { 142 | VirtualFreeEx(h_process, allocated_memory, NULL, MEM_RELEASE); 143 | ResumeThread(h_thread); 144 | 145 | CloseHandle(h_thread); 146 | CloseHandle(h_process); 147 | 148 | VirtualFree(buffer, NULL, MEM_RELEASE); 149 | error("WriteProcessMemory", "Failed to write process memory"); 150 | } 151 | 152 | ctx.Eip = (DWORD)allocated_memory; 153 | 154 | if (!SetThreadContext(h_thread, &ctx)) 155 | { 156 | VirtualFreeEx(h_process, allocated_memory, NULL, MEM_RELEASE); 157 | ResumeThread(h_thread); 158 | 159 | CloseHandle(h_thread); 160 | CloseHandle(h_process); 161 | 162 | VirtualFree(buffer, NULL, MEM_RELEASE); 163 | error("SetThreadContext", "Failed to set thread context"); 164 | } 165 | 166 | ResumeThread(h_thread); 167 | 168 | CloseHandle(h_thread); 169 | CloseHandle(h_process); 170 | 171 | VirtualFree(buffer, NULL, MEM_RELEASE); 172 | 173 | MessageBox(NULL, "Successfully injected", "Success!", NULL); 174 | 175 | return NULL; 176 | } 177 | 178 | --------------------------------------------------------------------------------