#ifndef __INJECTION_HPP__
#define __INJECTION_HPP__
//Definition Include
#include "ProcessDef.hpp"
namespace Navigator
{
void Process::injectModuleAndCallExport(const std::wstring& dllPath, const std::wstring& exportName) const
{
//Write path into targets memory
SafeRemoteMemory remotePathBuffer(allocateMemory((dllPath.length() + 1) * sizeof(wchar_t)), processHandle_);
writeWideString(remotePathBuffer, dllPath);
//Load kernel32.dll to get LoadLibraryWs address
SafeModule kernel32(LoadLibraryW(L"kernel32.dll"));
if(!kernel32)
throw std::runtime_error("Process::injectModuleAndCallEx port Error : LoadLibraryW() failed");
//Get LoadLibraryW address
DWORD_PTR addressLoadLibaryW = reinterpret_cast<DWORD_PTR>(customGetProcAddress(k ernel32, "LoadLibraryW"));
if (!addressLoadLibaryW)
throw std::runtime_error("Process::injectModuleAndCallEx port Error : customGetProcAddress() failed");
//Create remote Thread and wait until its finished
SafeHandle remoteThread(createThread(addressLoadLibaryW, remotePathBuffer, false, INFINITE));
//Get remote threads exit code
DWORD threadExitCode = 0;
if (!GetExitCodeThread(remoteThread, &threadExitCode))
throw std::runtime_error("Process::injectModuleAndCallEx port Error : GetExitCodeThread() failed");
//Its zero, LoadLibraryW failed
if(!threadExitCode)
throw std::runtime_error("Process::injectLibraryAndCallE xport Error : LoadLibraryW() in remote process failed");
//Call the export, if wanted
if(!exportName.empty() && exportName != L" ")
callExport(dllPath, exportName);
}
FARPROC Process::customGetProcAddress(HMODULE module, const std::string& functionName) const
{
PIMAGE_DOS_HEADER pDosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(module);
if(!pDosHeader || pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
throw std::runtime_error("Process::customGetProcAddress Error : DOS PE header is invalid.");
PIMAGE_NT_HEADERS pNtHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_ca st<PCHAR>(module) + pDosHeader->e_lfanew);
if(pNtHeader->Signature != IMAGE_NT_SIGNATURE)
throw std::runtime_error("Process::customGetProcAddress Error : NT PE header is invalid.");
PVOID pExportDirTemp = reinterpret_cast<PBYTE>(module) + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
PIMAGE_EXPORT_DIRECTORY pExportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(pExportD irTemp);
if(pExportDir->AddressOfNames == NULL)
throw std::runtime_error("Process::customGetProcAddress Error : Symbol names missing entirely.");
PDWORD pNamesRvas = reinterpret_cast<PDWORD>(reinterpret_cast<PBYTE>(m odule) + pExportDir->AddressOfNames);
PWORD pNameOrdinals = reinterpret_cast<PWORD>(reinterpret_cast<PBYTE>(mo dule) + pExportDir->AddressOfNameOrdinals);
PDWORD pFunctionAddresses = reinterpret_cast<PDWORD>( reinterpret_cast<PBYTE>(module) + pExportDir->AddressOfFunctions);
for (DWORD n = 0; n < pExportDir->NumberOfNames; n++)
{
PSTR CurrentName = reinterpret_cast<PSTR>(reinterpret_cast<PBYTE>(mod ule) + pNamesRvas[n]);
if(functionName == CurrentName)
{
WORD Ordinal = pNameOrdinals[n];
return reinterpret_cast<FARPROC>(reinterpret_cast<PBYTE>( module) + pFunctionAddresses[Ordinal]);
}
}
return 0;
}
DWORD Process::callExport(const std::wstring& moduleName, const std::wstring& exportName) const
{
//Get the modules baseaddress
DWORD_PTR moduleBase = getModuleBaseByName(moduleName, true);
if(!moduleBase)
throw std::runtime_error("Process::callExport Error : Module not found");
//Load module as data so we can read the EAT locally
SafeModule module(LoadLibraryExW(moduleName.c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES));
if(!module)
throw std::runtime_error("Process::callExport Error : LoadLibraryExW() failed");
//Get module pointer
DWORD_PTR modulePointer = reinterpret_cast<DWORD_PTR>(module.get());
//Find export
std::string exportNameA(exportName.begin(), exportName.end());
DWORD_PTR exportAddress = reinterpret_cast<DWORD_PTR>(GetProcAddress(module, exportNameA.c_str()));
if (!exportAddress)
throw std::runtime_error("Process::callExport Error : GetProcAddress() failed");
//If image is relocated we need to recalculate the address
if(modulePointer != moduleBase)
exportAddress = moduleBase + (exportAddress - modulePointer);
//Call the remote thread and wait until it terminates
SafeHandle remoteThread(createThread(exportAddress, reinterpret_cast<LPVOID>(moduleBase), false, INFINITE));
//Get thread exit code
DWORD exitCode = 0;
if (!GetExitCodeThread(remoteThread, &exitCode))
throw std::runtime_error("Process::callExport Error : GetExitCodeThread() failed");
return exitCode;
}
}
#endif //__INJECTION_HPP__