diff --git a/app/build.gradle b/app/build.gradle index fe1c9c5f..7f60bf81 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,7 +9,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 1 - versionName "1.0" + versionName "0.0.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { @@ -32,7 +32,8 @@ android { } release { signingConfig signingConfigs.sign - minifyEnabled false + minifyEnabled true + shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } @@ -57,6 +58,7 @@ dependencies { implementation "moe.shizuku.support:recyclerview-utils:3.0.4" implementation "moe.shizuku.support:design:3.1.0" implementation "moe.shizuku.support:support-utils:3.0.4" + implementation "moe.shizuku.support:htmlcompat:2.0.0" } repositories { mavenCentral() diff --git a/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java b/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java index f8b80af1..ac6e76d7 100644 --- a/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java +++ b/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java @@ -1,12 +1,13 @@ package moe.riru.manager; import android.content.Context; -import android.support.test.InstrumentationRegistry; -import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; +import androidx.test.InstrumentationRegistry; +import androidx.test.runner.AndroidJUnit4; + import static org.junit.Assert.*; /** diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ad1f586a..be5faa8f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,7 @@ android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" + android:theme="@style/AppTheme" tools:ignore="GoogleAppIndexingWarning" > diff --git a/app/src/main/cpp/helper.cpp b/app/src/main/cpp/helper.cpp index 97d800a8..e83ee449 100644 --- a/app/src/main/cpp/helper.cpp +++ b/app/src/main/cpp/helper.cpp @@ -55,13 +55,13 @@ int xh_elf_check_elfheader(uintptr_t base_addr) { //check machine #if defined(__arm__) - if(EM_ARM != ehdr->e_machine) return XH_ERRNO_FORMAT; + if(EM_ARM != ehdr->e_machine) return 1; #elif defined(__aarch64__) if (EM_AARCH64 != ehdr->e_machine) return 1; #elif defined(__i386__) - if(EM_386 != ehdr->e_machine) return XH_ERRNO_FORMAT; + if(EM_386 != ehdr->e_machine) return 1; #elif defined(__x86_64__) - if(EM_X86_64 != ehdr->e_machine) return XH_ERRNO_FORMAT; + if(EM_X86_64 != ehdr->e_machine) return 1; #else return XH_ERRNO_FORMAT; #endif @@ -72,10 +72,6 @@ int xh_elf_check_elfheader(uintptr_t base_addr) { return 0; } -#define PAGE_START(addr) ((addr) & PAGE_MASK) -#define PAGE_END(addr) (PAGE_START(addr + sizeof(uintptr_t) - 1) + PAGE_SIZE) -#define PAGE_COVER(addr) (PAGE_END(addr) - PAGE_START(addr)) - static int init_elf(const char *pathname, uintptr_t base_in_mem) { struct stat statbuf{}; int fd = open(pathname, O_RDONLY | O_CLOEXEC); @@ -138,14 +134,20 @@ static int init_elf(const char *pathname, uintptr_t base_in_mem) { if (strcmp("riru_get_version", (char *) dynstr + dynsyms[i].st_name) == 0) riru_get_version_addr = dynsyms[i].st_value + base_in_mem; - else if (strcmp("riru_get_original_native_methods", (char *) dynstr + dynsyms[i].st_name) == 0) + else if (strcmp("riru_get_original_native_methods", + (char *) dynstr + dynsyms[i].st_name) == 0) riru_get_original_native_methods_addr = dynsyms[i].st_value + base_in_mem; - else if (strcmp("riru_is_zygote_methods_replaced", (char *) dynstr + dynsyms[i].st_name) == 0) + else if (strcmp("riru_is_zygote_methods_replaced", + (char *) dynstr + dynsyms[i].st_name) == 0) riru_is_zygote_methods_replaced_addr = dynsyms[i].st_value + base_in_mem; - else if (strcmp("riru_get_nativeForkAndSpecialize_calls_count", (char *) dynstr + dynsyms[i].st_name) == 0) - riru_get_nativeForkAndSpecialize_calls_count_addr = dynsyms[i].st_value + base_in_mem; - else if (strcmp("riru_get_nativeForkSystemServer_calls_count", (char *) dynstr + dynsyms[i].st_name) == 0) - riru_get_nativeForkSystemServer_calls_count_addr = dynsyms[i].st_value + base_in_mem; + else if (strcmp("riru_get_nativeForkAndSpecialize_calls_count", + (char *) dynstr + dynsyms[i].st_name) == 0) + riru_get_nativeForkAndSpecialize_calls_count_addr = + dynsyms[i].st_value + base_in_mem; + else if (strcmp("riru_get_nativeForkSystemServer_calls_count", + (char *) dynstr + dynsyms[i].st_name) == 0) + riru_get_nativeForkSystemServer_calls_count_addr = + dynsyms[i].st_value + base_in_mem; } } @@ -205,6 +207,30 @@ static jint get_nativeForkSystemServer_calls_count(JNIEnv *env, jobject thiz) { return ((int (*)()) riru_get_nativeForkSystemServer_calls_count_addr)(); } +static jstring get_nativeForkAndSpecialize_signature(JNIEnv *env, jobject thiz) { + if (!riru_get_original_native_methods_addr) + return nullptr; + + auto method = ((const JNINativeMethod *(*)(const char *, const char *, const char *)) riru_get_original_native_methods_addr)( + "com/android/internal/os/Zygote", "nativeForkAndSpecialize", nullptr); + if (method != nullptr) + return env->NewStringUTF(method->signature); + else + return nullptr; +} + +static jstring get_nativeForkSystemServer_signature(JNIEnv *env, jobject thiz) { + if (!riru_get_original_native_methods_addr) + return nullptr; + + auto method = ((const JNINativeMethod *(*)(const char *, const char *, const char *)) riru_get_original_native_methods_addr)( + "com/android/internal/os/Zygote", "nativeForkSystemServer", nullptr); + if (method != nullptr) + return env->NewStringUTF(method->signature); + else + return nullptr; +} + static JNINativeMethod gMethods[] = { {"init", "()Z", (void *) init}, {"isRiruModuleExists", "(Ljava/lang/String;)Z", (void *) is_riru_module_exists}, @@ -212,6 +238,8 @@ static JNINativeMethod gMethods[] = { {"isZygoteMethodsReplaced", "()Z", (void *) is_zygote_methods_replaced}, {"getNativeForkAndSpecializeCallsCount", "()I", (void *) get_nativeForkAndSpecialize_calls_count}, {"getNativeForkSystemServerCallsCount", "()I", (void *) get_nativeForkSystemServer_calls_count}, + {"getNativeForkAndSpecializeSignature", "()Ljava/lang/String;", (void *) get_nativeForkAndSpecialize_signature}, + {"getNativeForkSystemServerSignature", "()Ljava/lang/String;", (void *) get_nativeForkSystemServer_signature}, }; static int registerNativeMethods(JNIEnv *env, const char *className, diff --git a/app/src/main/java/moe/riru/manager/MainActivity.java b/app/src/main/java/moe/riru/manager/MainActivity.java index 3353325e..2d815f8b 100644 --- a/app/src/main/java/moe/riru/manager/MainActivity.java +++ b/app/src/main/java/moe/riru/manager/MainActivity.java @@ -1,11 +1,15 @@ package moe.riru.manager; +import android.app.AlertDialog; +import android.content.ClipData; +import android.content.ClipboardManager; import android.os.Bundle; import android.util.Log; import androidx.annotation.Nullable; import moe.riru.manager.app.BaseActivity; import moe.riru.manager.utils.NativeHelper; +import moe.shizuku.support.text.HtmlCompat; public class MainActivity extends BaseActivity { @@ -13,10 +17,64 @@ public class MainActivity extends BaseActivity { protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + boolean init, isZygoteMethodsReplaced; + int version, nativeForkAndSpecializeCallsCount, nativeForkSystemServerCallsCount; + String nativeForkAndSpecializeSignature, nativeForkSystemServerSignature; + + StringBuilder sb = new StringBuilder(); + + init = NativeHelper.init(); + if (init) { + version = NativeHelper.getRiruVersion(); + if (version < 13) { + sb.append("Riru version less than 13, diagnostic is only available for Riru v13 or above."); + } else { + isZygoteMethodsReplaced = NativeHelper.isZygoteMethodsReplaced(); + nativeForkAndSpecializeCallsCount = NativeHelper.getNativeForkAndSpecializeCallsCount(); + nativeForkSystemServerCallsCount = NativeHelper.getNativeForkSystemServerCallsCount(); + nativeForkAndSpecializeSignature = NativeHelper.getNativeForkAndSpecializeSignature(); + nativeForkSystemServerSignature = NativeHelper.getNativeForkSystemServerSignature(); + + sb.append("Riru v").append(version).append(" found.").append("
"); + + if (isZygoteMethodsReplaced) { + sb.append("Native methods of Zygote class replaced.").append("

") + .append("nativeForkAndSpecialize calls count: ").append(nativeForkAndSpecializeCallsCount).append("
") + .append("nativeForkSystemServer calls count: ").append(nativeForkSystemServerCallsCount).append("
"); + + if (nativeForkAndSpecializeCallsCount == 0) { + sb.append("
nativeForkAndSpecialize calls count is 0, Riru is not working correctly.
This may because Riru's hook is overwritten by other things, please check yourself."); + } else if (nativeForkSystemServerCallsCount != 0) { + sb.append("
Everything looks fine :D"); + } + } else { + sb.append("However, native methods of Zygote class not replaced, please contact developer with the following information.").append("

") + .append("nativeForkAndSpecializeSignature:
").append(nativeForkAndSpecializeSignature).append("

") + .append("getNativeForkSystemServerSignature:
").append(nativeForkSystemServerSignature).append(""); + } + } + } else { + sb.append("Riru not found in memory."); + } + + new AlertDialog.Builder(this) + .setMessage(HtmlCompat.fromHtml(sb.toString())) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + finish(); + }) + .setNeutralButton("Copy", (dialog, which) -> { + getSystemService(ClipboardManager.class).setPrimaryClip(ClipData.newPlainText("text", HtmlCompat.fromHtml(sb.toString()).toString())); + finish(); + }) + .setCancelable(false) + .show(); + Log.i("RiruManager", "init: " + NativeHelper.init()); Log.i("RiruManager", "getRiruVersion: " + NativeHelper.getRiruVersion()); Log.i("RiruManager", "isZygoteMethodsReplaced: " + NativeHelper.isZygoteMethodsReplaced()); Log.i("RiruManager", "getNativeForkAndSpecializeCallsCount: " + NativeHelper.getNativeForkAndSpecializeCallsCount()); Log.i("RiruManager", "getNativeForkSystemServerCallsCount: " + NativeHelper.getNativeForkSystemServerCallsCount()); + Log.i("RiruManager", "getNativeForkAndSpecializeSignature: " + NativeHelper.getNativeForkAndSpecializeSignature()); + Log.i("RiruManager", "getNativeForkSystemServerSignature: " + NativeHelper.getNativeForkSystemServerSignature()); } } diff --git a/app/src/main/java/moe/riru/manager/utils/NativeHelper.java b/app/src/main/java/moe/riru/manager/utils/NativeHelper.java index 0226862e..193dad18 100644 --- a/app/src/main/java/moe/riru/manager/utils/NativeHelper.java +++ b/app/src/main/java/moe/riru/manager/utils/NativeHelper.java @@ -1,5 +1,8 @@ package moe.riru.manager.utils; +import androidx.annotation.Keep; + +@Keep public class NativeHelper { static { @@ -12,4 +15,6 @@ public class NativeHelper { public static native boolean isZygoteMethodsReplaced(); public static native int getNativeForkAndSpecializeCallsCount(); public static native int getNativeForkSystemServerCallsCount(); + public static native String getNativeForkAndSpecializeSignature(); + public static native String getNativeForkSystemServerSignature(); }