1111 * furnished to do so, subject to the following conditions:
1212 *
1313 * The above copyright notice and this permission notice shall be included in all
14- * copies or substantial portions of the Software.
14+ * copies or substantial portions of the Software.
1515 *
1616 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1717 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2222 * SOFTWARE.
2323 */
2424
25+ #include <stdio.h>
26+ #include <stdlib.h>
27+ #include <string.h>
28+ #include <windows.h>
29+
2530#include "nerror.h"
2631#include "ntosutils.h"
2732#include "ntmem.h"
2833#include "ntosutilswin.h"
2934
35+ void print_usage () {
36+ printf ("GhostInjector - DLL Injection tool for Windows processes\n\n" );
37+ printf ("Examples:\n" );
38+ printf (" ghostinjector.exe 1234 mydll.dll\n" );
39+ printf (" ghostinjector.exe 5678 first.dll second.dll third.dll\n\n" );
40+ printf ("Usage:\n" );
41+ printf (" ghostinjector.exe <process_id> <dll_path> [dll_path2 ...]\n" );
42+ printf (" ghostinjector.exe -h | --help\n" );
43+ }
44+
3045int main (int argc , char * argv [])
3146{
3247 if (HAS_ERR (neptune_init ()))
3348 return EXIT_FAILURE ;
3449
35- if (argc < 3 ) {
36- #ifdef LOG_LEVEL_1
37- LOG_INFO (
38- "Usage: %s <thread_id:DWORD or process_id:DWORD> <dll_path:string>" ,
39- argv [0 ]);
40- #endif /* ifdef LOG_LEVEL_1 */
41-
42- return 0x10 ;
50+ if (argc < 3 || strcmp (argv [1 ], "-h" ) == 0 || strcmp (argv [1 ], "--help" ) == 0 ) {
51+ print_usage ();
52+ neptune_destroy ();
53+ return EXIT_SUCCESS ;
4354 }
4455
45- #ifdef LOG_LEVEL_1
46- LOG_INFO ("Neptune initilaized!" );
47- #endif /* ifdef LOG_LEVEL_1 */
48-
49- const char * dll_path = argv [2 ];
50- const char * id_str = argv [1 ];
56+ uint32_t id = atoi (argv [1 ]);
5157
5258#ifdef LOG_LEVEL_1
53- LOG_INFO ("DLL Path(%s)" , dll_path );
54- #endif /* ifdef LOG_LEVEL_1 */
55-
56- DWORD id = atoi ( id_str );
59+ LOG_INFO ("Neptune initialized!" );
60+ LOG_INFO ( "ID: %u" , id );
61+ LOG_INFO ( "Number of DLLs to inject: %d" , argc - 2 );
62+ #endif
5763
58- if (id < 0 ) {
64+ if (id == 0 ) {
5965#ifdef LOG_LEVEL_1
6066 LOG_ERROR ("Invalid id: must be greater than 0" );
61- #endif /* ifdef LOG_LEVEL_1 */
62-
67+ #endif
6368 neptune_destroy ();
6469 return 0x11 ;
6570 }
@@ -68,85 +73,86 @@ int main(int argc, char *argv[])
6873 if (kernel32 == NULL ) {
6974#ifdef LOG_LEVEL_1
7075 LOG_ERROR ("GetModuleHandleA failed" );
71- #endif /* ifdef LOG_LEVEL_1 */
72-
76+ #endif
7377 neptune_destroy ();
7478 return 0x20 ;
7579 }
7680
77- void * load_library_func = GetProcAddress (kernel32 , "LoadLibraryA" );
81+ FARPROC load_library_func = GetProcAddress (kernel32 , "LoadLibraryA" );
7882 if (load_library_func == NULL ) {
7983#ifdef LOG_LEVEL_1
8084 LOG_ERROR ("GetProcAddress failed" );
81- #endif /* ifdef LOG_LEVEL_1 */
82-
85+ #endif
86+ neptune_destroy ();
8387 return 0x21 ;
8488 }
8589
8690#ifdef LOG_LEVEL_1
87- LOG_INFO ("LoadLibraryA=%p" , load_library_func );
88- #endif /* ifdef LOG_LEVEL_1 */
91+ LOG_INFO ("LoadLibraryA=%p" , ( void * ) load_library_func );
92+ #endif
8993
90- // Initialize the ntutils layer for working on the target thread.
9194 if (HAS_ERR (nosu_attach (id ))) {
9295#ifdef LOG_LEVEL_1
9396 LOG_WARN ("nosu_attach failed" );
94- #endif /* ifdef LOG_LEVEL_1 */
97+ #endif
9598
9699 if (HAS_ERR (nosu_find_thread_and_upgrade (id ))) {
97100#ifdef LOG_LEVEL_1
98101 LOG_ERROR ("nosu_find_thread_and_upgrade failed" );
99- #endif /* ifdef LOG_LEVEL_1 */
100-
102+ #endif
101103 neptune_destroy ();
102104 return 0x06 ;
103105 }
104106 }
105107
106- size_t dll_path_len = strlen ( dll_path );
107- size_t dll_path_size = dll_path_len + 1 ;
108+ for ( int i = 2 ; i < argc ; i ++ ) {
109+ const char * dll_path = argv [ i ] ;
108110
109- ntmem_t * ntmem = ntm_create_with_alloc_ex (dll_path_size + 1 );
110- if (ntmem == NULL ) {
111111#ifdef LOG_LEVEL_1
112- LOG_ERROR ( "ntm_create failed" );
113- #endif /* ifdef LOG_LEVEL_1 */
112+ LOG_INFO ( "Injecting DLL [%d/%d]: %s" , i - 1 , argc - 2 , dll_path );
113+ #endif
114114
115- ntu_destroy ();
116- neptune_destroy ();
117- return 0x92 ;
118- }
115+ size_t dll_path_len = strlen (dll_path );
116+ size_t dll_path_size = dll_path_len + 1 ;
119117
120- // Copy the converted string into memory that will be pushed to the target.
121- void * local = NTM_LOCAL (ntmem );
122- memcpy (local , dll_path , dll_path_size );
123-
124- // Push the DLL path into the remote memory.
125- void * dll_path_addr = ntm_push (ntmem );
126- if (dll_path_addr == NULL ) {
118+ ntmem_t * ntmem = ntm_create_with_alloc_ex (dll_path_size + 1 );
119+ if (ntmem == NULL ) {
127120#ifdef LOG_LEVEL_1
128- LOG_ERROR ("ntm_push failed" );
129- #endif /* ifdef LOG_LEVEL_1 */
121+ LOG_ERROR ("ntm_create failed for %s" , dll_path );
122+ #endif
123+ continue ;
124+ }
130125
131- ntu_destroy ();
132- neptune_destroy ();
133- return 0x93 ;
134- }
126+ void * local = NTM_LOCAL (ntmem );
127+ memcpy (local , dll_path , dll_path_size );
135128
129+ void * dll_path_addr = ntm_push (ntmem );
130+ if (dll_path_addr == NULL ) {
136131#ifdef LOG_LEVEL_1
137- LOG_INFO ( "DLL Path Address(%p) " , dll_path_addr );
138- #endif /* ifdef LOG_LEVEL_1 */
139-
140- // Call LoadLibraryA inside the target thread context.
141- void * load_library_ret = ntu_ucall ( load_library_func , dll_path_addr );
132+ LOG_ERROR ( "ntm_push failed for %s " , dll_path );
133+ #endif
134+ ntm_delete ( ntmem );
135+ continue ;
136+ }
142137
143138#ifdef LOG_LEVEL_1
144- LOG_INFO ("Return Value(%p)" , load_library_ret );
145- #endif /* ifdef LOG_LEVEL_1 */
139+ LOG_INFO ("DLL Path Address(%p)" , dll_path_addr );
140+ #endif
141+
142+ void * load_library_ret = ntu_ucall ((void * )load_library_func , dll_path_addr );
146143
147- ntm_delete (ntmem );
144+ #ifdef LOG_LEVEL_1
145+ LOG_INFO ("LoadLibrary returned: %p" , load_library_ret );
146+ if (load_library_ret != NULL ) {
147+ LOG_INFO ("Successfully injected: %s" , dll_path );
148+ } else {
149+ LOG_ERROR ("Failed to inject: %s" , dll_path );
150+ }
151+ #endif
148152
153+ ntm_delete (ntmem );
154+ }
149155 ntu_destroy ();
150156 neptune_destroy ();
151157 return EXIT_SUCCESS ;
152- }
158+ }
0 commit comments