11// Windows Includes
22#include < Windows.h>
33#include < TlHelp32.h>
4+ #include < Psapi.h>
45#include < malloc.h>
56#include < Tchar.h>
67
@@ -43,36 +44,47 @@ bool Injector::icompare(const std::wstring& a, const std::wstring& b) const
4344 return false ;
4445}
4546
46- // Check if a module is injected via process ID , and return the base address
47- BYTE* Injector::GetModuleBaseAddress (DWORD ProcID , const std::wstring& Path) {
47+ // Check if a module is injected via process handle , and return the base address
48+ BYTE* Injector::GetModuleBaseAddress (HANDLE Process , const std::wstring& Path) {
4849 // Grab a new snapshot of the process
49- EnsureCloseHandle Snapshot (CreateToolhelp32Snapshot (TH32CS_SNAPMODULE, ProcID));
50- if (Snapshot == INVALID_HANDLE_VALUE)
51- throw std::runtime_error (" Could not get module snapshot for remote process." );;
50+ std::vector<HMODULE> Modules;
51+ DWORD SizeNeeded = 0 ;
52+ do
53+ {
54+ Modules.reserve (SizeNeeded / sizeof (HMODULE));
55+ if (!EnumProcessModules (Process, Modules.data (), Modules.capacity () * sizeof (HMODULE), &SizeNeeded))
56+ throw std::runtime_error (" Could not get module snapshot for remote process." );
57+ } while (SizeNeeded > Modules.capacity () * sizeof (HMODULE));
58+ // Make capacity into size
59+ Modules = std::vector<HMODULE>(Modules.begin (), Modules.begin () + SizeNeeded / sizeof (HMODULE));
5260
5361 // Get the HMODULE of the desired library
54- MODULEENTRY32W ModEntry = { sizeof (ModEntry) };
5562 bool Found = false ;
56- BOOL bMoreMods = Module32FirstW (Snapshot, &ModEntry);
57- for (; bMoreMods; bMoreMods = Module32NextW (Snapshot, &ModEntry))
63+ for (const auto &Module : Modules)
5864 {
59- std::wstring ModuleName (ModEntry.szModule );
60- std::wstring ExePath (ModEntry.szExePath );
65+ WCHAR ModuleName[MAX_PATH];
66+ WCHAR ExePath[MAX_PATH];
67+ // The size of the ModuleName buffer, in characters.
68+ if (!GetModuleBaseNameW (Process, Module, ModuleName, sizeof (ModuleName) / sizeof (WCHAR)))
69+ throw std::runtime_error (" Could not get ModuleName." );
70+ // The size of the ExePath buffer, in characters.
71+ if (!GetModuleFileNameExW (Process, Module, ExePath, sizeof (ExePath) / sizeof (WCHAR)))
72+ throw std::runtime_error (" Could not get ExePath." );
6173 Found = (icompare (ModuleName, Path) || icompare (ExePath, Path));
6274 if (Found)
63- return ModEntry. modBaseAddr ;
75+ return reinterpret_cast <BYTE*>(Module) ;
6476 }
6577 return nullptr ;
6678}
6779
6880// MBCS version of GetModuleBaseAddress
69- BYTE* Injector::GetModuleBaseAddress (DWORD ProcID , const std::string& Path)
81+ BYTE* Injector::GetModuleBaseAddress (HANDLE Process , const std::string& Path)
7082{
7183 // Convert path to unicode
7284 std::wstring UnicodePath (Path.begin (),Path.end ());
7385
7486 // Call the Unicode version of the function to actually do the work.
75- return GetModuleBaseAddress (ProcID , UnicodePath);
87+ return GetModuleBaseAddress (Process , UnicodePath);
7688}
7789
7890// Injects a module (fully qualified path) via process id
@@ -81,6 +93,7 @@ void Injector::InjectLib(DWORD ProcID, const std::wstring& Path)
8193 // Get a handle for the target process.
8294 EnsureCloseHandle Process (OpenProcess (
8395 PROCESS_QUERY_INFORMATION | // Required by Alpha
96+ PROCESS_VM_READ | // For EnumProcessModules
8497 PROCESS_CREATE_THREAD | // For CreateRemoteThread
8598 PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
8699 PROCESS_VM_WRITE, // For WriteProcessMemory
@@ -123,7 +136,7 @@ void Injector::InjectLib(DWORD ProcID, const std::wstring& Path)
123136 // it's possible that we get a thread exit code of 0 with a non-zero HMODULE,
124137 // as the thread exit code is a DWORD, which is smaller than an HMODULE - so,
125138 // check the process list.
126- if (!GetModuleBaseAddress (ProcID , Path))
139+ if (!GetModuleBaseAddress (Process , Path))
127140 throw std::runtime_error (" Call to LoadLibraryW in remote process failed." );
128141}
129142
@@ -140,19 +153,20 @@ void Injector::InjectLib(DWORD ProcID, const std::string& Path)
140153// Ejects a module (fully qualified path) via process id
141154void Injector::EjectLib (DWORD ProcID, const std::wstring& Path)
142155{
143- const auto BaseAddress = GetModuleBaseAddress (ProcID, Path);
144- if (!BaseAddress)
145- throw std::runtime_error (" Could not find module in remote process." );;
146-
147156 // Get a handle for the target process.
148157 EnsureCloseHandle Process (OpenProcess (
149158 PROCESS_QUERY_INFORMATION |
159+ PROCESS_VM_READ |
150160 PROCESS_CREATE_THREAD |
151161 PROCESS_VM_OPERATION, // For CreateRemoteThread
152162 FALSE , ProcID));
153163 if (!Process)
154164 throw std::runtime_error (" Could not get handle to process." );
155165
166+ const auto BaseAddress = GetModuleBaseAddress (Process, Path);
167+ if (!BaseAddress)
168+ throw std::runtime_error (" Could not find module in remote process." );;
169+
156170 // Get the real address of LoadLibraryW in Kernel32.dll
157171 HMODULE hKernel32 = GetModuleHandle (TEXT (" Kernel32" ));
158172 if (hKernel32 == NULL )
@@ -242,6 +256,11 @@ std::tstring Injector::GetPath( const std::tstring& ModuleName )
242256 ModulePath = ModulePath.substr (0 , ModulePath.rfind ( _T (" \\ " ) ) + 1 );
243257 ModulePath.append (ModuleName);
244258
259+ TCHAR FullModulePath[MAX_PATH];
260+ if (!GetFullPathName (ModulePath.c_str (), sizeof (FullModulePath) / sizeof (TCHAR), FullModulePath, NULL ))
261+ throw std::runtime_error (" Could not get full path to module." );
262+ ModulePath = std::tstring (&FullModulePath[0 ]);
263+
245264 // Check path/file is valid
246265 if (GetFileAttributes (ModulePath.c_str ()) == INVALID_FILE_ATTRIBUTES)
247266 {
0 commit comments