Last active
May 26, 2017 11:53
-
-
Save YaLTeR/d11c200eaed504177335 to your computer and use it in GitHub Desktop.
Ready to use build: https://yadi.sk/d/ZHvALFzz3JTXAF
This file contains hidden or 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
#define WIN32_LEAN_AND_MEAN | |
#include <Windows.h> | |
#include <process.h> | |
#include <Psapi.h> | |
#include <cstdint> | |
#include <cstring> | |
#include <string> | |
using std::uint8_t; | |
using std::size_t; | |
using std::uintptr_t; | |
using namespace std::literals; | |
#include <MinHook.h> | |
struct module_info | |
{ | |
HMODULE handle; | |
LPVOID base; | |
DWORD size; | |
}; | |
struct pattern | |
{ | |
const uint8_t* bytes; | |
const char* mask; | |
}; | |
constexpr uint8_t bytes_SetSignonState[] = { 0x55, 0x8B, 0xEC, 0x56, 0x57, 0x8B, 0x7D, 0x08, 0x8B, 0xF1, 0x83, 0xFF, 0x02, 0x75, 0x71, 0x8B, 0x46, 0x04, 0x8B, 0x90, 0xA0, 0x00, 0x00, 0x00, 0x8D, 0x4E, 0x04, 0xFF, 0xD2, 0x84, 0xC0, 0x75 }; | |
constexpr pattern pattern_SetSignonState = { | |
bytes_SetSignonState, | |
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
}; | |
constexpr uint8_t bytes_SomeDemoFunction[] = { 0x55, 0x8B, 0xEC, 0x8B, 0x45, 0x08, 0x81, 0xEC, 0x0C, 0x02, 0x00, 0x00, 0x56, 0x8B, 0xF1, 0x85, 0xC0, 0x0F, 0x84, 0xAA, 0x00, 0x00, 0x00, 0x80, 0x38, 0x00, 0x0F, 0x84, 0xA1, 0x00, 0x00, 0x00 }; | |
constexpr pattern pattern_SomeDemoFunction = { | |
bytes_SomeDemoFunction, | |
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" | |
}; | |
static module_info get_module_info(LPCWSTR name) | |
{ | |
module_info rv; | |
rv.handle = GetModuleHandleW(name); | |
if (rv.handle) { | |
MODULEINFO info; | |
if (GetModuleInformation(GetCurrentProcess(), rv.handle, &info, sizeof(info))) { | |
rv.base = info.lpBaseOfDll; | |
rv.size = info.SizeOfImage; | |
} | |
} | |
return rv; | |
} | |
static bool compare(const uint8_t* data, const pattern& pattern) | |
{ | |
auto bytes = pattern.bytes; | |
auto mask = pattern.mask; | |
for (; *mask != '\0'; ++data, ++bytes, ++mask) | |
if (*mask == 'x' && *data != *bytes) | |
return false; | |
return true; | |
} | |
static uintptr_t find_pattern(const module_info& module, const pattern& pattern) | |
{ | |
auto length = std::strlen(pattern.mask); | |
auto p = reinterpret_cast<const uint8_t*>(module.base); | |
auto end = p + module.size - length; | |
for (; p <= end; ++p) | |
if (compare(p, pattern)) | |
return reinterpret_cast<uintptr_t>(p); | |
return 0; | |
} | |
namespace engine_dll | |
{ | |
using SetSignonState_t = bool (__fastcall *)(void* thisptr, int edx, int state, int spawncount); | |
SetSignonState_t SetSignonState; | |
using Cbuf_GetCommandBuffer_t = void* (__cdecl *)(); | |
Cbuf_GetCommandBuffer_t Cbuf_GetCommandBuffer; | |
using Cbuf_AddText_t = void (__cdecl *)(void* command_buffer, const char* text, int unknown); | |
Cbuf_AddText_t Cbuf_AddText; | |
static bool __fastcall MySetSignonState(void* thisptr, int edx, int state, int spawncount) | |
{ | |
constexpr int SIGNONSTATE_FULL = 6; | |
if (state == SIGNONSTATE_FULL) { | |
//MessageBoxW(0, L"SetSignonState(SIGNONSTATE_FULL)", L"Portal2AutoPause", MB_ICONINFORMATION); | |
Cbuf_AddText(Cbuf_GetCommandBuffer(), "toggleconsole\n", 0); | |
} | |
auto rv = SetSignonState(thisptr, edx, state, spawncount); | |
return rv; | |
} | |
} | |
static unsigned __stdcall main_thread(void* args) | |
{ | |
auto engine = get_module_info(L"engine.dll"); | |
if (!engine.handle) { | |
MessageBoxW(0, L"Could not get engine.dll module info.", L"Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
auto SetSignonState = find_pattern(engine, pattern_SetSignonState); | |
if (!SetSignonState) { | |
MessageBoxW(0, L"Could not find CBaseClient::SetSignonState.", L"Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
auto SomeDemoFunction = find_pattern(engine, pattern_SomeDemoFunction); | |
if (!SomeDemoFunction) { | |
MessageBoxW(0, L"Could not find the Cbuf pattern.", L"Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
engine_dll::Cbuf_GetCommandBuffer = reinterpret_cast<engine_dll::Cbuf_GetCommandBuffer_t>(*reinterpret_cast<uintptr_t*>(SomeDemoFunction + 121) + SomeDemoFunction + 125); | |
engine_dll::Cbuf_AddText = reinterpret_cast<engine_dll::Cbuf_AddText_t>(*reinterpret_cast<uintptr_t*>(SomeDemoFunction + 127) + SomeDemoFunction + 131); | |
auto err = MH_Initialize(); | |
if (err != MH_OK) { | |
MessageBoxA(0, ("MH_Initialize error: "s + MH_StatusToString(err)).c_str(), "Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
err = MH_CreateHook(reinterpret_cast<LPVOID>(SetSignonState), engine_dll::MySetSignonState, reinterpret_cast<LPVOID*>(&engine_dll::SetSignonState)); | |
if (err != MH_OK) { | |
MessageBoxA(0, ("MH_CreateHook error: "s + MH_StatusToString(err)).c_str(), "Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
err = MH_EnableHook(reinterpret_cast<LPVOID>(SetSignonState)); | |
if (err != MH_OK) { | |
MessageBoxA(0, ("MH_EnableHook error: "s + MH_StatusToString(err)).c_str(), "Portal2AutoPause", MB_ICONERROR); | |
return 1; | |
} | |
return 0; | |
} | |
BOOL APIENTRY DllMain(HMODULE module, DWORD reason, LPVOID reserved) | |
{ | |
switch (reason) { | |
case DLL_PROCESS_ATTACH: | |
DisableThreadLibraryCalls(module); | |
_beginthreadex(nullptr, 0, main_thread, nullptr, 0, nullptr); | |
break; | |
case DLL_PROCESS_DETACH: | |
break; | |
} | |
return TRUE; | |
} |
Is Autojump and/or ABH even possible at all?
when is autojump
is this legal?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When is TAS ?
(Just kidding don't do it)