From b38e50d520ecc5ac6acccd6cfdb112a278f6fb1f Mon Sep 17 00:00:00 2001 From: Federico Cecchetto Date: Sat, 29 May 2021 23:35:47 +0200 Subject: [PATCH] Add replaceFunc function --- src/component/gsc.cpp | 73 +++++++++++++++++++++++++++++++++++++ src/component/scripting.cpp | 4 ++ src/component/scripting.hpp | 2 + 3 files changed, 79 insertions(+) diff --git a/src/component/gsc.cpp b/src/component/gsc.cpp index d42e599..5f77bd1 100644 --- a/src/component/gsc.cpp +++ b/src/component/gsc.cpp @@ -1,6 +1,7 @@ #include #include "loader/component_loader.hpp" #include "scheduler.hpp" +#include "scripting.hpp" #include "game/scripting/event.hpp" #include "game/scripting/execution.hpp" @@ -169,6 +170,62 @@ namespace gsc retn } } + + unsigned int replaced_pos = 0; + + void get_replaced_pos(unsigned int pos) + { + if (scripting::replaced_functions.find(pos) != scripting::replaced_functions.end()) + { + replaced_pos = scripting::replaced_functions[pos]; + } + } + + __declspec(naked) void vm_execute_stub() + { + __asm + { + pushad + push esi + call get_replaced_pos + pop esi + popad + + cmp replaced_pos, 0 + jne set_pos + + movzx eax, byte ptr[esi] + inc esi + + jmp loc_1 + loc_1: + mov [ebp - 0x18], eax + mov [ebp - 0x8], esi + + push ecx + + mov ecx, 0x20B8E28 + mov [ecx], eax + + mov ecx, 0x20B4A5C + mov[ecx], esi + + pop ecx + + cmp eax, 0x98 + + push 0x56B740 + retn + set_pos: + mov esi, replaced_pos + mov replaced_pos, 0 + + movzx eax, byte ptr[esi] + inc esi + + jmp loc_1 + } + } } namespace function @@ -204,8 +261,24 @@ namespace gsc return {}; }); + function::add("replacefunc", [](function_args args) -> scripting::script_value + { + const auto what = args[0].get_raw(); + const auto with = args[1].get_raw(); + + if (what.type != game::SCRIPT_FUNCTION || with.type != game::SCRIPT_FUNCTION) + { + throw std::runtime_error("Invalid type"); + } + + scripting::replaced_functions[what.u.uintValue] = with.u.uintValue; + + return {}; + }); + utils::hook::jump(0x56C8EB, call_builtin_stub); utils::hook::jump(0x56CBDC, call_builtin_method_stub); + utils::hook::jump(0x56B726, vm_execute_stub); } }; } diff --git a/src/component/scripting.cpp b/src/component/scripting.cpp index 782de82..27c33ac 100644 --- a/src/component/scripting.cpp +++ b/src/component/scripting.cpp @@ -12,6 +12,8 @@ namespace scripting std::unordered_map> fields_table; std::unordered_map> script_function_table; + std::unordered_map replaced_functions; + namespace { utils::hook::detour vm_notify_hook; @@ -67,6 +69,8 @@ namespace scripting void g_shutdown_game_stub(const int free_scripts) { + replaced_functions.clear(); + g_shutdown_game_hook.invoke(free_scripts); } diff --git a/src/component/scripting.hpp b/src/component/scripting.hpp index 21e9445..b8fc942 100644 --- a/src/component/scripting.hpp +++ b/src/component/scripting.hpp @@ -2,6 +2,8 @@ namespace scripting { + extern std::unordered_map replaced_functions; + extern std::unordered_map> fields_table; extern std::unordered_map> script_function_table; } \ No newline at end of file