Skip to content

Commit ddf9abd

Browse files
authored
Merge pull request #25 from bot-1450/master
Fix Dll Ejection
2 parents 8e7314c + 78eb433 commit ddf9abd

File tree

2 files changed

+39
-20
lines changed

2 files changed

+39
-20
lines changed

Injector/Injector.cpp

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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
141154
void 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
{

Injector/Injector.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ class Injector
1717
static Injector* Get();
1818

1919
// Check if the library is injected.
20-
BYTE* GetModuleBaseAddress(DWORD ProcID, const std::wstring& Path);
21-
BYTE* GetModuleBaseAddress(DWORD ProcID, const std::string& Path);
20+
BYTE* GetModuleBaseAddress(HANDLE Process, const std::wstring& Path);
21+
BYTE* GetModuleBaseAddress(HANDLE Process, const std::string& Path);
2222

2323
// Inject library
2424
void InjectLib(DWORD ProcID, const std::wstring& Path);

0 commit comments

Comments
 (0)