refactor(FreemodeRecovery): Replaced stack recovery and patch script VM instead

closes #213
This commit is contained in:
Yimura 2022-05-18 23:17:57 +02:00
parent 8619312195
commit 8cf086adb0
7 changed files with 34 additions and 62 deletions

View File

@ -116,8 +116,6 @@ namespace big
bool vehicle_kick = true;
};
bool freemode_terminated = false;
script_events script_events{};
};

View File

@ -29,8 +29,6 @@ namespace big
// GTA Thead Start
m_gta_thread_start_hook("GTS", g_pointers->m_gta_thread_start, &hooks::gta_thread_start),
// GTA Thread Tick
m_gta_thread_tick_hook("GTT", g_pointers->m_gta_thread_tick, &hooks::gta_thread_tick),
// GTA Thread Kill
m_gta_thread_kill_hook("GTK", g_pointers->m_gta_thread_kill, &hooks::gta_thread_kill),
@ -84,7 +82,6 @@ namespace big
m_gta_thread_start_hook.enable();
m_gta_thread_kill_hook.enable();
m_gta_thread_tick_hook.enable();
m_network_player_mgr_shutdown_hook.enable();
@ -119,7 +116,6 @@ namespace big
m_network_player_mgr_shutdown_hook.disable();
m_gta_thread_tick_hook.disable();
m_gta_thread_kill_hook.disable();
m_gta_thread_start_hook.disable();

View File

@ -24,7 +24,6 @@ namespace big
static BOOL set_cursor_pos(int x, int y);
static GtaThread* gta_thread_start(unsigned int** a1, unsigned int a2);
static rage::eThreadState gta_thread_tick(GtaThread* a1, unsigned int a2);
static rage::eThreadState gta_thread_kill(GtaThread* thread);
static void network_player_mgr_shutdown(CNetworkPlayerMgr* _this);
@ -83,7 +82,6 @@ namespace big
detour_hook m_convert_thread_to_fiber_hook;
detour_hook m_gta_thread_start_hook;
detour_hook m_gta_thread_tick_hook;
detour_hook m_gta_thread_kill_hook;
detour_hook m_network_player_mgr_shutdown_hook;

View File

@ -5,7 +5,7 @@ namespace big
{
rage::eThreadState hooks::gta_thread_kill(GtaThread* thread)
{
rage::eThreadState result = g_hooking->m_gta_thread_kill_hook.get_original<decltype(&gta_thread_kill)>()(thread);
const auto result = g_hooking->m_gta_thread_kill_hook.get_original<decltype(&gta_thread_kill)>()(thread);
if (g->notifications.gta_thread_kill.log)
LOG(INFO) << "Script Thread '" << thread->m_name << "' terminated.";
@ -14,9 +14,6 @@ namespace big
g_native_hooks->do_cleanup_for_thread(thread);
if (thread->m_script_hash == RAGE_JOAAT("freemode"))
g->protections.freemode_terminated = !(result == rage::eThreadState::running);
return result;
}
}

View File

@ -1,40 +0,0 @@
#include "hooking.hpp"
#include "gta/script_thread.hpp"
namespace big
{
static char struct_backup[sizeof(GtaThread)];
static char stack_buffer[0xFFFF];
rage::eThreadState hooks::gta_thread_tick(GtaThread* thread, unsigned int a2)
{
rage::eThreadState state = thread->m_context.m_state;
if (thread->m_script_hash == RAGE_JOAAT("freemode") && state == rage::eThreadState::running && !g->protections.freemode_terminated)
{
memcpy(struct_backup, (void*)thread, sizeof(GtaThread));
if (thread->m_stack)
memcpy(stack_buffer, thread->m_stack, thread->m_context.m_stack_size);
}
rage::eThreadState result = g_hooking->m_gta_thread_tick_hook.get_original<decltype(&gta_thread_tick)>()(thread, a2);
if (thread->m_script_hash == RAGE_JOAAT("freemode"))
{
if (result == rage::eThreadState::killed && state == rage::eThreadState::running && !g->protections.freemode_terminated)
{
LOG(INFO) << "Freemode script crashed, attempting recovery...";
result = rage::eThreadState::running;
memcpy(thread, struct_backup, sizeof(GtaThread));
if (thread->m_stack)
memcpy(thread->m_stack, stack_buffer, thread->m_context.m_stack_size);
}
if (g->protections.freemode_terminated) g->protections.freemode_terminated = !(result == rage::eThreadState::running);
}
return result;
}
}

View File

@ -101,13 +101,7 @@ namespace big
m_gta_thread_start = ptr.as<PVOID>();
});
// Thread Thick
main_batch.add("TT", "48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 8B FA 48 8B D9 74 05", [this](memory::handle ptr)
{
m_gta_thread_tick = ptr.as<PVOID>();
});
// Thread Kill
// GTA Thread Kill
main_batch.add("TK", "48 89 5C 24 ? 57 48 83 EC 20 48 83 B9 ? ? ? ? ? 48 8B D9 74 14", [this](memory::handle ptr)
{
m_gta_thread_kill = ptr.as<PVOID>();
@ -240,8 +234,38 @@ namespace big
{
m_network_group_override = ptr.as<PVOID>();
});
main_batch.run(memory::module(nullptr));
auto mem_region = memory::module(nullptr);
main_batch.run(mem_region);
/**
* Freemode thread restorer through VM patch
*/
if (auto pat1 = mem_region.scan("3b 0a 0f 83 ? ? ? ? 48 ff c7"))
{
*pat1.add(2).as<uint32_t*>() = 0xc9310272;
*pat1.add(6).as<uint16_t*>() = 0x9090;
}
if (auto pat2 = mem_region.scan("3b 0a 0f 83 ? ? ? ? 49 03 fa"))
{
*pat2.add(2).as<uint32_t*>() = 0xc9310272;
*pat2.add(6).as<uint16_t*>() = 0x9090;
}
auto pat3 = mem_region.scan_all("3b 11 0f 83 ? ? ? ? 48 ff c7");
for (auto& handle : pat3)
{
*handle.add(2).as<uint32_t*>() = 0xd2310272;
*handle.add(6).as<uint16_t*>() = 0x9090;
}
auto pat4 = mem_region.scan_all("3b 11 0f 83 ? ? ? ? 49 03 fa");
for (auto& handle : pat4)
{
*handle.add(2).as<uint32_t*>() = 0xd2310272;
*handle.add(6).as<uint16_t*>() = 0x9090;
}
m_hwnd = FindWindowW(L"grcWindow", nullptr);
if (!m_hwnd)

View File

@ -56,7 +56,6 @@ namespace big
functions::get_screen_coords_for_world_coords* m_get_screen_coords_for_world_coords{};
PVOID m_gta_thread_start{};
PVOID m_gta_thread_tick{};
PVOID m_gta_thread_kill{};
PVOID m_network_player_mgr_shutdown;