From 6983b16a0c922fd351efe2a94928c7d62fd31fc0 Mon Sep 17 00:00:00 2001 From: JaanDev <67502867+JaanDev@users.noreply.github.com> Date: Mon, 6 Jan 2025 23:59:50 +0300 Subject: [PATCH 1/4] some changes --- src/hooks.cpp | 12 ++++++------ src/patches.cpp | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/hooks.cpp b/src/hooks.cpp index 01f1fd5..316c2de 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -214,12 +214,12 @@ void gd_string_assign_hk(void* self, char* src, size_t len) { $execute { #ifdef GEODE_IS_WINDOWS // constexpr auto GD_STR_ASSIGN_ADDR = 0x3BE50; // OLD (2.206?) - // constexpr auto GD_STR_ASSIGN_ADDR = 0x3cca0; - // gd_string_assign_o = reinterpret_cast(base::get() + GD_STR_ASSIGN_ADDR); - // auto res2 = Mod::get()->hook((void*)(base::get() + GD_STR_ASSIGN_ADDR), gd_string_assign_hk, "gd::string::assign", tulip::hook::TulipConvention::Thiscall).err(); - // if (res2 != std::nullopt) { - // log::error("Failed to hook gd::string::assign because of: {}", res2); - // } + constexpr auto GD_STR_ASSIGN_ADDR = 0x3cca0; + gd_string_assign_o = reinterpret_cast(base::get() + GD_STR_ASSIGN_ADDR); + auto res2 = Mod::get()->hook((void*)(base::get() + GD_STR_ASSIGN_ADDR), gd_string_assign_hk, "gd::string::assign", tulip::hook::TulipConvention::Thiscall).err(); + if (res2 != std::nullopt) { + log::error("Failed to hook gd::string::assign because of: {}", res2); + } // constexpr auto GD_STR_APPEND_ADDR = 0x21DE0; // gd_string_append_o = reinterpret_cast(base::get() + GD_STR_APPEND_ADDR); diff --git a/src/patches.cpp b/src/patches.cpp index a1733e8..f5ffde0 100644 --- a/src/patches.cpp +++ b/src/patches.cpp @@ -59,6 +59,11 @@ void patches::patchStrings() { // log::debug("res {}", res2); // res2 = gdl::patchStdString2("Hello!", {{base::get() + 0x67032, 0x2a}}, base::get() + 0x67052); // "Ease Out" which is inlined // log::debug("res {}", res2); + + // bool res; + // res = gdl::patchCString(base::get() + 0x35C17A, "Привет GDL!"); // yay it works + + #endif auto languageID = gdl::getCurrentLanguage(); From e3ae9f430489b7c51521666c5a0fd8ee0d6d5576 Mon Sep 17 00:00:00 2001 From: JaanDev <67502867+JaanDev@users.noreply.github.com> Date: Tue, 7 Jan 2025 00:01:03 +0300 Subject: [PATCH 2/4] some changes x2 --- src/hooks.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks.cpp b/src/hooks.cpp index 316c2de..3f1664e 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -215,12 +215,12 @@ void gd_string_assign_hk(void* self, char* src, size_t len) { #ifdef GEODE_IS_WINDOWS // constexpr auto GD_STR_ASSIGN_ADDR = 0x3BE50; // OLD (2.206?) constexpr auto GD_STR_ASSIGN_ADDR = 0x3cca0; - gd_string_assign_o = reinterpret_cast(base::get() + GD_STR_ASSIGN_ADDR); + gd_string_assign_o = reinterpret_cast(base::get() + GD_STR_ASSIGN_ADDR); auto res2 = Mod::get()->hook((void*)(base::get() + GD_STR_ASSIGN_ADDR), gd_string_assign_hk, "gd::string::assign", tulip::hook::TulipConvention::Thiscall).err(); if (res2 != std::nullopt) { log::error("Failed to hook gd::string::assign because of: {}", res2); } - + // constexpr auto GD_STR_APPEND_ADDR = 0x21DE0; // gd_string_append_o = reinterpret_cast(base::get() + GD_STR_APPEND_ADDR); // auto res3 = Mod::get()->hook((void*)(base::get() + GD_STR_APPEND_ADDR), gd_string_append_hk, "gd::string::append", tulip::hook::TulipConvention::Thiscall).err(); From 426c7ce7ae2a7a52a26ad8d9eb1ea1c907e5f0d8 Mon Sep 17 00:00:00 2001 From: JaanDev <67502867+JaanDev@users.noreply.github.com> Date: Tue, 7 Jan 2025 00:01:52 +0300 Subject: [PATCH 3/4] update submodules? --- libs/utf8 | 2 +- libs/zydis | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/utf8 b/libs/utf8 index aed5828..b26a5f7 160000 --- a/libs/utf8 +++ b/libs/utf8 @@ -1 +1 @@ -Subproject commit aed58281cf45838bdb7296e3109bd5a633d677ed +Subproject commit b26a5f718f4f370af1852a0d5c6ae8fa031ba7d0 diff --git a/libs/zydis b/libs/zydis index 5a68f63..bffbb61 160000 --- a/libs/zydis +++ b/libs/zydis @@ -1 +1 @@ -Subproject commit 5a68f639e4f01604cc7bfc8d313f583a8137e3d3 +Subproject commit bffbb610cfea643b98e87658b9058382f7522807 From be4ddf8789daec92da3bff9efc07bf4d14c8c464 Mon Sep 17 00:00:00 2001 From: JaanDev <67502867+JaanDev@users.noreply.github.com> Date: Tue, 7 Jan 2025 00:04:29 +0300 Subject: [PATCH 4/4] reformat --- api/stringPatch.cpp | 32 ++++++++++++++++---------------- src/patches.cpp | 27 +++++++++++++++------------ src/utils.cpp | 2 +- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/api/stringPatch.cpp b/api/stringPatch.cpp index f966eac..8699e7f 100644 --- a/api/stringPatch.cpp +++ b/api/stringPatch.cpp @@ -12,19 +12,21 @@ namespace gdl { #if defined(GEODE_IS_WINDOWS64) bool patchCString(uintptr_t srcAddr, const char* str) { uint8_t* arr = (uint8_t*)srcAddr; - if(arr[1] != 0x8D) { + if (arr[1] != 0x8D) { log::error("0x{:X}: instruction isn't lea!", srcAddr); return false; } uint8_t reg = arr[2] >> 3; + // clang-format off std::array patch = { static_cast(0x48 | (reg > 0x07)), // prefix 64 bit operation static_cast(0xB8 | (reg & 0xF7)), // mov , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <64-bit value> 0xC3 // ret }; + // clang-format on *(uintptr_t*)(patch.data() + 2) = (uintptr_t)str; @@ -35,7 +37,7 @@ namespace gdl { std::copy(patch.begin(), patch.end(), tramp); std::array callBytes = {0xE8, 0x00, 0x00, 0x00, 0x00, 0x90, 0x90}; // call and 2 NOPs - auto relAddr = (uintptr_t)tramp - ((uintptr_t)srcAddr + 5); // call is 5 bytes long + auto relAddr = (uintptr_t)tramp - ((uintptr_t)srcAddr + 5); // call is 5 bytes long *(int32_t*)(callBytes.data() + 1) = (int32_t)relAddr; if (Mod::get()->patch((void*)srcAddr, ByteVector(callBytes.begin(), callBytes.end())).isErr()) { @@ -46,7 +48,7 @@ namespace gdl { return true; } - bool patchStdString(uintptr_t srcAddr, std::string const& str) { + bool patchStdString(uintptr_t srcAddr, const std::string& str) { // clang-format off // 1. patch the alloc_data function // 1. patch `lea rcx/ecx, [...]` OR `mov ecx/rcx ...` to the correct string size (with \0). @@ -77,20 +79,20 @@ namespace gdl { uint8_t reg = 0; // check for 64-bit or 16-bit operation - if(*arr == 0x48 || *arr == 0x49 || *arr == 0x66) { + if (*arr == 0x48 || *arr == 0x49 || *arr == 0x66) { arr++; availableSize++; } - if(*arr == 0x8D) { // lea + if (*arr == 0x8D) { // lea auto modrm = gdlutils::decodeModRM(*arr); availableSize += modrm.size + 1; reg = modrm.reg; - } else if(*arr == 0x89 || *arr == 0x8B) { // mov , || mov , [mem] + } else if (*arr == 0x89 || *arr == 0x8B) { // mov , || mov , [mem] auto modrm = gdlutils::decodeModRM(*arr); availableSize += modrm.size; reg = modrm.reg; - } else if(*arr >= 0xB8 && *arr <= 0xBF) { // mov , + } else if (*arr >= 0xB8 && *arr <= 0xBF) { // mov , availableSize += 5; reg = (*arr - 0xB8) & 0xF7; } else { @@ -98,33 +100,31 @@ namespace gdl { return false; } - bool strTooLong = - (availableSize <= 3 && str.size() > 0x7F) || - (availableSize == 4 && str.size() > 0x7FFF); + bool strTooLong = (availableSize <= 3 && str.size() > 0x7F) || (availableSize == 4 && str.size() > 0x7FFF); - if(strTooLong) { + if (strTooLong) { log::error("0x{:X}: String too long!", srcAddr, str.size()); return false; } std::vector patch(availableSize, 0x90); - if(availableSize <= 3) { + if (availableSize <= 3) { patch[0] = 0xB0 | (reg & 0xF7); patch[1] = static_cast(str.size()); } - if(availableSize == 4) { + if (availableSize == 4) { int16_t size = static_cast(str.size()); patch[0] = 0x66; patch[1] = 0xB0 | (reg & 0xF7); - std::copy(&patch[3], (uint8_t*)(&size), (uint8_t*)(&size) + sizeof(size)); + std::copy(&patch[3], (uint8_t*)(&size), (uint8_t*)(&size) + sizeof(size)); } - if(availableSize >= 5) { + if (availableSize >= 5) { int32_t size = static_cast(str.size()); patch[0] = 0xB8 | (reg & 0xF7); - std::copy(&patch[1], (uint8_t*)(&size), (uint8_t*)(&size) + sizeof(size)); + std::copy(&patch[1], (uint8_t*)(&size), (uint8_t*)(&size) + sizeof(size)); } if (Mod::get()->patch((void*)srcAddr, ByteVector(patch.begin(), patch.end())).isErr()) { diff --git a/src/patches.cpp b/src/patches.cpp index 359b3a8..06b4992 100644 --- a/src/patches.cpp +++ b/src/patches.cpp @@ -39,18 +39,20 @@ void patches::patchStrings() { patches::fixCyrillicP(); #ifdef GEODE_IS_WINDOWS64 - bool res3; - res3 = gdl::patchCString(base::get() + 0x320CB5, "Настройки"); -// log::debug("{}", res3); -// res3 = gdl::patchCString(base::get() + 0x350598, "Привет, мир 2!"); -// log::debug("{}", res3); -// res3 = gdl::patchCString(base::get() + 0x3505F1, "Привет, мир 3!"); -// log::debug("{}", res3); - -// bool res2; -// res2 = gdl::patchStdStringRel("hi", 0x31561F, 0x31562F, 0x315638, {0x315641, 0x315648, 0x31564B, 0x315652, 0x315656, 0x31565C, 0x31565F, 0x315666, 0x31566A}); -// // res2 = gdl::patchStdStringRel("This is a very very long string1!This is a very very long string2!This is a very very long string3!This is a very very long string4!This is a very very long string5!", 0x31561F, 0x31562F, 0x315638, {0x315641, 0x315648, 0x31564B, 0x315652, 0x315656, 0x31565C, 0x31565F, 0x315666, 0x31566A}); -// log::debug("res {}", res2); + bool res3; + res3 = gdl::patchCString(base::get() + 0x320CB5, "Настройки"); + + ///////////// OLD ///////////// + // log::debug("{}", res3); + // res3 = gdl::patchCString(base::get() + 0x350598, "Привет, мир 2!"); + // log::debug("{}", res3); + // res3 = gdl::patchCString(base::get() + 0x3505F1, "Привет, мир 3!"); + // log::debug("{}", res3); + + // bool res2; + // res2 = gdl::patchStdStringRel("hi", 0x31561F, 0x31562F, 0x315638, {0x315641, 0x315648, 0x31564B, 0x315652, 0x315656, 0x31565C, 0x31565F, 0x315666, 0x31566A}); + // // res2 = gdl::patchStdStringRel("This is a very very long string1!This is a very very long string2!This is a very very long string3!This is a very very long string4!This is a very very long string5!", 0x31561F, 0x31562F, 0x315638, {0x315641, 0x315648, 0x31564B, 0x315652, 0x315656, 0x31565C, 0x31565F, 0x315666, 0x31566A}); + // log::debug("res {}", res2); // bool res2; // res2 = gdl::patchStdString2("Hello world! This is a long enough string!", {{base::get() + 0x31561F, 0x4F}}, base::get() + 0x31562A); // quit text @@ -59,6 +61,7 @@ void patches::patchStrings() { // log::debug("res {}", res2); // res2 = gdl::patchStdString2("Hello!", {{base::get() + 0x67032, 0x2a}}, base::get() + 0x67052); // "Ease Out" which is inlined // log::debug("res {}", res2); + /////////////////////////////// // bool res; // res = gdl::patchCString(base::get() + 0x35C17A, "Привет GDL!"); // yay it works diff --git a/src/utils.cpp b/src/utils.cpp index 1ff18ce..870d629 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -65,5 +65,5 @@ ModRM gdlutils::decodeModRM(uint8_t modrm){ ret.reg = (modrm >> 2) & 0b00000111; - return ret + return ret; } \ No newline at end of file