From fd5799cc95ec13c7bcbf22c602ea8ddcb14d6d3c Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Sun, 13 Oct 2024 15:33:53 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E5=A4=9A=E6=A8=A1=E5=9D=97=E6=B3=A8?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/game.h | 2 +- module/src/main/cpp/hack.cpp | 37 +++++++++++++++++++++++++----------- module/src/main/cpp/log.h | 2 +- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/module/src/main/cpp/game.h b/module/src/main/cpp/game.h index 64378e7..81a30b0 100644 --- a/module/src/main/cpp/game.h +++ b/module/src/main/cpp/game.h @@ -5,6 +5,6 @@ #ifndef ZYGISK_IL2CPPDUMPER_GAME_H #define ZYGISK_IL2CPPDUMPER_GAME_H -#define AimPackageName "com.example.testdlopen" +#define AimPackageName "com.sankuai.meituan" #endif //ZYGISK_IL2CPPDUMPER_GAME_H diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index 3bcf9a0..25d5a18 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -18,28 +18,33 @@ #include //#include #include - -void hack_start(const char *game_data_dir,JavaVM *vm) { +void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { bool load = false; LOGI("hack_start %s", game_data_dir); - // 构建新文件路径 - char new_so_path[256]; - snprintf(new_so_path, sizeof(new_so_path), "%s/files/%s.so", game_data_dir, "test"); - // 复制 /sdcard/test.so 到 game_data_dir 并重命名 - const char *src_path = "/data/local/tmp/test.so"; + // 构建新文件路径,使用传入的 soname 参数 + char new_so_path[256]; + snprintf(new_so_path, sizeof(new_so_path), "%s/files/%s.so", game_data_dir, soname); + + // 构建源文件路径 + char src_path[256]; + snprintf(src_path, sizeof(src_path), "/data/local/tmp/%s.so", soname); + + // 打开源文件 int src_fd = open(src_path, O_RDONLY); if (src_fd < 0) { LOGE("Failed to open %s: %s (errno: %d)", src_path, strerror(errno), errno); return; } + // 打开目标文件 int dest_fd = open(new_so_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (dest_fd < 0) { LOGE("Failed to open %s", new_so_path); close(src_fd); return; } + // 复制文件内容 char buffer[4096]; ssize_t bytes; @@ -52,18 +57,21 @@ void hack_start(const char *game_data_dir,JavaVM *vm) { } } + // 关闭文件描述符 close(src_fd); close(dest_fd); + + // 修改文件权限 if (chmod(new_so_path, 0755) != 0) { LOGE("Failed to change permissions on %s: %s (errno: %d)", new_so_path, strerror(errno), errno); return; } else { LOGI("Successfully changed permissions to 755 on %s", new_so_path); } - void * handle; - // 使用 xdl_open 打开新复制的 so 文件 + + // 加载 .so 文件 + void *handle; for (int i = 0; i < 10; i++) { -// void *handle = xdl_open(new_so_path, 0); handle = dlopen(new_so_path, RTLD_NOW | RTLD_LOCAL); if (handle) { LOGI("Successfully loaded %s", new_so_path); @@ -74,9 +82,13 @@ void hack_start(const char *game_data_dir,JavaVM *vm) { sleep(1); } } + + // 如果加载失败 if (!load) { - LOGI("test.so not found in thread %d", gettid()); + LOGI("%s.so not found in thread %d", soname, gettid()); } + + // 查找 JNI_OnLoad 并调用 void (*JNI_OnLoad)(JavaVM *, void *); *(void **) (&JNI_OnLoad) = dlsym(handle, "JNI_OnLoad"); if (JNI_OnLoad) { @@ -85,6 +97,9 @@ void hack_start(const char *game_data_dir,JavaVM *vm) { } else { LOGE("JNI_OnLoad symbol not found in %s", new_so_path); } +} +void hack_start(const char *game_data_dir,JavaVM *vm) { + load_so(game_data_dir,vm,"test"); } diff --git a/module/src/main/cpp/log.h b/module/src/main/cpp/log.h index bb4e5f1..5571db0 100644 --- a/module/src/main/cpp/log.h +++ b/module/src/main/cpp/log.h @@ -7,7 +7,7 @@ #include -#define LOG_TAG "Perfare" +#define LOG_TAG "myinjector" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) From be5208409d5166518a79792f31c57e9c1db78b3a Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Mon, 28 Oct 2024 22:20:58 +0800 Subject: [PATCH 2/4] =?UTF-8?q?jni=E8=B0=83=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/game.h | 2 +- module/src/main/cpp/hack.cpp | 18 +++++++++--------- module/src/main/cpp/main.cpp | 8 ++++++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/module/src/main/cpp/game.h b/module/src/main/cpp/game.h index 81a30b0..c4fac4a 100644 --- a/module/src/main/cpp/game.h +++ b/module/src/main/cpp/game.h @@ -5,6 +5,6 @@ #ifndef ZYGISK_IL2CPPDUMPER_GAME_H #define ZYGISK_IL2CPPDUMPER_GAME_H -#define AimPackageName "com.sankuai.meituan" +#define AimPackageName "com.tencent.mobileqq" #endif //ZYGISK_IL2CPPDUMPER_GAME_H diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index 25d5a18..bc526fb 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -89,18 +89,18 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { } // 查找 JNI_OnLoad 并调用 - void (*JNI_OnLoad)(JavaVM *, void *); - *(void **) (&JNI_OnLoad) = dlsym(handle, "JNI_OnLoad"); - if (JNI_OnLoad) { - LOGI("JNI_OnLoad symbol found, calling JNI_OnLoad."); - JNI_OnLoad(vm, NULL); - } else { - LOGE("JNI_OnLoad symbol not found in %s", new_so_path); - } +// void (*setupSignalHandler)(); +// *(void **) (&setupSignalHandler) = dlsym(handle, "setupSignalHandler"); +// +// if (setupSignalHandler) { +// LOGI("setupSignalHandler symbol found, calling setupSignalHandler."); +// setupSignalHandler(); // 调用找到的函数 +// } else { +// LOGE("setupSignalHandler symbol not found in %s", new_so_path); +// } } void hack_start(const char *game_data_dir,JavaVM *vm) { load_so(game_data_dir,vm,"test"); - } std::string GetLibDir(JavaVM *vms) { diff --git a/module/src/main/cpp/main.cpp b/module/src/main/cpp/main.cpp index 5fa0b4f..42cbe83 100644 --- a/module/src/main/cpp/main.cpp +++ b/module/src/main/cpp/main.cpp @@ -25,7 +25,11 @@ public: void preAppSpecialize(AppSpecializeArgs *args) override { auto package_name = env->GetStringUTFChars(args->nice_name, nullptr); auto app_data_dir = env->GetStringUTFChars(args->app_data_dir, nullptr); - LOGI("preAppSpecialize %s %s", package_name, app_data_dir); +// if (strcmp(package_name, AimPackageName) == 0){ +// args->runtime_flags=8451; +// } + LOGI("preAppSpecialize %s %s %d", package_name, app_data_dir,args->runtime_flags); + preSpecialize(package_name, app_data_dir); env->ReleaseStringUTFChars(args->nice_name, package_name); env->ReleaseStringUTFChars(args->app_data_dir, app_data_dir); @@ -47,7 +51,7 @@ private: size_t length; void preSpecialize(const char *package_name, const char *app_data_dir) { - if (strcmp(package_name, AimPackageName) == 0) { + if (strcmp(package_name, AimPackageName) == 0||strcmp(package_name, "com.tencent.mobileqq:MSF") == 0) { LOGI("成功注入目标进程: %s", package_name); enable_hack = true; _data_dir = new char[strlen(app_data_dir) + 1]; From 7d5a626750162f6aeeee4bcb39e008f04708ff19 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Fri, 15 Nov 2024 14:10:13 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E8=A7=84=E8=8C=83?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=8A=A0=E4=B8=80=E5=AE=9A=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/src/main/cpp/hack.cpp | 1 + module/src/main/cpp/main.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/module/src/main/cpp/hack.cpp b/module/src/main/cpp/hack.cpp index bc526fb..28ef6f0 100644 --- a/module/src/main/cpp/hack.cpp +++ b/module/src/main/cpp/hack.cpp @@ -101,6 +101,7 @@ void load_so(const char *game_data_dir, JavaVM *vm, const char *soname) { } void hack_start(const char *game_data_dir,JavaVM *vm) { load_so(game_data_dir,vm,"test"); + //如果要注入多个so,那么就在这里不断的添加load_so函数即可 } std::string GetLibDir(JavaVM *vms) { diff --git a/module/src/main/cpp/main.cpp b/module/src/main/cpp/main.cpp index 42cbe83..4594e0c 100644 --- a/module/src/main/cpp/main.cpp +++ b/module/src/main/cpp/main.cpp @@ -51,7 +51,7 @@ private: size_t length; void preSpecialize(const char *package_name, const char *app_data_dir) { - if (strcmp(package_name, AimPackageName) == 0||strcmp(package_name, "com.tencent.mobileqq:MSF") == 0) { + if (strcmp(package_name, AimPackageName) == 0) { LOGI("成功注入目标进程: %s", package_name); enable_hack = true; _data_dir = new char[strlen(app_data_dir) + 1]; From 14ad58ec74394d7e94a861af0ae7f51d32d73528 Mon Sep 17 00:00:00 2001 From: jiqiu2021 Date: Fri, 15 Nov 2024 14:22:19 +0800 Subject: [PATCH 4/4] =?UTF-8?q?=E6=B7=BB=E5=8A=A0readme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 61 +++++++++++++++++++++++++++++++++++-------------- README.zh-CN.md | 19 --------------- 2 files changed, 44 insertions(+), 36 deletions(-) delete mode 100644 README.zh-CN.md diff --git a/README.md b/README.md index d4ed2d4..18f3d30 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,48 @@ -# Zygisk-Il2CppDumper -Il2CppDumper with Zygisk, dump il2cpp data at runtime, can bypass protection, encryption and obfuscation. +# [Zygisk-MyInjector](https://github.com/jiqiu2022/Zygisk-MyInjector) -中文说明请戳[这里](README.zh-CN.md) -## How to use -1. Install [Magisk](https://github.com/topjohnwu/Magisk) v24 or later and enable Zygisk -2. Build module + +原项目https://github.com/Perfare/Zygisk-Il2CppDumper + +本项目在原项目基础上做局部更改,请支持原项目作者劳动成果 + +1. 安装[Magisk](https://github.com/topjohnwu/Magisk) v24以上版本并开启Zygisk +2. 生成模块 - GitHub Actions - 1. Fork this repo - 2. Go to the **Actions** tab in your forked repo - 3. In the left sidebar, click the **Build** workflow. - 4. Above the list of workflow runs, select **Run workflow** - 5. Input the game package name and click **Run workflow** - 6. Wait for the action to complete and download the artifact + 1. Fork这个项目 + 2. 在你fork的项目中选择**Actions**选项卡 + 3. 在左边的侧边栏中,单击**Build** + 4. 选择**Run workflow** + 5. 输入游戏包名并点击**Run workflow** + 6. 等待操作完成并下载 - Android Studio - 1. Download the source code - 2. Edit `game.h`, modify `AimPackageName` to the game package name - 3. Use Android Studio to run the gradle task `:module:assembleRelease` to compile, the zip package will be generated in the `out` folder -3. Install module in Magisk -4. Start the game, `dump.cs` will be generated in the `/data/data/AimPackageName/files/` directory \ No newline at end of file + 1. 下载源码 + 2. 编辑`game.h`, 修改`GamePackageName`为游戏包名 + 3. 使用Android Studio运行gradle任务`:module:assembleRelease`编译,zip包会生成在`out`文件夹下 +3. 在Magisk里安装模块 + +4. 将要注入的so放入到/data/local/tmp下修改为test.so + + (部分手机第一次注入不会成功,请重启,再之后的注入会成功) + +目前正在开发的分支: + +​ 1. 使用Java的System.load加载so + +​ 2. 注入多个so的分支 + +计划开发: + +1. 第一步,仿照Riru,将注入的so进行内存上的初步隐藏(可以对抗部分业务检测,游戏安全相关已经补齐,建议不要尝试) +2. 第二步,实现一个自定义的linker,进行更深层次的注入隐藏 +3. 第三步,搭配对应配套手机的内核模块对注入的模块进行进一步完美擦除,达到完美注入的目的 + +以此项目为脚手架的计划开发: + +1. 一个全新的Frida框架,保留大部分原生api,并可以过任何相关注入检测 + +2. 一个全新的Trace框架,高性能Trace,速度是Stallker的60倍,并且支持更全面的信息打印。(具体效果可以参考看雪帖子) + +3. 一个全新的无痕调试框架,支持像GDB一样调试,没有ptrace痕迹,两种思路进行无痕调试(基于硬件断点以及基于VM) + + \ No newline at end of file diff --git a/README.zh-CN.md b/README.zh-CN.md deleted file mode 100644 index f8b2012..0000000 --- a/README.zh-CN.md +++ /dev/null @@ -1,19 +0,0 @@ -# Zygisk-Il2CppDumper -Zygisk版Il2CppDumper,在游戏运行时dump il2cpp数据,可以绕过保护,加密以及混淆。 - -## 如何食用 -1. 安装[Magisk](https://github.com/topjohnwu/Magisk) v24以上版本并开启Zygisk -2. 生成模块 - - GitHub Actions - 1. Fork这个项目 - 2. 在你fork的项目中选择**Actions**选项卡 - 3. 在左边的侧边栏中,单击**Build** - 4. 选择**Run workflow** - 5. 输入游戏包名并点击**Run workflow** - 6. 等待操作完成并下载 - - Android Studio - 1. 下载源码 - 2. 编辑`game.h`, 修改`AimPackageName`为游戏包名 - 3. 使用Android Studio运行gradle任务`:module:assembleRelease`编译,zip包会生成在`out`文件夹下 -3. 在Magisk里安装模块 -4. 启动游戏,会在`/data/data/AimPackageName/files/`目录下生成`dump.cs` \ No newline at end of file