2424
2525#include <stdio.h>
2626#include <stdlib.h>
27+ #include <stdbool.h>
2728#include <string.h>
2829#include <windows.h>
30+ #include <tlhelp32.h>
2931
3032#include "nerror.h"
3133#include "ntosutils.h"
3234#include "ntmem.h"
3335#include "ntosutilswin.h"
3436
37+ /**
38+ * @brief Check if the given ID is a process ID
39+ * @param id The ID to check
40+ * @return true if it's a process ID, false if not (likely a thread ID)
41+ */
42+ static bool is_process_id (uint32_t id )
43+ {
44+ HANDLE snap = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
45+ if (snap == INVALID_HANDLE_VALUE )
46+ return false;
47+
48+ PROCESSENTRY32 pe = { .dwSize = sizeof (pe ) };
49+
50+ if (Process32First (snap , & pe )) {
51+ do {
52+ if (pe .th32ProcessID == id ) {
53+ CloseHandle (snap );
54+ return true;
55+ }
56+ } while (Process32Next (snap , & pe ));
57+ }
58+
59+ CloseHandle (snap );
60+ return false;
61+ }
62+
63+ /**
64+ * @brief Get the process ID that owns the given thread
65+ * @param thread_id The thread ID
66+ * @return Process ID, or 0 if not found
67+ */
68+ static DWORD get_process_id_from_thread (DWORD thread_id )
69+ {
70+ HANDLE snap = CreateToolhelp32Snapshot (TH32CS_SNAPTHREAD , 0 );
71+ if (snap == INVALID_HANDLE_VALUE )
72+ return 0 ;
73+
74+ THREADENTRY32 te = { .dwSize = sizeof (te ) };
75+
76+ if (Thread32First (snap , & te )) {
77+ do {
78+ if (te .th32ThreadID == thread_id ) {
79+ DWORD pid = te .th32OwnerProcessID ;
80+ CloseHandle (snap );
81+ return pid ;
82+ }
83+ } while (Thread32Next (snap , & te ));
84+ }
85+
86+ CloseHandle (snap );
87+ return 0 ;
88+ }
89+
90+ #ifdef LOG_LEVEL_3
91+ /**
92+ * @brief Log all modules loaded in the target process
93+ * @param pid The process ID
94+ */
95+ static void log_process_modules (DWORD pid )
96+ {
97+ HANDLE snap = CreateToolhelp32Snapshot (
98+ TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32 , pid );
99+ if (snap == INVALID_HANDLE_VALUE ) {
100+ LOG_WARN (
101+ "Failed to enumerate modules for process %u (error: %lu)" ,
102+ pid , GetLastError ());
103+ return ;
104+ }
105+
106+ MODULEENTRY32 me = { .dwSize = sizeof (me ) };
107+ int count = 0 ;
108+
109+ LOG_INFO ("=== Modules loaded in process %u ===" , pid );
110+
111+ if (Module32First (snap , & me )) {
112+ do {
113+ LOG_INFO (" [%d] %s (base: %p, size: %u)" , ++ count ,
114+ me .szModule , me .modBaseAddr , me .modBaseSize );
115+ } while (Module32Next (snap , & me ));
116+ }
117+
118+ LOG_INFO ("=== Total: %d modules ===" , count );
119+ CloseHandle (snap );
120+ }
121+ #endif
122+
35123void print_usage ()
36124{
37125 printf ("GhostInjector - DLL Injection tool for Windows processes\n\n" );
@@ -59,7 +147,6 @@ int main(int argc, char *argv[])
59147
60148#ifdef LOG_LEVEL_1
61149 LOG_INFO ("Neptune initialized!" );
62- LOG_INFO ("ID: %u" , id );
63150 LOG_INFO ("Number of DLLs to inject: %d" , argc - 2 );
64151#endif
65152
@@ -71,6 +158,29 @@ int main(int argc, char *argv[])
71158 return 0x11 ;
72159 }
73160
161+ bool is_process = is_process_id (id );
162+ DWORD pid ;
163+
164+ if (is_process ) {
165+ pid = id ;
166+ #ifdef LOG_LEVEL_2
167+ LOG_INFO ("ID %u is a process" , id );
168+ #endif
169+ } else {
170+ pid = get_process_id_from_thread (id );
171+ #ifdef LOG_LEVEL_2
172+ LOG_INFO ("ID %u is a thread, owner process ID: %u" , id , pid );
173+ #endif
174+ if (pid == 0 ) {
175+ #ifdef LOG_LEVEL_1
176+ LOG_ERROR ("Failed to get process ID from thread %u" ,
177+ id );
178+ #endif
179+ neptune_destroy ();
180+ return 0x08 ;
181+ }
182+ }
183+
74184 HMODULE kernel32 = GetModuleHandleA ("kernel32" );
75185 if (kernel32 == NULL ) {
76186#ifdef LOG_LEVEL_1
@@ -93,14 +203,24 @@ int main(int argc, char *argv[])
93203 LOG_INFO ("LoadLibraryA=%p" , (void * )load_library_func );
94204#endif
95205
96- if (HAS_ERR (nosu_attach (id ))) {
97- #ifdef LOG_LEVEL_1
98- LOG_WARN ("nosu_attach failed" );
206+ #ifdef LOG_LEVEL_3
207+ log_process_modules (pid );
99208#endif
100209
210+ if (is_process ) {
101211 if (HAS_ERR (nosu_find_thread_and_upgrade (id ))) {
102212#ifdef LOG_LEVEL_1
103- LOG_ERROR ("nosu_find_thread_and_upgrade failed" );
213+ LOG_ERROR (
214+ "nosu_find_thread_and_upgrade failed for thread %u" ,
215+ id );
216+ #endif
217+ neptune_destroy ();
218+ return 0x07 ;
219+ }
220+ } else {
221+ if (HAS_ERR (nosu_attach (id ))) {
222+ #ifdef LOG_LEVEL_1
223+ LOG_ERROR ("nosu_attach failed for process %u" , id );
104224#endif
105225 neptune_destroy ();
106226 return 0x06 ;
0 commit comments