diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index 3aacd654..3bc23b00 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -9,32 +9,8 @@ #include #include #include "il2cpp_dump.h" -#include "game.h" -#include - -int isGame(JNIEnv *env, jstring appDataDir) { - if (!appDataDir) - return 0; - const char *app_data_dir = env->GetStringUTFChars(appDataDir, nullptr); - int user = 0; - static char package_name[256]; - if (sscanf(app_data_dir, "/data/%*[^/]/%d/%s", &user, package_name) != 2) { - if (sscanf(app_data_dir, "/data/%*[^/]/%s", package_name) != 1) { - package_name[0] = '\0'; - LOGW("can't parse %s", app_data_dir); - return 0; - } - } - int flag = 0; - if (strcmp(package_name, GamePackageName) == 0) { - LOGI("detect game: %s", package_name); - game_data_dir = new char[strlen(app_data_dir) + 1]; - strcpy(game_data_dir, app_data_dir); - flag = 1; - } - env->ReleaseStringUTFChars(appDataDir, app_data_dir); - return flag; -} +#include "log.h" +#include "xdl.h" static int GetAndroidApiLevel() { char prop_value[PROP_VALUE_MAX]; @@ -42,16 +18,21 @@ static int GetAndroidApiLevel() { return atoi(prop_value); } -void *hack_thread(void *arg) { - LOGI("hack thread: %d", gettid()); - int api_level = GetAndroidApiLevel(); - LOGI("api level: %d", api_level); - sleep(5); +void hack_start(const char *game_data_dir) { void *handle = xdl_open("libil2cpp.so", 0); if (handle) { - il2cpp_dump(handle, game_data_dir); + il2cpp_api_init(handle); + il2cpp_dump(game_data_dir); } else { LOGI("libil2cpp.so not found in thread %d", gettid()); } - return nullptr; +} + +void hack_prepare(const char *game_data_dir) { + LOGI("hack thread: %d", gettid()); + int api_level = GetAndroidApiLevel(); + LOGI("api level: %d", api_level); + sleep(5); + + hack_start(game_data_dir); } \ No newline at end of file diff --git a/module/src/main/cpp/hack.h b/module/src/main/cpp/hack.h index 4d4b875c..7af5a07b 100644 --- a/module/src/main/cpp/hack.h +++ b/module/src/main/cpp/hack.h @@ -5,14 +5,6 @@ #ifndef ZYGISK_IL2CPPDUMPER_HACK_H #define ZYGISK_IL2CPPDUMPER_HACK_H -#include -#include "log.h" - -static int enable_hack; -static char *game_data_dir = NULL; - -int isGame(JNIEnv *env, jstring appDataDir); - -void *hack_thread(void *arg); +void hack_prepare(const char *game_data_dir); #endif //ZYGISK_IL2CPPDUMPER_HACK_H diff --git a/module/src/main/cpp/il2cpp_dump.cpp b/module/src/main/cpp/il2cpp_dump.cpp index 0cf1f040..9900ecf5 100644 --- a/module/src/main/cpp/il2cpp_dump.cpp +++ b/module/src/main/cpp/il2cpp_dump.cpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include "xdl.h" #include "log.h" #include "il2cpp-tabledefs.h" #include "il2cpp-class.h" @@ -37,34 +37,6 @@ void init_il2cpp_api(void *handle) { #undef DO_API } -uint64_t get_module_base(const char *module_name) { - uint64_t addr = 0; - char line[1024]; - uint64_t start = 0; - uint64_t end = 0; - char flags[5]; - char path[PATH_MAX]; - - FILE *fp = fopen("/proc/self/maps", "r"); - if (fp != nullptr) { - while (fgets(line, sizeof(line), fp)) { - strcpy(path, ""); - sscanf(line, "%" PRIx64"-%" PRIx64" %s %*" PRIx64" %*x:%*x %*u %s\n", &start, &end, - flags, path); -#if defined(__aarch64__) - if (strstr(flags, "x") == 0) //TODO - continue; -#endif - if (strstr(path, module_name)) { - addr = start; - break; - } - } - fclose(fp); - } - return addr; -} - std::string get_method_modifier(uint32_t flags) { std::stringstream outPut; auto access = flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK; @@ -349,17 +321,13 @@ std::string dump_type(const Il2CppType *type) { return outPut.str(); } -void il2cpp_dump(void *handle, char *outDir) { - //initialize +void il2cpp_api_init(void *handle) { LOGI("il2cpp_handle: %p", handle); init_il2cpp_api(handle); if (il2cpp_domain_get_assemblies) { Dl_info dlInfo; if (dladdr((void *) il2cpp_domain_get_assemblies, &dlInfo)) { il2cpp_base = reinterpret_cast(dlInfo.dli_fbase); - } else { - LOGW("dladdr error, using get_module_base."); - il2cpp_base = get_module_base("libil2cpp.so"); } LOGI("il2cpp_base: %" PRIx64"", il2cpp_base); } else { @@ -368,9 +336,12 @@ void il2cpp_dump(void *handle, char *outDir) { } auto domain = il2cpp_domain_get(); il2cpp_thread_attach(domain); - //start dump +} + +void il2cpp_dump(const char *outDir) { LOGI("dumping..."); size_t size; + auto domain = il2cpp_domain_get(); auto assemblies = il2cpp_domain_get_assemblies(domain, &size); std::stringstream imageOutput; for (int i = 0; i < size; ++i) { diff --git a/module/src/main/cpp/il2cpp_dump.h b/module/src/main/cpp/il2cpp_dump.h index 1bea8a5b..5578c771 100644 --- a/module/src/main/cpp/il2cpp_dump.h +++ b/module/src/main/cpp/il2cpp_dump.h @@ -5,6 +5,8 @@ #ifndef ZYGISK_IL2CPPDUMPER_IL2CPP_DUMP_H #define ZYGISK_IL2CPPDUMPER_IL2CPP_DUMP_H -void il2cpp_dump(void *handle, char *outDir); +void il2cpp_api_init(void *handle); + +void il2cpp_dump(const char *outDir); #endif //ZYGISK_IL2CPPDUMPER_IL2CPP_DUMP_H diff --git a/module/src/main/cpp/main.cpp b/module/src/main/cpp/main.cpp index 65cb0a9d..15be0983 100644 --- a/module/src/main/cpp/main.cpp +++ b/module/src/main/cpp/main.cpp @@ -1,9 +1,9 @@ #include -#include -#include +#include #include "hack.h" #include "zygisk.hpp" - +#include "game.h" +#include "log.h" using zygisk::Api; using zygisk::AppSpecializeArgs; @@ -12,29 +12,39 @@ using zygisk::ServerSpecializeArgs; class MyModule : public zygisk::ModuleBase { public: void onLoad(Api *api, JNIEnv *env) override { - env_ = env; + this->api = api; + this->env = env; } void preAppSpecialize(AppSpecializeArgs *args) override { - if (!args || !args->nice_name) { - LOGE("Skip unknown process"); - return; - } - enable_hack = isGame(env_, args->app_data_dir); + auto package_name = env->GetStringUTFChars(args->nice_name, nullptr); + auto app_data_dir = env->GetStringUTFChars(args->app_data_dir, nullptr); + preSpecialize(package_name, app_data_dir); + env->ReleaseStringUTFChars(args->nice_name, package_name); + env->ReleaseStringUTFChars(args->app_data_dir, app_data_dir); } void postAppSpecialize(const AppSpecializeArgs *) override { if (enable_hack) { - int ret; - pthread_t ntid; - if ((ret = pthread_create(&ntid, nullptr, hack_thread, nullptr))) { - LOGE("can't create thread: %s\n", strerror(ret)); - } + std::thread hack_thread(hack_prepare, game_data_dir); + hack_thread.detach(); } } private: - JNIEnv *env_{}; + Api *api; + JNIEnv *env; + bool enable_hack; + char *game_data_dir; + + void preSpecialize(const char *package_name, const char *app_data_dir) { + if (strcmp(package_name, GamePackageName) == 0) { + LOGI("detect game: %s", package_name); + enable_hack = true; + game_data_dir = new char[strlen(app_data_dir) + 1]; + strcpy(game_data_dir, app_data_dir); + } + } }; REGISTER_ZYGISK_MODULE(MyModule) \ No newline at end of file