From 9f5ccd9ef14303b8bc7fcd4421641532eb4d806f Mon Sep 17 00:00:00 2001 From: qimiko <25387744+qimiko@users.noreply.github.com> Date: Sat, 22 Jun 2024 02:34:18 -0700 Subject: [PATCH] custom exceptions option --- app/src/main/cpp/launcher-fix.cpp | 78 +++++++++++++++---- .../geode/launcher/GeometryDashActivity.kt | 6 ++ .../java/com/geode/launcher/LauncherFix.kt | 2 + .../preferences/DeveloperSettingsActivity.kt | 7 +- .../geode/launcher/utils/PreferenceUtils.kt | 4 +- app/src/main/res/values/strings.xml | 3 + 6 files changed, 81 insertions(+), 19 deletions(-) diff --git a/app/src/main/cpp/launcher-fix.cpp b/app/src/main/cpp/launcher-fix.cpp index 53fc7f3..fa8f317 100644 --- a/app/src/main/cpp/launcher-fix.cpp +++ b/app/src/main/cpp/launcher-fix.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -17,8 +18,9 @@ class DataPaths { public: - std::string original_data_path; - std::string data_path; + std::string original_data_path{}; + std::string data_path{}; + std::string load_symbols_from{}; static DataPaths& get_instance() { static auto paths_instance = DataPaths(); @@ -26,7 +28,7 @@ class DataPaths { } private: - DataPaths() : original_data_path(), data_path() {} + DataPaths() {} }; extern "C" @@ -43,6 +45,20 @@ JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_setDataPath( env->ReleaseStringUTFChars(data_path, data_path_str); } +extern "C" +JNIEXPORT void JNICALL Java_com_geode_launcher_LauncherFix_enableCustomSymbolList( + JNIEnv* env, + jobject, + jstring symbol_path +) { + auto is_copy = jboolean(); + auto symbol_path_str = env->GetStringUTFChars(symbol_path, &is_copy); + + DataPaths::get_instance().load_symbols_from = std::string(symbol_path_str); + + env->ReleaseStringUTFChars(symbol_path, symbol_path_str); +} + #ifdef __arm__ // 32bit code typedef Elf32_Dyn Elf_Dyn; @@ -119,6 +135,43 @@ bool patch_symbol(std::uint32_t* hash_table, char* str_table, Elf_Sym* sym_table return false; } +std::vector get_symbols_listing() { + auto symbol_path = DataPaths::get_instance().load_symbols_from; + if (symbol_path.empty()) { + // this is every function that i thought would be relevant + return { + "__gxx_personality_v0", + "__cxa_throw", + "__cxa_rethrow", + "__cxa_allocate_exception", + "__cxa_end_catch", + "__cxa_begin_catch", + "__cxa_guard_abort", + "__cxa_guard_acquire", + "__cxa_guard_release", + "__cxa_free_exception", + "_Unwind_RaiseException", + "_Unwind_Resume" + }; + } + + std::ifstream symbol_file{symbol_path}; + if (!symbol_file) { + __android_log_print(ANDROID_LOG_WARN, "GeodeLauncher-fix", "failed to read symbol file at %s", symbol_path.c_str()); + return {}; + } + + std::vector symbols_list{}; + std::string current_line{}; + while (std::getline(symbol_file, current_line)) { + if (!current_line.empty()) { + symbols_list.push_back(current_line); + } + } + + return symbols_list; +} + int on_dl_iterate(dl_phdr_info* info, size_t size, void* data) { // this is probably going to be gd if (strstr(info->dlpi_name, "libcocos2dcpp.so") != nullptr) { @@ -178,20 +231,11 @@ int on_dl_iterate(dl_phdr_info* info, size_t size, void* data) { auto str_table = reinterpret_cast(str_table_addr); auto sym_table = reinterpret_cast(sym_table_addr); - // this is every function that i thought would be relevant - patch_symbol(hash_table, str_table, sym_table, "__gxx_personality_v0"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_throw"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_rethrow"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_allocate_exception"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_end_catch"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_begin_catch"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_guard_abort"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_guard_acquire"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_guard_release"); - patch_symbol(hash_table, str_table, sym_table, "__cxa_free_exception"); - - patch_symbol(hash_table, str_table, sym_table, "_Unwind_RaiseException"); - patch_symbol(hash_table, str_table, sym_table, "_Unwind_Resume"); + auto symbols_listing = get_symbols_listing(); + for (const auto& symbol : symbols_listing) { + patch_symbol(hash_table, str_table, sym_table, symbol.c_str()); + } + return 1; } diff --git a/app/src/main/java/com/geode/launcher/GeometryDashActivity.kt b/app/src/main/java/com/geode/launcher/GeometryDashActivity.kt index 9b31ee6..4acafc8 100644 --- a/app/src/main/java/com/geode/launcher/GeometryDashActivity.kt +++ b/app/src/main/java/com/geode/launcher/GeometryDashActivity.kt @@ -146,6 +146,12 @@ class GeometryDashActivity : AppCompatActivity(), Cocos2dxHelper.Cocos2dxHelperL tryLoadLibrary(gdPackageInfo, Constants.COCOS_LIB_NAME) if (GamePackageUtils.getGameVersionCode(packageManager) >= 39L) { + val customSymbols = PreferenceUtils.get(this).getBoolean(PreferenceUtils.Key.CUSTOM_SYMBOL_LIST) + if (customSymbols) { + val symbolFile = File(LaunchUtils.getBaseDirectory(this), "exception_symbols.txt") + LauncherFix.enableCustomSymbolList(symbolFile.path) + } + // this fix requires geode v3, which is 2.206+ // there is a short period in which 2.206 users will still have geode v2, but whatever. ig LauncherFix.performExceptionsRenaming() diff --git a/app/src/main/java/com/geode/launcher/LauncherFix.kt b/app/src/main/java/com/geode/launcher/LauncherFix.kt index 8079a88..2469b0b 100644 --- a/app/src/main/java/com/geode/launcher/LauncherFix.kt +++ b/app/src/main/java/com/geode/launcher/LauncherFix.kt @@ -14,4 +14,6 @@ object LauncherFix { external fun setOriginalDataPath(dataPath: String) external fun performExceptionsRenaming() + + external fun enableCustomSymbolList(symbolsPath: String) } \ No newline at end of file diff --git a/app/src/main/java/com/geode/launcher/preferences/DeveloperSettingsActivity.kt b/app/src/main/java/com/geode/launcher/preferences/DeveloperSettingsActivity.kt index 5841567..e409dbc 100644 --- a/app/src/main/java/com/geode/launcher/preferences/DeveloperSettingsActivity.kt +++ b/app/src/main/java/com/geode/launcher/preferences/DeveloperSettingsActivity.kt @@ -134,7 +134,12 @@ fun DeveloperSettingsScreen(onBackPressedDispatcher: OnBackPressedDispatcher?) { // if only there was a better way to define this! "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*(){}<>[]?:;'\"~`-_+=\\| ".contains(c) }} - ) + ) + SettingsCard( + title = stringResource(R.string.preference_override_exceptions_name), + description = stringResource(R.string.preference_override_exceptions_description), + preferenceKey = PreferenceUtils.Key.CUSTOM_SYMBOL_LIST + ) } OptionsGroup(title = stringResource(R.string.preference_category_updater)) { diff --git a/app/src/main/java/com/geode/launcher/utils/PreferenceUtils.kt b/app/src/main/java/com/geode/launcher/utils/PreferenceUtils.kt index 43bc36d..2c125fd 100644 --- a/app/src/main/java/com/geode/launcher/utils/PreferenceUtils.kt +++ b/app/src/main/java/com/geode/launcher/utils/PreferenceUtils.kt @@ -140,7 +140,8 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) { ENABLE_REDESIGN, RELEASE_CHANNEL_TAG, DEVELOPER_MODE, - CLEANUP_APKS + CLEANUP_APKS, + CUSTOM_SYMBOL_LIST } private fun defaultValueForBooleanKey(key: Key): Boolean { @@ -177,6 +178,7 @@ class PreferenceUtils(private val sharedPreferences: SharedPreferences) { Key.RELEASE_CHANNEL_TAG -> "PreferenceReleaseChannelTag" Key.DEVELOPER_MODE -> "PreferenceDeveloperMode" Key.CLEANUP_APKS -> "PreferenceCleanupPackages" + Key.CUSTOM_SYMBOL_LIST -> "PreferenceCustomSymbolList" } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b6d78ba..f2f5d4e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -180,4 +180,7 @@ Enable developer options Developer mode enables some options that may make the game unstable. Please do not modify them unless you know what you\'re doing!\nThese options may change behavior, or be removed entirely in future updates. Enabling developer mode automatically disallows the updater from overwriting custom loader builds. + + Custom exceptions fix symbols + Uses exception_symbols.txt to patch \ No newline at end of file