1+ // C Libraries
2+ #include <string.h>
3+
4+ // WinAPI Libraries
5+ #include <Windows.h>
6+ #include <tchar.h>
7+ #include <TlHelp32.h>
8+ #include <Shlwapi.h>
9+
10+ #ifdef UNICODE
11+ #define LOAD_LIBRARY_PROCNAME "LoadLibraryW"
12+ #else
13+ #define LOAD_LIBRARY_PROCNAME "LoadLibraryA"
14+ #endif
15+
16+ DWORD GetPIDByName (LPCTSTR lpszProcessName )
17+ {
18+ PROCESSENTRY32 entry ;
19+ entry .dwSize = sizeof (entry );
20+
21+ HANDLE snapshot = CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS , 0 );
22+
23+ if (Process32First (snapshot , & entry ))
24+ while (Process32Next (snapshot , & entry ))
25+ if (!_tcsicmp (entry .szExeFile , lpszProcessName ))
26+ {
27+ CloseHandle (snapshot );
28+ return entry .th32ProcessID ;
29+ };
30+
31+ return 0 ;
32+ }
33+
34+ int _tmain (int argc ,LPTSTR argv [])
35+ {
36+ TCHAR lpszDllNameBuffer [MAX_PATH ];
37+
38+ LPCTSTR lpszProcessName = argv [1 ], lpszDllName = argv [2 ];
39+
40+ for (int i = 1 ;i < argc ;i ++ )
41+ {
42+ if (!_tcsicmp (argv [i ],TEXT ("-process" )) || !_tcsicmp (argv [i ],TEXT ("-proc" )) || !_tcsicmp (argv [i ],TEXT ("-procname" )))
43+ lpszProcessName = argv [++ i ];
44+
45+ if (!_tcsicmp (argv [i ],TEXT ("-dll" )) || !_tcsicmp (argv [i ],TEXT ("-library" )))
46+ lpszDllName = argv [++ i ];
47+ }
48+
49+ if (PathIsRelative (lpszDllName ))
50+ {
51+ DWORD dwResult = SearchPath (NULL ,lpszDllName ,NULL ,MAX_PATH ,lpszDllNameBuffer ,NULL );
52+ lpszDllName = lpszDllNameBuffer ;
53+
54+ if (!dwResult )
55+ {
56+ DWORD dwError = GetLastError ();
57+
58+ LPTSTR lpBuffer = NULL ;
59+
60+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL , dwError , MAKELANGID (LANG_NEUTRAL , SUBLANG_DEFAULT ), (LPTSTR )& lpBuffer , 0 , NULL );
61+
62+ _tprintf (TEXT ("Failed to find dll: [%lu] %s\n" ),dwError ,lpBuffer );
63+
64+ return EXIT_FAILURE ;
65+ }
66+ }
67+
68+ DWORD dwPid = GetPIDByName (lpszProcessName );
69+
70+ if (dwPid == 0 )
71+ {
72+ _tprintf (TEXT ("Failed to get process id (%s)\n" ),lpszProcessName );
73+
74+ return EXIT_FAILURE ;
75+ }
76+
77+ HANDLE hProcess = OpenProcess (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ , FALSE, dwPid );
78+
79+ if (hProcess == NULL )
80+ {
81+ _tprintf (TEXT ("Failed to get process handle\n" ));
82+
83+ return EXIT_FAILURE ;
84+ }
85+
86+ size_t uSize = (SIZE_T )((_tcsclen (lpszDllName ) + 1 ) * sizeof (TCHAR ));
87+
88+ LPVOID lpMemory = VirtualAllocEx (hProcess ,NULL ,uSize ,MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
89+
90+ if (lpMemory == NULL )
91+ {
92+ _tprintf (TEXT ("Failed to allocate memory\n" ));
93+
94+ CloseHandle (hProcess );
95+
96+ return EXIT_FAILURE ;
97+ }
98+
99+ if (!WriteProcessMemory (hProcess ,lpMemory ,(LPCVOID )(lpszDllName ),uSize ,0u ))
100+ {
101+ DWORD dwError = GetLastError ();
102+
103+ LPTSTR lpBuffer = NULL ;
104+
105+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL , dwError , MAKELANGID (LANG_NEUTRAL , SUBLANG_DEFAULT ), (LPTSTR )& lpBuffer , 0 , NULL );
106+
107+ _tprintf (TEXT ("Failed to write memory: [%lu] %s\n" ),dwError ,lpBuffer );
108+
109+ CloseHandle (hProcess );
110+
111+ return EXIT_FAILURE ;
112+ }
113+
114+ HANDLE hKernel32 = GetModuleHandle (TEXT ("kernel32.dll" ));
115+
116+ if (hKernel32 == NULL )
117+ {
118+ _tprintf (TEXT ("Failed to get Kernel32.dll module handle\n" ));
119+
120+ CloseHandle (hProcess );
121+
122+ return EXIT_FAILURE ;
123+ }
124+
125+ LPTHREAD_START_ROUTINE lpLoadLibrary = (LPTHREAD_START_ROUTINE )GetProcAddress (hKernel32 ,LOAD_LIBRARY_PROCNAME );
126+
127+ if (lpLoadLibrary == NULL )
128+ {
129+ _tprintf (TEXT ("Failed to get %s entry inside Kernel32.dll\n" ),TEXT (LOAD_LIBRARY_PROCNAME ));
130+
131+ CloseHandle (hProcess );
132+
133+ return EXIT_FAILURE ;
134+ }
135+
136+ HANDLE hThread = CreateRemoteThread (hProcess ,NULL ,0u ,lpLoadLibrary ,lpMemory ,0 ,NULL );
137+
138+ if (hThread == NULL )
139+ {
140+ DWORD dwError = GetLastError ();
141+
142+ LPTSTR lpBuffer = NULL ;
143+
144+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL , dwError , MAKELANGID (LANG_NEUTRAL , SUBLANG_DEFAULT ), (LPTSTR )& lpBuffer , 0 , NULL );
145+
146+ _tprintf (TEXT ("Failed to create remote thread: [%lu] %s\n" ),dwError ,lpBuffer );
147+
148+ CloseHandle (hProcess );
149+
150+ return EXIT_FAILURE ;
151+ }
152+
153+ WaitForSingleObject (hThread , INFINITE );
154+
155+ DWORD dwExitCode ;
156+
157+ if (!GetExitCodeThread (hThread ,& dwExitCode ))
158+ {
159+ _tprintf (TEXT ("Failed to get thread exit code" ));
160+
161+ CloseHandle (hProcess );
162+
163+ return EXIT_FAILURE ;
164+ }
165+
166+ if (!dwExitCode )
167+ {
168+ _tprintf (TEXT ("Failed to call %s in remote process %s" ),TEXT (LOAD_LIBRARY_PROCNAME ),lpszProcessName );
169+
170+ CloseHandle (hProcess );
171+
172+ return EXIT_FAILURE ;
173+ }
174+
175+ _tprintf (TEXT ("Successfully injected \"%s\" into process [%lu] %s\n" ),lpszDllName ,dwPid ,lpszProcessName );
176+
177+ return EXIT_SUCCESS ;
178+ }
0 commit comments