Skip to content

Commit

Permalink
Added ASLR support
Browse files Browse the repository at this point in the history
  • Loading branch information
namreeb committed Jun 1, 2017
1 parent 8a5993a commit d380db7
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 78 deletions.
94 changes: 79 additions & 15 deletions dll/InitializeHooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,68 @@

#include <hadesmem/patcher.hpp>

#include <cstdint>

namespace
{
enum class Version
{
Classic = 0,
TBC,
WotLK,
Cata,
Total
};

enum class Offset
{
CVar__Set = 0,
RealmListCVar,
Initialize,
FoV,
Total
};

PVOID GetAddress(Version version, Offset offset)
{
static constexpr std::uint32_t offsets[static_cast<int>(Version::Total)][static_cast<int>(Offset::Total)] =
{
// Classic
{
0x23DF50,
0x82812C,
0x1AB680,
0x4089B4
},
// TBC
{
0x23F6C0,
0x943330,
0x1B3D00,
0x4B5A04
},
// WotLK
{
0x3668C0,
0x879D00,
0x2B0BF0,
0x5E8D88
},
// Cata
{
0x2553B0,
0x9BE800,
0x0CEDF0,
0x00, // not supported. let me know if anyone actually wants this
}
};

auto const baseAddress = reinterpret_cast<std::uint8_t *>(::GetModuleHandle(nullptr));

return baseAddress + offsets[static_cast<int>(version)][static_cast<int>(offset)];
}
}

