From 02185439357818bc157bf22a05a583a521299f59 Mon Sep 17 00:00:00 2001 From: chinosk <2248589280@qq.com> Date: Mon, 20 Jan 2025 20:13:07 +0000 Subject: [PATCH] fixed `LoginAsIOS` not working in `1.8.0` --- app/build.gradle | 2 +- app/src/main/cpp/GakumasLocalify/Hook.cpp | 51 ++++++++++++++++++- .../main/cpp/GakumasLocalify/Il2cppUtils.hpp | 9 ++++ 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index d45f6f7..70ec4d9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -16,7 +16,7 @@ android { minSdk 29 targetSdk 34 versionCode 10 - versionName "v2.0.1" + versionName "v2.0.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/cpp/GakumasLocalify/Hook.cpp b/app/src/main/cpp/GakumasLocalify/Hook.cpp index 5802afb..edb4971 100644 --- a/app/src/main/cpp/GakumasLocalify/Hook.cpp +++ b/app/src/main/cpp/GakumasLocalify/Hook.cpp @@ -1044,11 +1044,56 @@ namespace GakumasLocal::HookMain { if (Config::loginAsIOS) { return Il2cppString::New("iOS"); } - // auto ret = ApiBase_GetPlatformString_Orig(self, mtd); // Log::DebugFmt("ApiBase_GetPlatformString: %s", ret->ToString().c_str()); return ApiBase_GetPlatformString_Orig(self, mtd); } + void ProcessApiBase(void* self) { + static void* processedIOS = nullptr; + + if (Config::loginAsIOS) { + if (self == processedIOS) return; + + static auto ApiBase_klass = Il2cppUtils::get_class_from_instance(self); + static auto platform_field = UnityResolve::Invoke("il2cpp_class_get_field_from_name", ApiBase_klass, "_platform"); + auto platform = Il2cppUtils::ClassGetFieldValue(self, platform_field); + Log::DebugFmt("ProcessApiBase platform: %s", platform ? platform->ToString().c_str() : "null"); + if (platform) { + const auto origPlatform = platform->ToString(); + if (origPlatform != "iOS") { + Il2cppUtils::ClassSetFieldValue(self, platform_field, Il2cppString::New("iOS")); + processedIOS = self; + } + } + else { + Il2cppUtils::ClassSetFieldValue(self, platform_field, Il2cppString::New("iOS")); + processedIOS = self; + } + } + else { + if (processedIOS) { + Log::DebugFmt("Restore API to Android"); + static auto ApiBase_klass = Il2cppUtils::get_class_from_instance(self); + static auto platform_field = UnityResolve::Invoke("il2cpp_class_get_field_from_name", ApiBase_klass, "_platform"); + Il2cppUtils::ClassSetFieldValue(self, platform_field, Il2cppString::New("Android")); + processedIOS = nullptr; + } + } + } + + DEFINE_HOOK(void, ApiBase_ctor, (void* self, void* mtd)) { + ApiBase_ctor_Orig(self, mtd); + ProcessApiBase(self); + } + + DEFINE_HOOK(void*, ApiBase_get_Instance, (void* mtd)) { + auto ret = ApiBase_get_Instance_Orig(mtd); + if (ret) { + ProcessApiBase(ret); + } + return ret; + } + void UpdateSwingBreastBonesData(void* initializeData) { if (!Config::enableBreastParam) return; @@ -1384,7 +1429,9 @@ namespace GakumasLocal::HookMain { auto api_parent = UnityResolve::Invoke("il2cpp_class_get_parent", api_klass->address); if (api_parent) { // Log::DebugFmt("api_parent at %p, name: %s::%s", api_parent, api_parent->namespaze, api_parent->name); - ADD_HOOK(ApiBase_GetPlatformString, Il2cppUtils::il2cpp_class_get_method_from_name(api_parent, "GetPlatformString", 0)->methodPointer); + ADD_HOOK(ApiBase_GetPlatformString, Il2cppUtils::il2cpp_class_get_method_pointer_from_name(api_parent, "GetPlatformString", 0)); + ADD_HOOK(ApiBase_ctor, Il2cppUtils::il2cpp_class_get_method_pointer_from_name(api_parent, ".ctor", 0)); + ADD_HOOK(ApiBase_get_Instance, Il2cppUtils::il2cpp_class_get_method_pointer_from_name(api_parent, "get_Instance", 0)); } } diff --git a/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp b/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp index a8c3011..aa29404 100644 --- a/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp +++ b/app/src/main/cpp/GakumasLocalify/Il2cppUtils.hpp @@ -205,6 +205,15 @@ namespace Il2cppUtils { return UnityResolve::Invoke("il2cpp_class_get_method_from_name", klass, name, argsCount); } + static uintptr_t il2cpp_class_get_method_pointer_from_name(void* klass, const char* name, int argsCount) { + auto findKlass = il2cpp_class_get_method_from_name(klass, name, argsCount); + if (findKlass) { + return findKlass->methodPointer; + } + Log::ErrorFmt("method: %s not found", name); + return 0; + } + static void* find_nested_class(void* klass, std::predicate auto&& predicate) { void* iter{}; while (const auto curNestedClass = UnityResolve::Invoke("il2cpp_class_get_nested_types", klass, &iter))