Skip to content

Commit

Permalink
custom exceptions option
Browse files Browse the repository at this point in the history
  • Loading branch information
qimiko committed Jun 22, 2024
1 parent 3661df2 commit 9f5ccd9
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 19 deletions.
78 changes: 61 additions & 17 deletions app/src/main/cpp/launcher-fix.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <dlfcn.h>
#include <jni.h>
#include <fstream>
#include <string>
#include <cstdint>
#include <android/log.h>
Expand All @@ -17,16 +18,17 @@

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();
return paths_instance;
}

private:
DataPaths() : original_data_path(), data_path() {}
DataPaths() {}
};

extern "C"
Expand All @@ -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;
Expand Down Expand Up @@ -119,6 +135,43 @@ bool patch_symbol(std::uint32_t* hash_table, char* str_table, Elf_Sym* sym_table
return false;
}

std::vector<std::string> 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<std::string> 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) {
Expand Down Expand Up @@ -178,20 +231,11 @@ int on_dl_iterate(dl_phdr_info* info, size_t size, void* data) {
auto str_table = reinterpret_cast<char*>(str_table_addr);
auto sym_table = reinterpret_cast<Elf_Sym*>(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;
}

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/com/geode/launcher/GeometryDashActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/geode/launcher/LauncherFix.kt
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ object LauncherFix {
external fun setOriginalDataPath(dataPath: String)

external fun performExceptionsRenaming()

external fun enableCustomSymbolList(symbolsPath: String)
}
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"
}
}

Expand Down
3 changes: 3 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -180,4 +180,7 @@
<string name="preference_developer_mode">Enable developer options</string>
<string name="preference_developer_mode_about">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.</string>
<string name="preference_developer_update_notice">Enabling developer mode automatically disallows the updater from overwriting custom loader builds.</string>

<string name="preference_override_exceptions_name">Custom exceptions fix symbols</string>
<string name="preference_override_exceptions_description">Uses exception_symbols.txt to patch</string>
</resources>

0 comments on commit 9f5ccd9

Please sign in to comment.