Created
May 22, 2012 01:41
-
-
Save zv/2766022 to your computer and use it in GitHub Desktop.
auctionhouse bs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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