namespace Classic
{
class CVar {};
Expand All @@ -37,8 +99,8 @@ const char *InitializeHook(hadesmem::PatchDetourBase *detour, void *pThis, char
auto const initialize = detour->GetTrampolineT<InitializeT>();
auto const ret = (*initialize)(pThis);

auto const cvar = *reinterpret_cast<CVar **>(0xC2812C);
auto const set = hadesmem::detail::AliasCast<SetT>(0x63DF50);
auto const cvar = *reinterpret_cast<CVar **>(GetAddress(Version::Classic, Offset::RealmListCVar));
auto const set = hadesmem::detail::AliasCast<SetT>(GetAddress(Version::Classic, Offset::CVar__Set));

auto const pDone = authServer + strlen(authServer) + 1;

Expand All @@ -54,7 +116,7 @@ const char *InitializeHook(hadesmem::PatchDetourBase *detour, void *pThis, char
void ApplyClientInitHook(char *authServer, float fov)
{
auto const proc = hadesmem::Process(::GetCurrentProcessId());
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(0x5AB680);
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(GetAddress(Version::Classic, Offset::Initialize));
auto initializeDetour = new hadesmem::PatchDetour<InitializeT>(proc, initializeOrig,
[authServer] (hadesmem::PatchDetourBase *detour, void *pThis)
{
Expand All @@ -65,7 +127,7 @@ void ApplyClientInitHook(char *authServer, float fov)

if (fov > 0.01f)
{
auto const pFov = reinterpret_cast<PVOID>(0x8089B4);
auto const pFov = GetAddress(Version::Classic, Offset::FoV);
std::vector<std::uint8_t> patchData(sizeof(fov));
memcpy(&patchData[0], &fov, sizeof(fov));
auto patch = new hadesmem::PatchRaw(proc, pFov, patchData);
Expand All @@ -86,8 +148,8 @@ const char *InitializeHook(hadesmem::PatchDetourBase *detour, void *arg, char *A
auto const initialize = detour->GetTrampolineT<InitializeT>();
auto const ret = (*initialize)(arg);

auto const cvar = *reinterpret_cast<CVar **>(0xD43330);
auto const set = hadesmem::detail::AliasCast<SetT>(0x63F6C0);
auto const cvar = *reinterpret_cast<CVar **>(GetAddress(Version::TBC, Offset::RealmListCVar));
auto const set = hadesmem::detail::AliasCast<SetT>(GetAddress(Version::TBC, Offset::CVar__Set));

auto const pDone = AuthServer + strlen(AuthServer) + 1;

Expand All @@ -102,8 +164,10 @@ const char *InitializeHook(hadesmem::PatchDetourBase *detour, void *arg, char *A

void ApplyClientInitHook(char *authServer, float fov)
{
MessageBoxA(nullptr, "Initialize", "DEBUG", 0);

auto const proc = hadesmem::Process(::GetCurrentProcessId());
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(0x5B3D00);
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(GetAddress(Version::TBC, Offset::Initialize));
auto initializeDetour = new hadesmem::PatchDetour<InitializeT>(proc, initializeOrig,
[authServer] (hadesmem::PatchDetourBase *detour, void *pThis)
{
Expand All @@ -114,7 +178,7 @@ void ApplyClientInitHook(char *authServer, float fov)

if (fov > 0.01f)
{
auto const pFov = reinterpret_cast<PVOID>(0x8B5A04);
auto const pFov = GetAddress(Version::TBC, Offset::FoV);
std::vector<std::uint8_t> patchData(sizeof(fov));
memcpy(&patchData[0], &fov, sizeof(fov));
auto patch = new hadesmem::PatchRaw(proc, pFov, patchData);
Expand All @@ -135,8 +199,8 @@ void InitializeHook(hadesmem::PatchDetourBase *detour, void *arg, const char *lo
auto const initialize = detour->GetTrampolineT<InitializeT>();
(*initialize)(arg, locale);

auto const cvar = *reinterpret_cast<CVar **>(0xC79D00);
auto const set = hadesmem::detail::AliasCast<SetT>(0x7668C0);
auto const cvar = *reinterpret_cast<CVar **>(GetAddress(Version::WotLK, Offset::RealmListCVar));
auto const set = hadesmem::detail::AliasCast<SetT>(GetAddress(Version::WotLK, Offset::CVar__Set));

auto const pDone = authServer + strlen(authServer) + 1;

Expand All @@ -150,7 +214,7 @@ void InitializeHook(hadesmem::PatchDetourBase *detour, void *arg, const char *lo
void ApplyClientInitHook(char *authServer, float fov)
{
auto const proc = hadesmem::Process(::GetCurrentProcessId());
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(0x6B0BF0);
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(GetAddress(Version::WotLK, Offset::Initialize));
auto initializeDetour = new hadesmem::PatchDetour<InitializeT>(proc, initializeOrig,
[authServer] (hadesmem::PatchDetourBase *detour, void *arg, const char *locale)
{
Expand All @@ -161,7 +225,7 @@ void ApplyClientInitHook(char *authServer, float fov)

if (fov > 0.01f)
{
auto const pFov = reinterpret_cast<PVOID>(0x9E8D88);
auto const pFov = GetAddress(Version::WotLK, Offset::FoV);
std::vector<std::uint8_t> patchData(sizeof(fov));
memcpy(&patchData[0], &fov, sizeof(fov));
auto patch = new hadesmem::PatchRaw(proc, pFov, patchData);
Expand All @@ -182,8 +246,8 @@ void InitializeHook(hadesmem::PatchDetourBase *detour, char *authServer)
auto const initialize = detour->GetTrampolineT<InitializeT>();
(*initialize)();

auto const cvar = *reinterpret_cast<CVar **>(0xDBE800);
auto const set = hadesmem::detail::AliasCast<SetT>(0x6553B0);
auto const cvar = *reinterpret_cast<CVar **>(GetAddress(Version::Cata, Offset::RealmListCVar));
auto const set = hadesmem::detail::AliasCast<SetT>(GetAddress(Version::Cata, Offset::CVar__Set));

auto const pDone = authServer + strlen(authServer) + 1;

Expand All @@ -197,7 +261,7 @@ void InitializeHook(hadesmem::PatchDetourBase *detour, char *authServer)
void ApplyClientInitHook(char *authServer, float fov)
{
auto const proc = hadesmem::Process(::GetCurrentProcessId());
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(0x4CEDF0);
auto const initializeOrig = hadesmem::detail::AliasCast<InitializeT>(GetAddress(Version::Cata, Offset::Initialize));
auto initializeDetour = new hadesmem::PatchDetour<InitializeT>(proc, initializeOrig,
[authServer](hadesmem::PatchDetourBase *detour)
{
Expand Down
64 changes: 1 addition & 63 deletions dll/domainloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
*/

#include "InitializeHooks.hpp"

#include <Windows.h>
#include <metahost.h>
#include <CorError.h>
Expand All @@ -34,15 +32,9 @@
#include <cassert>
#include <cstdint>

#define BUILD_CLASSIC 5875
#define BUILD_TBC 8606
#define BUILD_WOTLK 12340
#define BUILD_CATA 15595

#pragma comment(lib, "mscoree.lib")

#define MB(s) MessageBox(nullptr, s, nullptr, MB_OK)
#define THROW_IF(expr, message) if (expr) { throw std::exception(message); }

namespace
{
Expand Down Expand Up @@ -95,7 +87,7 @@ unsigned __stdcall ThreadMain(const wchar_t *dllLocation)
// Execute the Main func in the domain manager, this will block indefinitely. Hence why we're in our own thread
// TODO: Add parameters for type and method names
DWORD dwRet = 0;
hr = clrHost->ExecuteInDefaultAppDomain(dllLocation, L"wowreeb.DomainManager.EntryPoint", L"Main", L"", &dwRet);
hr = clrHost->ExecuteInDefaultAppDomain(dllLocation, L"wcs.DomainManager.EntryPoint", L"Main", L"", &dwRet);

delete[] dllLocation;

Expand Down Expand Up @@ -144,60 +136,6 @@ HMODULE GetCurrentModule()
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, reinterpret_cast<LPCTSTR>(GetCurrentModule), &hModule);
return hModule;
}

unsigned int GetBuild()
{
wchar_t filename[255];
DWORD size = sizeof(filename)/sizeof(filename[0]);

THROW_IF(!QueryFullProcessImageName(::GetCurrentProcess(), 0, reinterpret_cast<LPWSTR>(&filename), &size), "QueryFullProcessImageName failed");

size = GetFileVersionInfoSize(filename, nullptr);

THROW_IF(!size, "Bad VersionInfo size");

std::vector<std::uint8_t> versionInfo(size);

THROW_IF(!::GetFileVersionInfo(filename, 0, size, &versionInfo[0]), "GetFileVersionInfo failed");

VS_FIXEDFILEINFO *verInfo;
UINT length;

THROW_IF(!::VerQueryValue(&versionInfo[0], L"\\", reinterpret_cast<LPVOID *>(&verInfo), &length), "VerQueryValue failed");
THROW_IF(verInfo->dwSignature != 0xFEEF04BD, "Incorrect version signature");

return static_cast<unsigned int>(verInfo->dwFileVersionLS & 0xFFFF);
}
}

// this function is executed in the context of the wow process
extern "C" __declspec(dllexport) unsigned int Load(char *authServer, float fov)
{
if (!authServer)
return EXIT_FAILURE;

auto const build = GetBuild();

switch (build)
{
case BUILD_CLASSIC:
Classic::ApplyClientInitHook(authServer, fov);
break;
case BUILD_TBC:
TBC::ApplyClientInitHook(authServer, fov);
break;
case BUILD_WOTLK:
WOTLK::ApplyClientInitHook(authServer, fov);
break;
case BUILD_CATA:
Cata::ApplyClientInitHook(authServer, fov);
break;
default:
assert(false);
break;
}

return EXIT_SUCCESS;
}

// this function is executed in the context of the wow process
Expand Down
63 changes: 63 additions & 0 deletions dll/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
*/

#include "InitializeHooks.hpp"

#include <hadesmem/injector.hpp>
#include <hadesmem/call.hpp>
#include <hadesmem/alloc.hpp>
Expand Down Expand Up @@ -87,6 +89,32 @@ void EjectionPoll(hadesmem::Process process, HMODULE dll, PVOID remoteBuffer, si
std::this_thread::sleep_for(std::chrono::milliseconds(100));
} while (true);
}

#define THROW_IF(expr, message) if (expr) { throw std::exception(message); }

unsigned int GetBuild()
{
wchar_t filename[255];
DWORD size = sizeof(filename) / sizeof(filename[0]);

THROW_IF(!QueryFullProcessImageName(::GetCurrentProcess(), 0, reinterpret_cast<LPWSTR>(&filename), &size), "QueryFullProcessImageName failed");

size = GetFileVersionInfoSize(filename, nullptr);

THROW_IF(!size, "Bad VersionInfo size");

std::vector<std::uint8_t> versionInfo(size);

THROW_IF(!::GetFileVersionInfo(filename, 0, size, &versionInfo[0]), "GetFileVersionInfo failed");

VS_FIXEDFILEINFO *verInfo;
UINT length;

THROW_IF(!::VerQueryValue(&versionInfo[0], L"\\", reinterpret_cast<LPVOID *>(&verInfo), &length), "VerQueryValue failed");
THROW_IF(verInfo->dwSignature != 0xFEEF04BD, "Incorrect version signature");

return static_cast<unsigned int>(verInfo->dwFileVersionLS & 0xFFFF);
}
}

// this function is executed in the context of the launcher process
Expand Down Expand Up @@ -167,4 +195,39 @@ extern "C" __declspec(dllexport) unsigned int Inject(const wchar_t *exePath, con
}

return 0;
}

#define BUILD_CLASSIC 5875
#define BUILD_TBC 8606
#define BUILD_WOTLK 12340
#define BUILD_CATA 15595

// this function is executed in the context of the wow process
extern "C" __declspec(dllexport) unsigned int Load(char *authServer, float fov)
{
if (!authServer)
return EXIT_FAILURE;

auto const build = GetBuild();

switch (build)
{
case BUILD_CLASSIC:
Classic::ApplyClientInitHook(authServer, fov);
break;
case BUILD_TBC:
TBC::ApplyClientInitHook(authServer, fov);
break;
case BUILD_WOTLK:
WOTLK::ApplyClientInitHook(authServer, fov);
break;
case BUILD_CATA:
Cata::ApplyClientInitHook(authServer, fov);
break;
default:
assert(false);
break;
}

return EXIT_SUCCESS;
}

0 comments on commit d380db7

Please sign in to comment.