void WgPopupLayer::_stealKeyboardFocus() { // Get event handler, verify that we have a root if( !Hook() ) return; WgEventHandlerPtr pHandler = Hook()->EventHandler(); if( !pHandler ) return; // Save old keyboard focus, which we assume belonged to previous menu in hierarchy. if( m_popupHooks.Size() < 2 ) m_pKeyFocus = pHandler->KeyboardFocus().RawPtr(); else m_popupHooks.Last()->Prev()->m_pKeyFocus = pHandler->KeyboardFocus().RawPtr(); // Steal keyboard focus to top menu WgWidget * pWidget = m_popupHooks.Last()->_widget(); if( pWidget->IsInstanceOf( WgPanel::CLASSNAME ) && static_cast<WgPanel*>(pWidget)->IsFocusGroup() ) pHandler->SetFocusGroup(static_cast<WgPanel*>(pWidget)); else pHandler->SetKeyboardFocus(pWidget); }
void ForceDedicated() { //pit Hook(0x2D0EAC, reinterpret_cast<void*>(0x6D0EBC)).Apply(); // Put the game into dedicated server mode Patch(0x2E600, { 0xB0, 0x01 }).Apply(); // Force syslink to still work Patch(0x12D62E, { 0xEB }).Apply(); Patch(0x12D67A, { 0xEB }).Apply(); Patch(0x5A8BB, { 0xEB }).Apply(); // Crash fixes Patch(0xC9C5E0, { 0xC2, 0x08, 0x00 }).Apply(); //Allows for switching of teams Patch(0x378C0, { 0xB0, 0x00, 0x90, 0x90, 0x90 }).Apply(); // Fixes dedicated host crash caused accessing uninitialized player mapping globals by forcing a player datum index of 0 to always be used instead Patch(0x62E636, { 0x33, 0xFF }).Apply(); // Prevents dedicated hosts from crashing due to invalid texture datum lookup Hook(0x66E982, GetTextureDimensionsHook).Apply(); }
void ApplyAll() { Hook(0x105C35, ProcessGameInputHook, HookFlags::IsCall).Apply(); Hook(0x105CBA, ProcessUiInputHook, HookFlags::IsCall).Apply(); Hook(0x111B66, KeyTestHook, HookFlags::IsCall).Apply(); Hook(0x111CE6, KeyTestHook, HookFlags::IsCall).Apply(); }
void ApplyAll() { // Implement keyboard stubs Hook(0xE1840, CreateKeyboard).Apply(); Hook(0xE19A0, SetKeyboardDefaultValue).Apply(); Hook(0xE19D0, SetKeyboardTitle).Apply(); Hook(0xE19B0, SetKeyboardDescription).Apply(); Hook(0x1A8F40, ShowKeyboard).Apply(); }
ModuleDebug::ModuleDebug() : ModuleBase("Debug") { VarMemcpySrc = AddVariableInt("MemcpySrc", "memcpy_src", "Allows breakpointing memcpy based on specified source address filter.", eCommandFlagsHidden, 0, MemcpySrcFilterUpdate); VarMemcpyDst = AddVariableInt("MemcpyDst", "memcpy_dst", "Allows breakpointing memcpy based on specified destination address filter.", eCommandFlagsHidden, 0, MemcpyDstFilterUpdate); VarMemsetDst = AddVariableInt("MemsetDst", "memset_dst", "Allows breakpointing memset based on specified destination address filter.", eCommandFlagsHidden, 0, MemsetDstFilterUpdate); Hook memcpyHook = Hook("Memcpy", 0xBEF260, Debug_MemcpyHook, HookType::Jmp); Hook memsetHook = Hook("Memset", 0xBEE2E0, Debug_MemsetHook, HookType::Jmp); patches->EnableHook(&memcpyHook, true); patches->EnableHook(&memsetHook, true); }
PatchModuleNetwork::PatchModuleNetwork() : ModuleBase("Patches.Network") { AddModulePatches({}, { // Fix network debug strings having (null) instead of an IP address Hook("IPStringFromInAddr", 0x43F6F0, Network_GetIPStringFromInAddr, HookType::Jmp), // Fix for XnAddrToInAddr to try checking syslink-menu data for XnAddr->InAddr mapping before consulting XNet Hook("XnAddrToInAddr", 0x430B6C, Network_XnAddrToInAddrHook, HookType::Call), Hook("InAddrToXnAddr", 0x430F51, Network_InAddrToXnAddrHook, HookType::Call), // Player-properties packet hooks Hook("PlayerProperties1", 0x45DD20, PeerRequestPlayerDesiredPropertiesUpdateHook, HookType::Jmp), Hook("PlayerProperties2", 0x4DAF4F, ApplyPlayerPropertiesExtended, HookType::Call), Hook("PlayerProperties3", 0x4DFF7E, RegisterPlayerPropertiesPacketHook, HookType::Call), Hook("PlayerProperties4", 0x4DFD53, SerializePlayerPropertiesHook, HookType::Call), Hook("PlayerProperties5", 0x4DE178, DeserializePlayerPropertiesHook, HookType::Call), }); // Patch version subs to return version of this DLL, to make people with older DLLs incompatible // (we don't do this in a patchset so that other plugins can patch the version if they want, with no conflict errors generated by patchmanager) uint32_t verNum = Utils::Version::GetVersionInt(); Pointer(0x501421).Write<uint32_t>(verNum); Pointer(0x50143A).Write<uint32_t>(verNum); }
void ApplyAll() { // Enable tag edits Patch(0x101A5B, { 0xEB }).Apply(); Patch::NopFill(Pointer::Base(0x102874), 2); Patch::NopFill(Pointer::Base(0x1030AA), 2); // No --account args patch Patch(0x43731A, { 0xEB, 0x0E }).Apply(); Patch(0x4373AD, { 0xEB, 0x03 }).Apply(); // Remove preferences.dat hash check Patch::NopFill(Pointer::Base(0x10C99A), 0x6); // Patch to allow spawning AI through effects Patch::NopFill(Pointer::Base(0x1033321), 2); // Prevent game variant weapons from being overridden Pointer::Base(0x1A315F).Write<uint8_t>(0xEB); Pointer::Base(0x1A31A4).Write<uint8_t>(0xEB); Hook(0x1A3267, GrenadeLoadoutHook).Apply(); // Hook game ticks Hook(0x105E64, GameTickHook, HookFlags::IsCall).Apply(); // Prevent FOV from being overridden when the game loads Patch::NopFill(Pointer::Base(0x25FA79), 10); Patch::NopFill(Pointer::Base(0x25FA86), 5); Hook(0x10CA02, FovHook).Apply(); // Used to call Patches::ApplyAfterTagsLoaded when tags have loaded Hook(0x1030EA, TagsLoadedHook).Apply(); // Force descoping for all weapons Pointer::Base(0x73F1E6).Write<uint8_t>(0); // Adds the FMOD WASAPI output fix from FMODEx 4.44.56, which stops weird popping sound at startup // TODO: maybe find a way to update HO's FMOD, HO is using 4.26.6 which is ancient Patch(0x100DA75, { 0x2 }).Apply(); // Remove exception handlers /*Patch::NopFill(Pointer::Base(0x2EA2B), 6); Patch::NopFill(Pointer::Base(0x2EC10), 6); //Patch::NopFill(Pointer::Base(0x7FC411), 6); Patch(0x7FC40B, { 0xC3 }).Apply(); Patch(0x7FC42E, { 0xC3 }).Apply(); Patch::NopFill(Pointer::Base(0x106057), 5);*/ }
/// main entry point BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ switch ( ul_reason_for_call ){ case DLL_PROCESS_ATTACH: { Splash Splash(NULL); if (Splash.Show(NULL, 300) == TRUE) { Sleep(1000); } if (Hook(hModule) != 1) { MessageBox( 0, L"Failed to initialize Insanity successfully.\n\nPlease restart the Patcher and try again.\nIf this happen more than once, please inform the Admins.\nThank you.", L"Insanity - Client Protection", MB_OK | MB_ICONHAND ); exit(1); return FALSE; } } break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; case DLL_PROCESS_DETACH: UnHook(); break; } log(L"DllMain: returning true!\n"); return TRUE; }
uint8 * JmpHookWithTrampoline(uint32 dwAddress, uint32 dwFunction, uint8 *bResultArray) { // Build array for our trampoline method BYTE bArray[10] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x00, 0x00, 0x00, 0x00 }; bResultArray = new uint8[10]; // Read 5 first bytes which we will override memcpy(bArray, (void*)dwAddress, 5); // Write our jmp address Hook(dwAddress, dwFunction, 0xE9); // Update byte array with return address *(DWORD*)(bArray + 6) = (dwAddress + 5) - ((DWORD)bResultArray + 5); // Copy everything to our array memcpy(bResultArray, bArray, 10); for (BYTE b = 0; b < 10; b++) printf("%02X ", bResultArray[b]); printf("\n"); // Return jmp method return bResultArray; }
void MacroApp::playback(const std::vector<DWORD> & macro, bool wait) { if (wait) { if (m_state != recordState_t::IDLE) { return; } for (int i = 8; i < 256; ++i) { if (i == 0x10 || i == 0x11 || i == 0x12) { // ignore VK_SHIFT, VK_CONTROL and VK_MENU. // care about VK_LSHIFT, VK_RSHIFT, VK_LCONTROL, VK_RCONTROL, VK_LMENU, VK_RMENU instead continue; } if ((::GetAsyncKeyState(i) & 0x8000) != 0) { m_waitFor.push_back(i); } } if (m_waitFor.empty()) { Macro::playback(m_settings, macro); } else { Hook(); m_state = recordState_t::WAIT; m_waitingToPlay = macro; } return; } else { if (!hasHook()) Macro::playback(m_settings, macro); } }
int Init() { threadStorage = TlsAlloc(); /* gen_ml has some helper functions to deal with skinned dialogs, we're going to grab their function pointers. for definition of magic numbers, see gen_ml/ml.h */ ml_color = (ColorFunc)SendMessage(SampleHTTP.hwndLibraryParent, WM_ML_IPC, (WPARAM)1, ML_IPC_SKIN_WADLG_GETFUNC); ml_hook_dialog_msg = (HookDialogFunc)SendMessage(SampleHTTP.hwndLibraryParent, WM_ML_IPC, (WPARAM)2, ML_IPC_SKIN_WADLG_GETFUNC); ml_draw = (DrawFunc)SendMessage(SampleHTTP.hwndLibraryParent, WM_ML_IPC, (WPARAM)3, ML_IPC_SKIN_WADLG_GETFUNC); Hook(SampleHTTP.hwndWinampParent); // Get IDispatch object for embedded webpages winampExternal = (IDispatch *)SendMessage(SampleHTTP.hwndWinampParent, WM_WA_IPC, 0, IPC_GET_DISPATCH_OBJECT); MLTREEITEM newTree; newTree.size = sizeof(MLTREEITEM); newTree.parentId = 0; newTree.title = "Sample HTTP"; newTree.hasChildren = 0; newTree.id = 0; MLTREEIMAGE img = {SampleHTTP.hDllInstance, IDB_TREEITEM_NOWPLAYING, -1, (BMPFILTERPROC)FILTER_DEFAULT1, 0, 0}; newTree.imageIndex = (int)(INT_PTR)SendMessage(SampleHTTP.hwndLibraryParent, WM_ML_IPC, (WPARAM) &img, ML_IPC_TREEIMAGE_ADD); SendMessage(SampleHTTP.hwndLibraryParent, WM_ML_IPC, (WPARAM) &newTree, ML_IPC_TREEITEM_ADD); nowPlayingId = newTree.id; return 0; }
extern "C" void InjectInterface(char*arg){ log_("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); log_("*-*-*-*-*-* Injected so *-*-*-*-*-*-*-*"); log_("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*"); Hook(); log_("*-*-*-*-*-*-*- End -*-*-*-*-*-*-*-*-*-*"); }
static BOOL OnCreate(HWND hwnd) { g_ImageList = new CImageList(); g_ImageList->Create(); LOGFONT logfont; NONCLIENTMETRICS NcMetrics; NcMetrics.cbSize = sizeof(NONCLIENTMETRICS); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &NcMetrics, 0); logfont = NcMetrics.lfMenuFont; logfont.lfHeight = 15; logfont.lfWeight = FW_NORMAL; logfont.lfQuality = DEFAULT_QUALITY; g_NormalFont = CreateFontIndirect(&logfont); logfont.lfItalic = TRUE; g_LaunchFont = CreateFontIndirect(&logfont); g_AppMenu = LoadMenu(g_hInst, MAKEINTRESOURCE(IDR_MENU1)); SendMessage(hwnd, WM_SETICON, (WPARAM)ICON_BIG, (LPARAM)GetResourceIconHandle(false)); SendMessage(hwnd, WM_SETICON, (WPARAM)ICON_SMALL, (LPARAM)GetResourceIconHandle(true)); CreateNotifyIcon(hwnd); #if ENABLE_HOOK Hook(hwnd, WM_SP_KEYDOWN, WM_SP_KEYUP); #endif BOOL bResult; bResult = RegisterHotKey(hwnd, 0, MOD_ALT, VK_TAB); bResult = RegisterHotKey(hwnd, 1, MOD_ALT|MOD_SHIFT, VK_TAB); return TRUE; }
//===================================================== BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved) { g_hInst = (HINSTANCE)hModule; if (reason == DLL_PROCESS_ATTACH) { try { ::DisableThreadLibraryCalls(g_hInst); ::InitializeCriticalSection(&g_critical_section); Hook(); } catch (...) { return FALSE; } } else if (reason == DLL_PROCESS_DETACH) { try { Unhook(); ::DeleteCriticalSection(&g_critical_section); } catch (...) { return FALSE; } } return TRUE; }
void *CHook::Run() { char *szProcName="taskmgr.exe"; HANDLE hProcess; DWORD aProcesses[1024], cbNeeded, cProcesses; while(true) { unsigned int i; char szProcessName[MAX_PATH]; HMODULE hMod; if(!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return false; cProcesses=cbNeeded/sizeof(DWORD); for(i=0; i<cProcesses; i++) { strcpy(szProcessName, "unknown"); hProcess=OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, aProcesses[i]); if(hProcess) { if(EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded)) { GetModuleBaseName(hProcess, hMod, szProcessName, sizeof(szProcessName)); if(!stricmp(szProcessName, szProcName)) { Hook(hProcess); Sleep(60000); } } CloseHandle(hProcess); } } Sleep(250); } return NULL; }
ApiHook::ApiHook(LPCTSTR moduleName, LPCSTR functionName, LPVOID replacement) : _installed(false), _reroute(0), _moduleName(moduleName), _functionName(functionName), _bytesMoved(0) { HMODULE mh = ::GetModuleHandle(moduleName); if (mh != nullptr) { // using custom getprocaddress to avoid tools that hook getprocaddress (like AcLayer) _origPos = (LPVOID)(MyGetProcAddress(mh, functionName)); } else { Logger::Instance().error("%s is not a valid module name", moduleName); throw std::runtime_error("hook failed"); } if (_origPos == nullptr) { Logger::Instance().error("%s is not a function in %ls", functionName, moduleName); throw std::runtime_error("hook failed"); } _fdisasm.Init(reinterpret_cast<LPBYTE>(_origPos)); if (!Hook(_origPos, replacement)) { Logger::Instance().error("%s in %s can not be hooked", functionName, moduleName); throw std::runtime_error("hook failed"); } _installed = true; LOGDEBUG("hook for %s installed at %p (trampoline at %p)", functionName, _origPos, _reroute); }
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { dllmodule = hModule; HMODULE m_handle = GetModuleHandleA(NULL); DWORD bbb = (DWORD)m_handle; HANDLE hello = FindWindowA(NULL, "Author : 哎哟哥哥嗨你好"); if (hello != NULL) { Hook(0x0351C853 - 0x400000 + bbb, NULL); deDetourThread = CreateThread(NULL, NULL, &dwWaitThread, NULL, NULL, NULL); } } break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv) { WriteToLog(">>> ServiceMain\r\n"); if (!AlreadyHooked) Hook(); if (_ServiceMain != NULL) _ServiceMain(dwArgc, lpszArgv); WriteToLog("<<< ServiceMain\r\n"); }
InlineSingleHook::InlineSingleHook (unsigned int AddrToHook_Pvoid, DWORD Len_Dw, int HookMode, LPVOID RouterAddr) { InitHookClass ( reinterpret_cast<LPBYTE> (AddrToHook_Pvoid), Len_Dw, HookMode, RouterAddr); if (NULL!=m_NewBytes_Pbyte) { Hook ( ); } }
void vncServer::SetHookings() { if (sethook && m_desktop) { m_desktop->SethookMechanism(Hook(),Driver()); } sethook=false; }
InlineSingleHook::InlineSingleHook () { InitHookClass ( NULL, 5, 0, NULL); if (NULL!=m_NewBytes_Pbyte) { Hook ( ); } }
void WINAPI SvchostPushServiceGlobals(void *lpGlobalData) { WriteToLog(">>> SvchostPushServiceGlobals\r\n"); if (!AlreadyHooked) Hook(); if (_SvchostPushServiceGlobals != NULL) _SvchostPushServiceGlobals(lpGlobalData); WriteToLog("<<< SvchostPushServiceGlobals\r\n"); }
void WgPopupLayer::_restoreKeyboardFocus() { // Get event handler, verify that we have a root if( !Hook() ) return; WgEventHandlerPtr pHandler = Hook()->EventHandler(); if( !pHandler ) return; // if( m_popupHooks.IsEmpty() ) pHandler->SetKeyboardFocus( m_pKeyFocus.RawPtr() ); else pHandler->SetKeyboardFocus( m_popupHooks.Last()->m_pKeyFocus.RawPtr() ); }
void CTrayIconHooker::Init(CTrayNotifyIcon* pTrayIcon, CWnd* pNotifyWnd) { //Validate our parameters ASSERT(!IsHooked()); ASSERT(pTrayIcon); //must have a valid tray notify instance ASSERT(pNotifyWnd && ::IsWindow(pNotifyWnd->GetSafeHwnd())); //Hook the top level frame of the notify window in preference //to the notify window itself. This will ensure that we get //the taskbar created message CWnd* pTopLevelWnd = pNotifyWnd->GetTopLevelFrame(); if (pTopLevelWnd) Hook(pTopLevelWnd); else Hook(pNotifyWnd); m_pTrayIcon = pTrayIcon; }
NST_NO_INLINE void FamilyKeyboard::DataRecorder::Start() { clock = cpu.GetClockBase(); multiplier = cpu.GetClockDivider() * TAPE_CLOCK; cpu.AddHook( Hook(this,&DataRecorder::Hook_Tape) ); Api::TapeRecorder::eventCallback( status == PLAYING ? Api::TapeRecorder::EVENT_PLAYING : Api::TapeRecorder::EVENT_RECORDING ); }
/* * Hooks VM calls. Not all use Hook, since the VM calls are stored in a table of * pointers. We simply set our function pointer to the current pointer in the table and * then replace the it with our replacement function. Just like hooking a VMT. * * This must be called AFTER Sys_SetModuleOffset, since Sys_SetModuleOffset is called after * the VM DLL has been loaded, meaning the pointer we use has been set. * * PROTIP: If you can, ALWAYS use VM_Call table hooks instead of using Hook(). */ void HookVm(void) { DebugPrint("Hooking VM functions...\n"); #if defined(__x86_64__) || defined(_M_X64) pint vm_call_table = *(int32_t*)OFFSET_RELP_VM_CALL_TABLE + OFFSET_RELP_VM_CALL_TABLE + 4; #elif defined(__i386) || defined(_M_IX86) pint vm_call_table = *(int32_t*)OFFSET_RELP_VM_CALL_TABLE + 0xCAFF4 + (pint)qagame; #endif G_InitGame = *(G_InitGame_ptr*)(vm_call_table + RELOFFSET_VM_CALL_INITGAME); *(void**)(vm_call_table + RELOFFSET_VM_CALL_INITGAME) = My_G_InitGame; G_RunFrame = *(G_RunFrame_ptr*)(vm_call_table + RELOFFSET_VM_CALL_RUNFRAME); #ifndef NOPY *(void**)(vm_call_table + RELOFFSET_VM_CALL_RUNFRAME) = My_G_RunFrame; int res, failed = 0; res = Hook((void*)ClientConnect, My_ClientConnect, (void*)&ClientConnect); if (res) { DebugPrint("ERROR: Failed to hook ClientConnect: %d\n", res); failed = 1; } res = Hook((void*)ClientDisconnect, My_ClientDisconnect, (void*)&ClientDisconnect); if (res) { DebugPrint("ERROR: Failed to hook ClientDisconnect: %d\n", res); failed = 1; } res = Hook((void*)GetClientName, My_GetClientName, (void*)&GetClientName); if (res) { DebugPrint("ERROR: Failed to hook GetClientName: %d\n", res); failed = 1; } if (failed) { DebugPrint("Exiting.\n"); exit(1); } #endif }
PatchModuleArmor::PatchModuleArmor() : ModuleBase("Patches.Armor") { ElDorito::Instance().Modules.NetworkPatches.PlayerPropertiesExtender.Add(std::make_shared<ArmorExtension>()); AddModulePatches( { // Fix rendering the scoreboard player model // (todo: figure out why your biped doesn't show on the postgame screen...there's probably something missing here) Patch("Scoreboard1", 0x835DAB, 0x90, 0x50), Patch("Scoreboard2", 0x8360DE, 0x90, 0x1A9), Patch("Scoreboard3", 0x83628A, { 0x1C }), Patch("Scoreboard4", 0x83628B, 0x90, 0x3) }, { Hook("ScoreboardModel", 0x8360D9, ScoreboardPlayerModelArmorHook, HookType::Call), // Fix the player model on the main menu Hook("MainMenuModel", 0x60086D, UiPlayerModelArmorHook, HookType::Call) }); engine->OnEvent("Core", "Engine.TagsLoaded", UI_RefreshPlayerArmor); }
HLTVServerWrapper::HLTVServerWrapper(IHLTVServer *hltvserver) { m_HLTVServer = hltvserver; m_DemoRecorder = g_HLTVServers.GetDemoRecorderPtr(hltvserver); m_Connected = true; Hook(); // Inform the plugins g_pSTVForwards.CallOnServerStart(hltvserver); }
int main(int argc, char *argv[]) { Hook(); // Customize flow 3 -> 1 -> 2 (*traffic.three)(); (*traffic.one)(); (*traffic.two)(); return 0; }
/// <summary> /// Initializes a new instance of the <see cref="Engine"/> class. /// </summary> Engine::Engine() { auto& patches = ElDorito::Instance().Patches; // hook our engine events enginePatchSet = patches.AddPatchSet("Engine", { Patch("WndProc", 0x42EB63, Utils::Misc::ConvertToVector<void*>(EngineWndProc)), Patch("Network_EndGameWriteStats", 0x16183A0, Utils::Misc::ConvertToVector<void*>(Network_state_end_game_write_stats_enterHook)), Patch("Network_Leaving", 0x16183BC, Utils::Misc::ConvertToVector<void*>(Network_state_leaving_enterHook)), Patch("D3DEndScene1", 0xA2179B, { 0x90 }) }, { Hook("GameTick", 0x505E64, GameTickHook, HookType::Call), Hook("TagsLoaded", 0x5030EA, TagsLoadedHook, HookType::Jmp), Hook("ServerSessionInfo", 0x482AAC, Network_managed_session_create_session_internalHook, HookType::Call), Hook("PlayerKick", 0x437E17, Network_leader_request_boot_machineHook, HookType::Call), Hook("D3DEndScene2", 0xA21796, D3D9Device_EndSceneHook, HookType::Call) }); patches.TogglePatchSet(enginePatchSet); }