Skip to content

Instantly share code, notes, and snippets.

@zv
Created May 22, 2012 01:41
Show Gist options
  • Save zv/2766022 to your computer and use it in GitHub Desktop.
Save zv/2766022 to your computer and use it in GitHub Desktop.
auctionhouse bs
#include <Windows.h>
#include <algorithm>
#include <ctime>
#include <fstream>
#include <memory>
#include <stdexcept>
#include <tuple>
#include <vector>
#include <boost/exception/all.hpp>
#include <boost/format.hpp>
#define ASMJIT_API
#include <HadesMemory/MemoryMgr.hpp>
#include <HadesMemory/Patcher.hpp>
#pragma comment(lib, "libAsmJit")
#pragma comment(lib, "libBeaEngine")
#pragma comment(lib, "libMemory")
#pragma comment(lib, "psapi")
void __stdcall Log(std::string const& message);
void __stdcall Log(boost::format const& fmt);
void __cdecl AddConstructorAddresses();
void __cdecl CtorTrampoline();
DWORD __stdcall CtorHandler(DWORD messagePtr, DWORD ctorAddress);
DWORD const kIDA_BASE = 0x3C910000;
std::string const kLOG_FILE_PATH = "dump-msg-ctor-calls.log";
typedef std::tuple<std::shared_ptr<Hades::Memory::PatchRaw>, DWORD> PatchTuple;
typedef std::tuple<DWORD, std::string> CtorTuple;
typedef std::runtime_error Error;
std::ofstream g_logFile;
std::vector<PatchTuple> g_patches;
std::vector<CtorTuple> g_messageCtors;
Hades::Memory::MemoryMgr g_memory(GetCurrentProcessId());
BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID) {
return TRUE;
}
extern "C" __declspec(dllexport) void Initialize() {
try {
try {
std::remove(kLOG_FILE_PATH.c_str());
} catch (...) {
// lol
}
Log("initialize called on AH.");
Log("adding the constructor classes.");
AddConstructorAddresses();
Log("grabbing dat ass!");
HMODULE const hBattlenetDll = GetModuleHandleA("battle.net.dll");
if (!hBattlenetDll) {
throw Error("houston, we've failed to grab dat ass!!!!");
}
// thanks eon
DWORD const bnetBasicHandle =
reinterpret_cast<DWORD>(hBattlenetDll);
auto const Rebaser = [&](CtorTuple& ctor) {
std::get<0>(ctor) += (bnetBasicHandle - kIDA_BASE);
};
Log("constructor pointers.");
std::for_each(g_messageCtors.begin(), g_messageCtors.end(), Rebaser);
// lol how do we shot SetWindowsHookEx()?
auto const MakeDetour = [&](CtorTuple& ctor) {
DWORD const address = std::get<0>(ctor);
Log(boost::format("Detouring 0x%08x.") % address);
AsmJit::Assembler a;
AsmJit::Label L_getEip = a.newLabel();
a.call(L_getEip);
a.bind(L_getEip);
DWORD trampolineAddr =
reinterpret_cast<DWORD>(&CtorTrampoline);
a.push(trampolineAddr);
a.ret();
Log("assembly is being compiled to an object file.");
BYTE* detourCode = static_cast<BYTE*>(a.make());
Log("successfully found static library links.");
Log("successfully injected the object file into application memory");
if (!detourCode) {
throw Error("AsmJit::Compiler::make failed.");
}
std::vector<BYTE> data(detourCode, detourCode + a.getCodeSize());
auto patch = new Hades::Memory::PatchRaw(g_memory,
reinterpret_cast<PVOID>(address), data);
patch->Apply();
Log("Pushing back the patched tuple to the prior local thread storageida, we're going in raw.");
g_patches.push_back(PatchTuple(
std::shared_ptr<Hades::Memory::PatchRaw>(patch),
address));
};
Log("Detouring the constructors.");
std::for_each(g_messageCtors.begin(), g_messageCtors.end(), MakeDetour);
Log("Successfully detoured constructors.");
Log("We're in.");
} catch (std::exception const& ex) {
Log(boost::diagnostic_information(ex));
} catch (...) {
Log("We're not so in.");
}
}
void __stdcall Log(std::string const& message) {
if (!message.empty()) {
OutputDebugStringA(("*** msg-ctor-calls-log: " + message).c_str());
if (!g_logFile.is_open()) {
g_logFile.open(kLOG_FILE_PATH, std::ofstream::app | std::ofstream::out);
}
g_logFile << boost::str(boost::format("[%08x] %s\n") % std::time(nullptr) % message);
g_logFile.close();
}
}
void __stdcall Log(boost::format const& fmt) {
Log(boost::str(fmt));
}
void __declspec(naked) __cdecl CtorTrampoline() {
__asm {
push ebp
mov ebp, esp
push edx
mov edx, [ebp+0x04]
sub edx, 0x05
push edx
push ecx
call CtorHandler
pop edx
leave
add esp, 0x04
retn
}
}
DWORD __stdcall CtorHandler(DWORD messagePtr, DWORD ctorAddress) {
for (size_t i = 0; i < g_patches.size(); ++i) {
if (std::get<1>(g_patches[i]) == ctorAddress) {
Log(boost::format("0x%08x: %s constructor called.")
% ctorAddress % std::get<1>(g_messageCtors[i]));
std::get<0>(g_patches[i])->Remove();
auto const origCtor = reinterpret_cast<DWORD (__thiscall*)(DWORD)>(
ctorAddress);
DWORD const result = origCtor(messagePtr);
std::get<0>(g_patches[i])->Apply();
return result;
}
}
Log(boost::format("Fatal error: Unknown constructor address 0x%08x.") % ctorAddress);
return 0;
}
void __cdecl AddConstructorAddresses() {
g_messageCtors.push_back(CtorTuple(0x3cc26de0, "ModuleLoadRequest"));
g_messageCtors.push_back(CtorTuple(0x3cc27130, "ModuleLoadResponse"));
g_messageCtors.push_back(CtorTuple(0x3cc27530, "ModuleMessageRequest"));
g_messageCtors.push_back(CtorTuple(0x3cc27a00, "LogonRequest"));
g_messageCtors.push_back(CtorTuple(0x3cc28360, "LogonResponse"));
g_messageCtors.push_back(CtorTuple(0x3cc28770, "AuthModuleVariant"));
g_messageCtors.push_back(CtorTuple(0x3cc28d10, "AuthAgreementLocale"));
g_messageCtors.push_back(CtorTuple(0x3cc2a410, "AuthenticationConfig"));
g_messageCtors.push_back(CtorTuple(0x3cc2af40, "AuthModuleConfig"));
g_messageCtors.push_back(CtorTuple(0x3cc2b260, "AuthAgreement"));
g_messageCtors.push_back(CtorTuple(0x3ccc4d80, "GetLoadRequest"));
g_messageCtors.push_back(CtorTuple(0x3ccc4df0, "GetLoadRequest2"));
g_messageCtors.push_back(CtorTuple(0x3ccc50b0, "ServerState"));
g_messageCtors.push_back(CtorTuple(0x3ccc5120, "ServerState2"));
g_messageCtors.push_back(CtorTuple(0x3ccc5610, "PoolStateRequest"));
g_messageCtors.push_back(CtorTuple(0x3ccc5680, "PoolStateRequest2"));
g_messageCtors.push_back(CtorTuple(0x3ccc5b80, "ServerInfo"));
g_messageCtors.push_back(CtorTuple(0x3ccc5c00, "ServerInfo2"));
g_messageCtors.push_back(CtorTuple(0x3ccc6460, "PoolStateResponse"));
g_messageCtors.push_back(CtorTuple(0x3ccc64e0, "PoolStateResponse2"));
g_messageCtors.push_back(CtorTuple(0x3ccf26b0, "NO_RESPONSE"));
g_messageCtors.push_back(CtorTuple(0x3ccf2720, "NO_RESPONSE2"));
g_messageCtors.push_back(CtorTuple(0x3ccf29e0, "Address"));
g_messageCtors.push_back(CtorTuple(0x3ccf2cf0, "ProcessId"));
g_messageCtors.push_back(CtorTuple(0x3ccf2d50, "ProcessId2"));
g_messageCtors.push_back(CtorTuple(0x3ccf3170, "ObjectAddress"));
g_messageCtors.push_back(CtorTuple(0x3ccf31e0, "ObjectAddress2"));
g_messageCtors.push_back(CtorTuple(0x3ccf3340, "NoData"));
g_messageCtors.push_back(CtorTuple(0x3ccf33b0, "NoData2"));
g_messageCtors.push_back(CtorTuple(0x3ccf39f0, "Address2"));
g_messageCtors.push_back(CtorTuple(0x3cd10aa0, "ConnectRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd10e20, "ConnectResponse"));
g_messageCtors.push_back(CtorTuple(0x3cd10e90, "ConnectResponse2"));
g_messageCtors.push_back(CtorTuple(0x3cd11230, "BoundService"));
g_messageCtors.push_back(CtorTuple(0x3cd11290, "BoundService2"));
g_messageCtors.push_back(CtorTuple(0x3cd11690, "BindResponse"));
g_messageCtors.push_back(CtorTuple(0x3cd11710, "BindResponse2"));
g_messageCtors.push_back(CtorTuple(0x3cd119e0, "EchoRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd11ea0, "EchoResponse"));
g_messageCtors.push_back(CtorTuple(0x3cd12360, "DisconnectRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd12740, "DisconnectNotification"));
g_messageCtors.push_back(CtorTuple(0x3cd12c60, "NullRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd12f90, "EncryptRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd148c0, "BindRequest"));
g_messageCtors.push_back(CtorTuple(0x3cd387a0, "Var"));
g_messageCtors.push_back(CtorTuple(0x3cd38c90, "Resource"));
g_messageCtors.push_back(CtorTuple(0x3cd38d00, "Resource2"));
g_messageCtors.push_back(CtorTuple(0x3cd39230, "ServerAddress"));
g_messageCtors.push_back(CtorTuple(0x3cd392a0, "ServerAddress2"));
g_messageCtors.push_back(CtorTuple(0x3cd396e0, "SupplementalService"));
g_messageCtors.push_back(CtorTuple(0x3cd39740, "SupplementalService2"));
g_messageCtors.push_back(CtorTuple(0x3cd39be0, "ServiceShard"));
g_messageCtors.push_back(CtorTuple(0x3cd39c50, "ServiceShard2"));
g_messageCtors.push_back(CtorTuple(0x3cd3ab20, "Var2"));
g_messageCtors.push_back(CtorTuple(0x3cd3b130, "ProgramResources"));
g_messageCtors.push_back(CtorTuple(0x3cd3b1b0, "ProgramResources2"));
g_messageCtors.push_back(CtorTuple(0x3cd3b450, "ServerSet"));
g_messageCtors.push_back(CtorTuple(0x3cd3b4e0, "ServerSet2"));
g_messageCtors.push_back(CtorTuple(0x3cd3ba30, "ListenPoint"));
g_messageCtors.push_back(CtorTuple(0x3cd3bab0, "ListenPoint2"));
g_messageCtors.push_back(CtorTuple(0x3cd3bd00, "ServiceConfig"));
g_messageCtors.push_back(CtorTuple(0x3cd3bd80, "ServiceConfig2"));
g_messageCtors.push_back(CtorTuple(0x3cd3c260, "RPCServerConfig"));
g_messageCtors.push_back(CtorTuple(0x3cd3c2e0, "RPCServerConfig2"));
g_messageCtors.push_back(CtorTuple(0x3cd3c590, "ProcessConfig"));
g_messageCtors.push_back(CtorTuple(0x3cd3c670, "ProcessConfig2"));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment