I finally got some time to play with Cypher's HadesMem library. I noticed that the new Injector class doesn't have a method to create a process and inject like his old Loader code did. I ripped the code from his old loader and reworked it to work with HadesMem. I thought I would share it.
Code:
// C++ Standard Library
#include <limits>
#include <memory>
#include <fstream>
#include <iterator>
#include <iostream>
// HadesMem
#include "HadesMem/Memory.h"
#include "HadesMem/EnsureCleanup.h"
#include "HadesMem/Injector.h"
// Windows API
#include <Windows.h>
// Create suspended process and use HadesMem to inject DLL
DWORD CreateAndInject(std::shared_ptr<Hades::Memory::MemoryMgr>&
MyMemory, std::wstring const& Path, std::wstring const& Args,
std::wstring const& Module, std::string const& Export)
{
// Set up structures for CreateProcess
STARTUPINFOW WoWSi;
ZeroMemory(&WoWSi, sizeof(WoWSi));
WoWSi.cb = sizeof(WoWSi);
PROCESS_INFORMATION WoWPi;
ZeroMemory(&WoWPi, sizeof(WoWPi));
// Ensure cleanup
Hades::Util::EnsureCloseHandle(WoWPi.hProcess);
Hades::Util::EnsureCloseHandle(WoWPi.hThread);
// Construct command line.
std::wstring CommandLine(L"\"" + Path + L"\" " + Args);
// Copy command line to buffer
std::vector<wchar_t> ProcArgs(CommandLine.begin(), CommandLine.end());
// Null-terminate buffer
ProcArgs.push_back(L'\0');
// Attempt process creation
if (!CreateProcessW(Path.c_str(), &ProcArgs[0], NULL, NULL, FALSE,
CREATE_SUSPENDED, NULL, NULL, &WoWSi, &WoWPi))
{
throw std::runtime_error("Injector::InjectLib: Could not create process.");
}
// Exception handling
try
{
// Create memory manager
MyMemory.reset(new Hades::Memory::MemoryMgr(WoWPi.dwProcessId));
// Create DLL injector
Hades::Memory::Injector MyInjector(*MyMemory);
// Inject DLL
HMODULE ModBase = MyInjector.InjectDll(Module);
std::wcout << "Module Base: " << ModBase << "." << std::endl;
// If export has been specified
if (!Export.empty())
{
// Call remote export
DWORD ExportRet = MyInjector.CallExport(Module, ModBase, Export);
std::wcout << "Export Returned: " << ExportRet << "." << std::endl;
}
}
// Catch exceptions
catch (std::exception const& /*e*/)
{
// Terminate process if injection failed
TerminateProcess(WoWPi.hProcess, 0);
// Rethrow exception
throw;
}
// Success! Let the process continue execution.
ResumeThread(WoWPi.hThread);
// Return ProcID for use in further calls
return WoWPi.dwProcessId;
}
// Program entry-point.
int wmain(int /*argc*/, wchar_t* /*argv*/[], wchar_t* /*envp*/[])
{
try
{
std::wcout << "Welcome to WoWHack." << std::endl;
// create memory manager
std::shared_ptr<Hades::Memory::MemoryMgr> MyMemory;
// create process, attach HadesMem, and inject DLL
CreateAndInject(MyMemory,L"c:\\wow\\wow.exe",L"",L"HadesMemHackDll_IA32.dll","_Initialize@4");
}
catch (boost::exception const& e)
{
// Dump error information
std::cout << boost::diagnostic_information(e);
}
catch (std::exception const& e)
{
// Dump error information
std::wcout << "Error! " << e.what() << std::endl;
}
// Pause for input before continuing
std::wcin.clear();
std::wcin.sync();
std::wcin.get();
}