Skip to content

Commit

Permalink
Merge some latest sources from Zygisk-Il2CppDumper
Browse files Browse the repository at this point in the history
xdl will be unused due to lack of emulator compatibility
BNMUtils.h has been removed
Gradle updated to 8.0.1
  • Loading branch information
AndnixSH committed May 17, 2023
1 parent a24ac97 commit 741ac21
Show file tree
Hide file tree
Showing 21 changed files with 2,071 additions and 212 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ Il2CppDumper without Magisk/Zygisk, dump il2cpp data at runtime, can bypass prot
This project is based on BrianGIG [Auto-Il2cppDumper](https://github.com/BryanGIG/Auto-Il2cppDumper) which I continue to maintain it

# How to use
This is full auto dumper, no need to put unity version anymore since it's based on Zygisk-Il2cppDumper.

Download pre-compiled libs [HERE](https://github.com/AndnixSH/Auto-Il2cppDumper/releases) and follow steps below

Note: Non-root methods involves modifying APK file, you may need to bypass APK integrity or signature check if it's present. I won't get into the details of bypassing anything because it is simply out of the scope

## Method 1: Fake lib
This is a trick to load our own libunity.so or libmain.so and load game's renamed original lib librealunity.so or librealmain.so. Can't decide which lib? Try libmain.so first as it sometimes work better than libunity.so or vice versa

Expand All @@ -29,7 +29,7 @@ Some games may have APK integrity and signature check. You may need to bypass it
- Install the APK

### Method 2: Lib call
If renaming lib doesn't work, try this method. Some games may have APK integrity and signature check. You may need to bypass it before adding Il2CppDumper
If renaming lib doesn't work, try this method.

- Decompile the game using Apktool
- Copy libil2cppdumper.so into the lib folder. Make sure only copy same ABIs as the target app, for example if target app has only armeabi-v7a, then you should only copy armeabi-v7a
Expand Down Expand Up @@ -75,7 +75,7 @@ Like
- Wait a few seconds. Let the game load into main screen
- Once the dump is complete, it will save the dump.cs in /storage/emulated/0/Android/data/(Package name)/
![](Images/2.png)
- If there is no dump.cs, check logcat using Matlog or Android Studio. Game should crash or freeze if dump fails
- If there is no dump.cs, check logcat using Matlog or Android Studio. Game usually crash or freeze if dump fails

### Obfuscated names
Names can't be deobfuscated. Once they are obfuscated/renamed, it can't be reverted back to original, the APK doesn't even have a brain to memorize all original names. Instead, try find older version without obfuscation, or debug the game using GG, frida, gdb, lldb or others. If you can't do any of these, maybe guess the functions and try one by one :P
Expand All @@ -89,8 +89,6 @@ In config header `jni/Includes/config.h`:

`UseFakeLib` is to use it as root mode

`RealLibToLoad` is the target lib to be faked

`Sleep` is to delay dumping. Increase if getting issue with dumper, like if not fully dumped

# Credits
Expand Down
9 changes: 7 additions & 2 deletions app/src/main/jni/Android.mk
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,14 @@ LOCAL_LDFLAGS += -Wl,--gc-sections,--strip-all, -llog
LOCAL_ARM_MODE := arm

LOCAL_C_INCLUDES += $(MAIN_LOCAL_PATH)
LOCAL_C_INCLUDES += $(LOCAL_PATH)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/Il2Cpp/xdl/include

LOCAL_SRC_FILES := native-lib.cpp \
FILE_LIST := $(wildcard $(LOCAL_PATH)/Il2Cpp/xdl/*.c)

LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)
LOCAL_SRC_FILES += native-lib.cpp \
Il2Cpp/il2cpp_dump.cpp

LOCAL_LDLIBS := -llog -landroid -lGLESv2
LOCAL_LDLIBS := -llog -landroid -lGLESv2 -ldl
include $(BUILD_SHARED_LIBRARY)
82 changes: 31 additions & 51 deletions app/src/main/jni/Il2Cpp/il2cpp_dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@
#include <vector>
#include <sstream>
#include <fstream>
#include <jni.h>
#include <unistd.h>
#include "xdl.h"
#include "Includes/log.h"
#include "il2cpp-tabledefs.h"
#include "il2cpp-class.h"
#include <jni.h>


#define DO_API(r, n, p) r (*n) p

#include "il2cpp-api-functions.h"
#include <Includes/BNMUtils.h>

#undef DO_API

static void *il2cpp_handle = nullptr;
static uint64_t il2cpp_base = 0;

const char *GetPackageName() {
Expand All @@ -38,40 +38,21 @@ const char *GetPackageName() {
return (const char *) application_id;
}

void init_il2cpp_api() {
#define DO_API(r, n, p) n = (r (*) p)dlsym(il2cpp_handle, #n)
void init_il2cpp_api(void *handle) {
#define DO_API(r, n, p) n = (r (*) p)dlsym(handle, #n)

#include "il2cpp-api-functions.h"
// Do not use XDL yet because it doesn't support emulators

#undef DO_API
}
/*#define DO_API(r, n, p) { \
n = (r (*) p)xdl_sym(handle, #n, nullptr); \
if(!n) { \
LOGW("api not found %s", #n); \
} \
}*/

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];
#include "il2cpp-api-functions.h"

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;
#undef DO_API
}

std::string get_method_modifier(uint32_t flags) {
Expand Down Expand Up @@ -358,32 +339,31 @@ std::string dump_type(const Il2CppType *type) {
return outPut.str();
}

void il2cpp_dump(void *handle) {
void il2cpp_api_init(void *handle) {
LOGI("il2cpp_handle: %p", handle);
il2cpp_handle = handle;
init_il2cpp_api();
init_il2cpp_api(handle);
if (il2cpp_domain_get_assemblies) {
Dl_info dlInfo;
if (dladdr((void *) il2cpp_domain_get_assemblies, &dlInfo)) {
il2cpp_base = reinterpret_cast<uint64_t>(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 {
LOGE("Failed to initialize il2cpp api.");
return;
}

while (!il2cpp_is_vm_thread(nullptr)) {
LOGI("Waiting for il2cpp_init...");
sleep(1);
}
auto domain = il2cpp_domain_get();
LOGI("il2cpp_thread_attach");
il2cpp_thread_attach(domain);
}

//start dump
LOGI("Get all assemblies");

void il2cpp_dump(const char *outDir) {
LOGI("dumping...");
size_t size;
auto domain = il2cpp_domain_get();
auto assemblies = il2cpp_domain_get_assemblies(domain, &size);
//geokar2006's bypass
//auto assemblies = Assembly$$GetAllAssemblies();
Expand Down Expand Up @@ -448,7 +428,7 @@ void il2cpp_dump(void *handle) {
auto imageName = std::string(image_name);
auto pos = imageName.rfind('.');
auto imageNameNoExt = imageName.substr(0, pos);
auto assemblyFileName = il2cpp_string_new(imageNameNoExt.c_str());
auto assemblyFileName = il2cpp_string_new(imageNameNoExt.data());
auto reflectionAssembly = ((Assembly_Load_ftn) assemblyLoad->methodPointer)(nullptr,
assemblyFileName,
nullptr);
Expand All @@ -464,12 +444,12 @@ void il2cpp_dump(void *handle) {
}
}
}

auto androidDataPath = std::string("/storage/emulated/0/Android/data/").append(GetPackageName()).append("/").append(GetPackageName()).append("-dump.cs");

LOGI("Save dump file to %s", androidDataPath.c_str());

std::ofstream outStream(androidDataPath);
auto outPath = std::string(outDir);
LOGI("Save dump file to %s", outPath.c_str());
std::ofstream outStream(outPath);
outStream << imageOutput.str();
auto count = outPuts.size();
for (int i = 0; i < count; ++i) {
Expand Down
10 changes: 6 additions & 4 deletions app/src/main/jni/Il2Cpp/il2cpp_dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
// Created by Perfare on 2020/7/4.
//

#ifndef RIRU_IL2CPPDUMPER_IL2CPP_H
#define RIRU_IL2CPPDUMPER_IL2CPP_H
#ifndef AUTO_IL2CPPDUMPER_IL2CPP_DUMP_H
#define AUTO_IL2CPPDUMPER_IL2CPP_DUMP_H

void il2cpp_dump(void *handle);
void il2cpp_api_init(void *handle);

void il2cpp_dump(const char *outDir);

const char* GetPackageName();

#endif //RIRU_IL2CPPDUMPER_IL2CPP_H
#endif //AUTO_IL2CPPDUMPER_IL2CPP_DUMP_H
92 changes: 92 additions & 0 deletions app/src/main/jni/Il2Cpp/xdl/include/xdl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright (c) 2020-2023 HexHacking Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//

// Created by caikelun on 2020-10-04.

//
// xDL version: 2.0.0
//
// xDL is an enhanced implementation of the Android DL series functions.
// For more information, documentation, and the latest version please check:
// https://github.com/hexhacking/xDL
//

#ifndef IO_GITHUB_HEXHACKING_XDL
#define IO_GITHUB_HEXHACKING_XDL

#include <dlfcn.h>
#include <link.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
// same as Dl_info:
const char *dli_fname; // Pathname of shared object that contains address.
void *dli_fbase; // Address at which shared object is loaded.
const char *dli_sname; // Name of nearest symbol with address lower than addr.
void *dli_saddr; // Exact address of symbol named in dli_sname.
// added by xDL:
size_t dli_ssize; // Symbol size of nearest symbol with address lower than addr.
const ElfW(Phdr) *dlpi_phdr; // Pointer to array of ELF program headers for this object.
size_t dlpi_phnum; // Number of items in dlpi_phdr.
} xdl_info_t;

//
// Default value for flags in both xdl_open() and xdl_iterate_phdr().
//
#define XDL_DEFAULT 0x00

//
// Enhanced dlopen() / dlclose() / dlsym().
//
#define XDL_TRY_FORCE_LOAD 0x01
#define XDL_ALWAYS_FORCE_LOAD 0x02
void *xdl_open(const char *filename, int flags);
void *xdl_close(void *handle);
void *xdl_sym(void *handle, const char *symbol, size_t *symbol_size);
void *xdl_dsym(void *handle, const char *symbol, size_t *symbol_size);

//
// Enhanced dladdr().
//
int xdl_addr(void *addr, xdl_info_t *info, void **cache);
void xdl_addr_clean(void **cache);

//
// Enhanced dl_iterate_phdr().
//
#define XDL_FULL_PATHNAME 0x01
int xdl_iterate_phdr(int (*callback)(struct dl_phdr_info *, size_t, void *), void *data, int flags);

//
// Custom dlinfo().
//
#define XDL_DI_DLINFO 1 // type of info: xdl_info_t
int xdl_info(void *handle, int request, void *info);

#ifdef __cplusplus
}
#endif

#endif
Loading

0 comments on commit 741ac21

Please sign in to comment.