diff --git a/.gitattributes b/.gitattributes index 12c34eb..1341b04 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,2 @@ *.prop text eol=lf -*.sh text eol=lf -gradle/wrapper/gradle-4.10.1-all.zip filter=lfs diff=lfs merge=lfs -text +*.sh text eol=lf \ No newline at end of file diff --git a/.gitignore b/.gitignore index e07007a..a750d98 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,8 @@ .DS_Store /build /captures -/release +/out .externalNativeBuild elf-cleaner.sh settings.gradle +.cxx \ No newline at end of file diff --git a/README.md b/README.md old mode 100644 new mode 100755 index 934e14c..209ef3b --- a/README.md +++ b/README.md @@ -38,8 +38,8 @@ Magisk 版 [Xposed Fingerprint pay](https://github.com/eritpchy/Xposed-Fingerpri ## 编译 -1. 运行./gradlew :riru-module-xfingerprint-pay-taobao:zip -2. 编译文件位于./release +1. 运行./gradlew :module:assembleRelease +2. 编译文件位于./out ## 致谢 diff --git a/app/.gitignore b/app/.gitignore deleted file mode 100644 index 921d403..0000000 --- a/app/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/build -signing.properties \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle deleted file mode 100644 index 0cdeb08..0000000 --- a/app/build.gradle +++ /dev/null @@ -1,67 +0,0 @@ -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android-extensions' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion rootProject.ext.targetSdkVersion - defaultConfig { - applicationId "moe.riru.manager" - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 4 - versionName "0.0.4" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - externalNativeBuild { - cmake { - abiFilters "armeabi-v7a", 'arm64-v8a', 'x86', 'x86_64' - cppFlags "-std=c++11" - arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static' - } - } - } - compileOptions { - sourceCompatibility 1.8 - targetCompatibility 1.8 - } - signingConfigs { - sign - } - buildTypes { - debug { - signingConfig signingConfigs.sign - } - release { - signingConfig signingConfigs.sign - minifyEnabled true - shrinkResources true - proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - } - } - externalNativeBuild { - cmake { - path "src/main/cpp/CMakeLists.txt" - } - } - splits { - abi { - enable false - } - } -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.2' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - 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() -} - -apply from: project.file('signing.gradle') \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/app/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/app/signing.gradle b/app/signing.gradle deleted file mode 100644 index b491fd2..0000000 --- a/app/signing.gradle +++ /dev/null @@ -1,17 +0,0 @@ -def ksFile = project.file('signing.properties') -def props = new Properties() -if (ksFile.canRead()) { - props.load(new FileInputStream(ksFile)) - - if (props != null) { - android.signingConfigs.sign.storeFile file(props['KEYSTORE_FILE']) - android.signingConfigs.sign.storePassword props['KEYSTORE_PASSWORD'] - android.signingConfigs.sign.keyAlias props['KEYSTORE_ALIAS'] - android.signingConfigs.sign.keyPassword props['KEYSTORE_ALIAS_PASSWORD'] - } else { - println 'some entries in \'signing.properties\' not found!' - } -} else { - println '\'signing.properties\' not found!' -} - diff --git a/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java b/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java deleted file mode 100644 index ac6e76d..0000000 --- a/app/src/androidTest/java/moe/riru/manager/ExampleInstrumentedTest.java +++ /dev/null @@ -1,27 +0,0 @@ -package moe.riru.manager; - -import android.content.Context; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import androidx.test.InstrumentationRegistry; -import androidx.test.runner.AndroidJUnit4; - -import static org.junit.Assert.*; - -/** - * Instrumented test, which will execute on an Android device. - * - * @see Testing documentation - */ -@RunWith(AndroidJUnit4.class) -public class ExampleInstrumentedTest { - @Test - public void useAppContext() { - // Context of the app under test. - Context appContext = InstrumentationRegistry.getTargetContext(); - - assertEquals("moe.riru.manager", appContext.getPackageName()); - } -} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml deleted file mode 100644 index be5faa8..0000000 --- a/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt deleted file mode 100644 index abdefa7..0000000 --- a/app/src/main/cpp/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -cmake_minimum_required(VERSION 3.4.1) - -set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--hash-style=both") - -add_library(helper SHARED - helper.cpp pmparser.c) - -target_link_libraries(helper - log) \ No newline at end of file diff --git a/app/src/main/cpp/helper.cpp b/app/src/main/cpp/helper.cpp deleted file mode 100644 index c5be2bc..0000000 --- a/app/src/main/cpp/helper.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include "logging.h" - -extern "C" { -#include "pmparser.h" -} - -static jboolean is_path_in_maps(const char *path) { - procmaps_iterator *maps = pmparser_parse(-1); - if (maps == nullptr) { - LOGE("[map]: cannot parse the memory map"); - return JNI_FALSE; - } - - procmaps_struct *maps_tmp = nullptr; - while ((maps_tmp = pmparser_next(maps)) != nullptr) { - if (strstr(maps_tmp->pathname, path)) - return JNI_TRUE; - } - pmparser_free(maps); - return JNI_FALSE; -} - -static jboolean init(JNIEnv *env, jobject thiz) { - procmaps_iterator *maps = pmparser_parse(-1); - if (maps == nullptr) { - LOGE("[map]: cannot parse the memory map"); - return JNI_FALSE; - } - - jboolean res = JNI_FALSE; - procmaps_struct *maps_tmp = nullptr; - while ((maps_tmp = pmparser_next(maps)) != nullptr) { - if (strstr(maps_tmp->pathname, "libmemtrack_real.so")) { - res = JNI_TRUE; - } - } - pmparser_free(maps); - return res; -} - -static jboolean is_riru_module_exists(JNIEnv *env, jobject thiz, jstring name) { - // TODO - return JNI_FALSE; -} - -static void *handle; - -static void *get_handle() { - if (handle == nullptr) - handle = dlopen(nullptr, 0); - - return handle; -} - -static jint get_riru_rersion(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return -1; - if (sym == nullptr) sym = dlsym(handle, "riru_get_version"); - if (sym) return ((int (*)()) sym)(); - return -1; -} - -static jboolean is_zygote_methods_replaced(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return JNI_FALSE; - if (sym == nullptr) sym = dlsym(handle, "riru_is_zygote_methods_replaced"); - if (sym) return static_cast(((int (*)()) sym)()); - return JNI_FALSE; -} - -static jint get_nativeForkAndSpecialize_calls_count(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return -1; - if (sym == nullptr) sym = dlsym(handle, "riru_get_nativeForkAndSpecialize_calls_count"); - if (sym) return static_cast(((int (*)()) sym)()); - return -1; -} - -static jint get_nativeForkSystemServer_calls_count(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return -1; - if (sym == nullptr) sym = dlsym(handle, "riru_get_nativeForkSystemServer_calls_count"); - if (sym) return static_cast(((int (*)()) sym)()); - return -1; -} - -static jstring get_nativeForkAndSpecialize_signature(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return nullptr; - if (sym == nullptr) sym = dlsym(handle, "riru_get_original_native_methods"); - if (sym) { - auto method = ((const JNINativeMethod *(*)(const char *, const char *, const char *)) sym)( - "com/android/internal/os/Zygote", "nativeForkAndSpecialize", nullptr); - if (method != nullptr) - return env->NewStringUTF(method->signature); - } - return nullptr; -} - -static jstring get_nativeSpecializeBlastula_signature(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return nullptr; - if (sym == nullptr) sym = dlsym(handle, "riru_get_original_native_methods"); - if (sym) { - auto method = ((const JNINativeMethod *(*)(const char *, const char *, const char *)) sym)( - "com/android/internal/os/Zygote", "nativeSpecializeBlastula", nullptr); - if (method != nullptr) - return env->NewStringUTF(method->signature); - } - return nullptr; -} - -static jstring get_nativeForkSystemServer_signature(JNIEnv *env, jobject thiz) { - static void *sym; - void *handle; - if ((handle = get_handle()) == nullptr) return nullptr; - if (sym == nullptr) sym = dlsym(handle, "riru_get_original_native_methods"); - if (sym) { - auto method = ((const JNINativeMethod *(*)(const char *, const char *, const char *)) sym)( - "com/android/internal/os/Zygote", "nativeForkSystemServer", nullptr); - if (method != nullptr) - return env->NewStringUTF(method->signature); - } - return nullptr; -} - -static JNINativeMethod gMethods[] = { - {"init", "()Z", (void *) init}, - {"isRiruModuleExists", "(Ljava/lang/String;)Z", (void *) is_riru_module_exists}, - {"getRiruVersion", "()I", (void *) get_riru_rersion}, - {"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}, - {"getNativeSpecializeBlastulaSignature", "()Ljava/lang/String;", (void *) get_nativeSpecializeBlastula_signature}, - {"getNativeForkSystemServerSignature", "()Ljava/lang/String;", (void *) get_nativeForkSystemServer_signature}, -}; - -static int registerNativeMethods(JNIEnv *env, const char *className, - JNINativeMethod *gMethods, int numMethods) { - jclass clazz; - clazz = env->FindClass(className); - if (clazz == nullptr) - return JNI_FALSE; - - if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) - return JNI_FALSE; - - return JNI_TRUE; -} - -static int registerNatives(JNIEnv *env) { - if (!registerNativeMethods(env, "moe/riru/manager/utils/NativeHelper", gMethods, - sizeof(gMethods) / sizeof(gMethods[0]))) - return JNI_FALSE; - - return JNI_TRUE; -} - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { - JNIEnv *env = nullptr; - jint result; - - if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) - return -1; - - assert(env != nullptr); - - if (!registerNatives(env)) { - LOGE("registerNatives NativeHelper"); - return -1; - } - - result = JNI_VERSION_1_6; - - return result; -} diff --git a/app/src/main/cpp/logging.h b/app/src/main/cpp/logging.h deleted file mode 100644 index e4d2307..0000000 --- a/app/src/main/cpp/logging.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _LOGGING_H -#define _LOGGING_H - -#include -#include "android/log.h" - -#ifndef LOG_TAG -#define LOG_TAG "RiruManager" -#endif - -//#ifdef DEBUG -#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -/*#else -#define LOGD(...) -#endif*/ -#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, 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__) -#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) - -#endif // _LOGGING_H diff --git a/app/src/main/cpp/pmparser.c b/app/src/main/cpp/pmparser.c deleted file mode 100644 index a07bf34..0000000 --- a/app/src/main/cpp/pmparser.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - @Author : ouadimjamal@gmail.com - @date : December 2015 - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. No representations are made about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. -*/ - -#include "pmparser.h" - -/** - * gobal variables - */ -//procmaps_struct* g_last_head=NULL; -//procmaps_struct* g_current=NULL; - -#include "android/log.h" - -#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__); - -procmaps_iterator* pmparser_parse(int pid){ - procmaps_iterator* maps_it = malloc(sizeof(procmaps_iterator)); - char maps_path[500]; - if(pid>=0 ){ - sprintf(maps_path,"/proc/%d/maps",pid); - }else{ - sprintf(maps_path,"/proc/self/maps"); - } - FILE* file=fopen(maps_path,"r"); - if(!file){ - fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno)); - return NULL; - } - int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH]; - int c; - procmaps_struct* list_maps=NULL; - procmaps_struct* tmp; - procmaps_struct* current_node=list_maps; - char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX]; - while( !feof(file) ){ - fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file); - //allocate a node - tmp=(procmaps_struct*)malloc(sizeof(procmaps_struct)); - //fill the node - _pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname); - //printf("#%s",buf); - //printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); - //addr_start & addr_end - unsigned long l_addr_start; - sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start ); - sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end ); - //size - tmp->length=(unsigned long)(tmp->addr_end-tmp->addr_start); - //perm - strcpy(tmp->perm,perm); - tmp->is_r=(perm[0]=='r'); - tmp->is_w=(perm[1]=='w'); - tmp->is_x=(perm[2]=='x'); - tmp->is_p=(perm[3]=='p'); - - //offset - sscanf(offset,"%lx",&tmp->offset ); - //device - strcpy(tmp->dev,dev); - //inode - tmp->inode=atoi(inode); - //pathname - strcpy(tmp->pathname,pathname); - tmp->next=NULL; - //attach the node - if(ind==0){ - list_maps=tmp; - list_maps->next=NULL; - current_node=list_maps; - } - current_node->next=tmp; - current_node=tmp; - ind++; - //printf("%s",buf); - } - - //close file - fclose(file); - - - //g_last_head=list_maps; - maps_it->head = list_maps; - maps_it->current = list_maps; - return maps_it; -} - - -procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ - if(p_procmaps_it->current == NULL) - return NULL; - procmaps_struct* p_current = p_procmaps_it->current; - p_procmaps_it->current = p_procmaps_it->current->next; - return p_current; - /* - if(g_current==NULL){ - g_current=g_last_head; - }else - g_current=g_current->next; - - return g_current; - */ -} - - - -void pmparser_free(procmaps_iterator* p_procmaps_it){ - procmaps_struct* maps_list = p_procmaps_it->head; - if(maps_list==NULL) return ; - procmaps_struct* act=maps_list; - procmaps_struct* nxt=act->next; - while(act!=NULL){ - free(act); - act=nxt; - if(nxt!=NULL) - nxt=nxt->next; - } - -} - - -void _pmparser_split_line( - char*buf,char*addr1,char*addr2, - char*perm,char* offset,char* device,char*inode, - char* pathname){ - // - int orig=0; - int i=0; - //addr1 - while(buf[i]!='-'){ - addr1[i-orig]=buf[i]; - i++; - } - addr1[i]='\0'; - i++; - //addr2 - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - addr2[i-orig]=buf[i]; - i++; - } - addr2[i-orig]='\0'; - - //perm - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - perm[i-orig]=buf[i]; - i++; - } - perm[i-orig]='\0'; - //offset - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - offset[i-orig]=buf[i]; - i++; - } - offset[i-orig]='\0'; - //dev - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - device[i-orig]=buf[i]; - i++; - } - device[i-orig]='\0'; - //inode - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - inode[i-orig]=buf[i]; - i++; - } - inode[i-orig]='\0'; - //pathname - pathname[0]='\0'; - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){ - pathname[i-orig]=buf[i]; - i++; - } - pathname[i-orig]='\0'; - -} - -void pmparser_print(procmaps_struct* map, int order){ - - procmaps_struct* tmp=map; - int id=0; - if(order<0) order=-1; - while(tmp!=NULL){ - //(unsigned long) tmp->addr_start; - if(order==id || order==-1){ - printf("Backed by:\t%s\n",strlen(tmp->pathname)==0?"[anonym*]":tmp->pathname); - printf("Range:\t\t%p-%p\n",tmp->addr_start,tmp->addr_end); - printf("Length:\t\t%ld\n",tmp->length); - printf("Offset:\t\t%ld\n",tmp->offset); - printf("Permissions:\t%s\n",tmp->perm); - printf("Inode:\t\t%d\n",tmp->inode); - printf("Device:\t\t%s\n",tmp->dev); - } - if(order!=-1 && id>order) - tmp=NULL; - else if(order==-1){ - printf("#################################\n"); - tmp=tmp->next; - }else tmp=tmp->next; - - id++; - } -} diff --git a/app/src/main/cpp/pmparser.h b/app/src/main/cpp/pmparser.h deleted file mode 100644 index 1162470..0000000 --- a/app/src/main/cpp/pmparser.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - @Author : ouadimjamal@gmail.com - @date : December 2015 - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. No representations are made about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - - */ - -#ifndef H_PMPARSER -#define H_PMPARSER -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//maximum line length in a procmaps file -#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) -/** - * procmaps_struct - * @desc hold all the information about an area in the process's VM - */ -typedef struct procmaps_struct{ - void* addr_start; //< start address of the area - void* addr_end; //< end address - unsigned long length; //< size of the range - - char perm[5]; //< permissions rwxp - short is_r; //< rewrote of perm with short flags - short is_w; - short is_x; - short is_p; - - long offset; //< offset - char dev[12]; //< dev major:minor - int inode; //< inode of the file that backs the area - - char pathname[600]; //< the path of the file that backs the area - //chained list - struct procmaps_struct* next; //"); - - 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", "getNativeSpecializeBlastulaSignature: " + NativeHelper.getNativeSpecializeBlastulaSignature()); - Log.i("RiruManager", "getNativeForkSystemServerSignature: " + NativeHelper.getNativeForkSystemServerSignature()); - } -} diff --git a/app/src/main/java/moe/riru/manager/app/BaseActivity.java b/app/src/main/java/moe/riru/manager/app/BaseActivity.java deleted file mode 100644 index 3494493..0000000 --- a/app/src/main/java/moe/riru/manager/app/BaseActivity.java +++ /dev/null @@ -1,6 +0,0 @@ -package moe.riru.manager.app; - -import android.app.Activity; - -public abstract class BaseActivity extends Activity { -} diff --git a/app/src/main/java/moe/riru/manager/utils/BuildUtils.java b/app/src/main/java/moe/riru/manager/utils/BuildUtils.java deleted file mode 100644 index 05b4f8a..0000000 --- a/app/src/main/java/moe/riru/manager/utils/BuildUtils.java +++ /dev/null @@ -1,10 +0,0 @@ -package moe.riru.manager.utils; - -import android.os.Build; - -public class BuildUtils { - - public static boolean isQ() { - return "Q".equals(Build.VERSION.RELEASE) || Build.VERSION.SDK_INT >= 29; - } -} diff --git a/app/src/main/java/moe/riru/manager/utils/NativeHelper.java b/app/src/main/java/moe/riru/manager/utils/NativeHelper.java deleted file mode 100644 index 4d054f5..0000000 --- a/app/src/main/java/moe/riru/manager/utils/NativeHelper.java +++ /dev/null @@ -1,47 +0,0 @@ -package moe.riru.manager.utils; - -import android.content.Context; - -import androidx.annotation.Keep; -import moe.riru.manager.R; - -@Keep -public class NativeHelper { - - private static final int MAX_VERSION = 19; - private static final int V18 = 19; - private static final int V17_1 = 18; - - static { - System.loadLibrary("helper"); - } - - public static String versionName(Context context, int versionCode) { - if (versionCode > MAX_VERSION) { - return context.getString(R.string.riru_unknown_version, versionCode); - } - - if (versionCode <= 0) { - return context.getString(R.string.riru_not_found); - } - - switch (versionCode) { - case V18: - return "v18"; - case V17_1: - return "v17.1"; - default: - return "v" + versionCode; - } - } - - public static native boolean init(); - public static native boolean isRiruModuleExists(String name); - public static native int getRiruVersion(); - public static native boolean isZygoteMethodsReplaced(); - public static native int getNativeForkAndSpecializeCallsCount(); - public static native int getNativeForkSystemServerCallsCount(); - public static native String getNativeForkAndSpecializeSignature(); - public static native String getNativeSpecializeBlastulaSignature(); - public static native String getNativeForkSystemServerSignature(); -} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb29..0000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cf..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cf..0000000 --- a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 898f3ed..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index dffca36..0000000 Binary files a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 64ba76f..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index dae5e08..0000000 Binary files a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index e5ed465..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index 14ed0af..0000000 Binary files a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index b0907ca..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index d8ae031..0000000 Binary files a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 2c18de9..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index beed3cd..0000000 Binary files a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml deleted file mode 100644 index e0357ab..0000000 --- a/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/app/src/test/java/moe/riru/manager/ExampleUnitTest.java b/app/src/test/java/moe/riru/manager/ExampleUnitTest.java deleted file mode 100644 index d412db0..0000000 --- a/app/src/test/java/moe/riru/manager/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package moe.riru.manager; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/build.gradle b/build.gradle old mode 100644 new mode 100755 index 2a3d2fa..7cea681 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,18 @@ -// Top-level build file where you can add configuration options common to all sub-projects/modules. +apply plugin: 'idea' -buildscript { - ext.kotlin_version = '1.3.21' +idea.module { + excludeDirs += file('out') + resourceDirs += file('template') + resourceDirs += file('scripts') +} +buildscript { repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.3.2' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - - // NOTE: Do not place your application dependencies here; they belong - // in the individual module build.gradle files + classpath 'com.android.tools.build:gradle:3.5.3' } } @@ -20,7 +20,6 @@ allprojects { repositories { google() jcenter() - maven { url 'https://dl.bintray.com/rikkaw/Libraries' } } } @@ -30,5 +29,5 @@ task clean(type: Delete) { ext { minSdkVersion = 23 - targetSdkVersion = 28 -} \ No newline at end of file + targetSdkVersion = 29 +} diff --git a/build.sh b/build.sh deleted file mode 100644 index a07598a..0000000 --- a/build.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -MODULE_NAME=$1 -shift -if [ "$MODULE_NAME" == "" ]; then - echo "Usage: sh build.sh []" - exit 1 -fi - -if [ ! -d "$MODULE_NAME" ]; then - echo "$MODULE_NAME not exists" - exit 1 -fi - -VERSION=$1 -shift -[[ "$VERSION" == "" ]] && VERSION=v1 - -LIBS_OUTPUT=$MODULE_NAME/build/ndkBuild/libs -NDK_OUT=$MODULE_NAME/build/ndkBuild/obj - -# build -NDK_BUILD=ndk-build -[[ "$OSTYPE" == "msys" ]] && NDK_BUILD=ndk-build.cmd -[[ "$OSTYPE" == "cygwin" ]] && NDK_BUILD=ndk-build.cmd - -$NDK_BUILD -C $MODULE_NAME NDK_LIBS_OUT=build/ndkBuild/libs NDK_OUT=build/ndkBuild/obj $@ - -# create tmp dir -TMP_DIR=build/zip -TMP_DIR_MAGISK=$TMP_DIR/magisk - -rm -rf $TMP_DIR -mkdir -p $TMP_DIR - -cp -a template/magisk/. $TMP_DIR_MAGISK - -# copy files -mkdir -p $TMP_DIR_MAGISK/system/lib64 -mkdir -p $TMP_DIR_MAGISK/system/lib -mkdir -p $TMP_DIR_MAGISK/system_x86/lib64 -mkdir -p $TMP_DIR_MAGISK/system_x86/lib -cp -a $LIBS_OUTPUT/arm64-v8a/. $TMP_DIR_MAGISK/system/lib64 -cp -a $LIBS_OUTPUT/armeabi-v7a/. $TMP_DIR_MAGISK/system/lib -[[ -d $LIBS_OUTPUT/x86_64 ]] && cp -a $LIBS_OUTPUT/x86_64/. $TMP_DIR_MAGISK/system_x86/lib64 -[[ -d $LIBS_OUTPUT/x86 ]] && cp -a $LIBS_OUTPUT/x86/. $TMP_DIR_MAGISK/system_x86/lib - -# run custom script -if [ -f $MODULE_NAME/build.sh ]; then - source $MODULE_NAME/build.sh - copy_files -fi - -# zip -mkdir -p release -ZIP_NAME=magisk-$MODULE_NAME-"$VERSION".zip -rm -f release/$ZIP_NAME -rm -f $TMP_DIR_MAGISK/$ZIP_NAME -(cd $TMP_DIR_MAGISK; zip -r $ZIP_NAME * > /dev/null) -mv $TMP_DIR_MAGISK/$ZIP_NAME release/$ZIP_NAME - -# clean tmp dir -rm -rf $TMP_DIR diff --git a/gradle.properties b/gradle.properties old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar old mode 100644 new mode 100755 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties old mode 100644 new mode 100755 index 1b7ea6b..30b572c --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Thu Feb 14 15:40:39 CST 2019 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.0.1-all.zip diff --git a/gradlew.bat b/gradlew.bat old mode 100644 new mode 100755 diff --git a/riru-core/.gitignore b/module/.gitignore old mode 100644 new mode 100755 similarity index 100% rename from riru-core/.gitignore rename to module/.gitignore diff --git a/module/build.gradle b/module/build.gradle new file mode 100755 index 0000000..c44eca4 --- /dev/null +++ b/module/build.gradle @@ -0,0 +1,123 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion rootProject.ext.targetSdkVersion + defaultConfig { + minSdkVersion rootProject.ext.minSdkVersion + targetSdkVersion rootProject.ext.targetSdkVersion + ndk { + abiFilters "armeabi-v7a", 'arm64-v8a', 'x86', 'x86_64' + } + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.9.1" + } + } +} + +def moduleId = "module_xfingerprint_pay_taobao" +def moduleProp = [ + name : "指纹支付 - 淘宝", + version : "v3.9.6", + versionCode: "1", + author : "Jason Eric", + description: "让淘宝支持指纹支付 Fingerprint pay for Taobao.", + api : 4 +] + +def magiskModuleProp = [ + id : "riru-${moduleId.replace('_', '-')}", + name : "Riru - ${moduleProp['name']}", + version : moduleProp['version'], + versionCode: moduleProp['versionCode'], + author : moduleProp['author'], + description: moduleProp['description'] +] + +def outDir = file("$rootDir/out") +def magiskDir = file("$outDir/magisk_module") +def zipName = "magisk-${magiskModuleProp['id']}-${magiskModuleProp['version']}.zip" +def riruDir = "$magiskDir/data/misc/riru/modules/${moduleId}" + +import java.nio.file.Files +import java.security.MessageDigest + +static def calcSha256(file) { + def md = MessageDigest.getInstance("SHA-256") + file.eachByte 4096, { bytes, size -> + md.update(bytes, 0, size); + } + return md.digest().encodeHex() +} + +static def renameOrFail(File from, File to) { + if (!from.renameTo(to)) { + throw new IOException("Unable reanme file $from to $to") + } +} + +android.libraryVariants.all { variant -> + def task = variant.assembleProvider.get() + task.doLast { + // clear + delete { delete magiskDir } + + // copy from template + copy { + from "$rootDir/template/magisk_module" + into magiskDir.path + } + // copy .git files manually since gradle exclude it by default + Files.copy(file("$rootDir/template/magisk_module/.gitattributes").toPath(), file("${magiskDir.path}/.gitattributes").toPath()) + + // generate module.prop + def modulePropText = "" + magiskModuleProp.each { k, v -> modulePropText += "$k=$v\n" } + modulePropText = modulePropText.trim() + file("$magiskDir/module.prop").text = modulePropText + + // generate module.prop for Riru + def riruModulePropText = "" + moduleProp.each { k, v -> riruModulePropText += "$k=$v\n" } + riruModulePropText = riruModulePropText.trim() + file(riruDir).mkdirs() + + // module.prop.new will be renamed to module.prop in post-fs-data.sh + file("$riruDir/module.prop.new").text = riruModulePropText + + // copy native files + def nativeOutDir = file("build/intermediates/cmake/$variant.name/obj") + + file("$magiskDir/system").mkdirs() + file("$magiskDir/system_x86").mkdirs() + renameOrFail(file("$nativeOutDir/arm64-v8a"), file("$magiskDir/system/lib64")) + renameOrFail(file("$nativeOutDir/armeabi-v7a"), file("$magiskDir/system/lib")) + renameOrFail(file("$nativeOutDir/x86_64"), file("$magiskDir/system_x86/lib64")) + renameOrFail(file("$nativeOutDir/x86"), file("$magiskDir/system_x86/lib")) + + file("$magiskDir/system/framework").mkdirs() + copy { + from zipTree('libs/fingerprint-pay-taobao-magisk.apk') + rename('classes.dex', 'libxfingerprint_pay_taobao.dex') + into file("$magiskDir/system/framework") + include 'classes.dex' + } + + // generate sha1sum + fileTree("$magiskDir").matching { + exclude "README.md", "META-INF" + }.visit { f -> + if (f.directory) return + file(f.file.path + ".sha256sum").text = calcSha256(f.file) + } + } + task.finalizedBy zipMagiskMoudle +} + +task zipMagiskMoudle(type: Zip) { + from magiskDir + archiveName zipName + destinationDir outDir +} \ No newline at end of file diff --git a/module/libs/fingerprint-pay-taobao-magisk.apk b/module/libs/fingerprint-pay-taobao-magisk.apk new file mode 100644 index 0000000..91c48ca Binary files /dev/null and b/module/libs/fingerprint-pay-taobao-magisk.apk differ diff --git a/module/src/main/AndroidManifest.xml b/module/src/main/AndroidManifest.xml new file mode 100755 index 0000000..235c657 --- /dev/null +++ b/module/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/module/src/main/cpp/CMakeLists.txt b/module/src/main/cpp/CMakeLists.txt new file mode 100755 index 0000000..8930277 --- /dev/null +++ b/module/src/main/cpp/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.4.1) + +set(MODULE_NAME "riru_module_xfingerprint_pay_taobao") + +message("Build type: ${CMAKE_BUILD_TYPE}") + +set(CMAKE_CXX_STANDARD 11) + +set(LINKER_FLAGS "-ffixed-x18 -Wl,--hash-style=both") +set(C_FLAGS "-Werror=format -fdata-sections -ffunction-sections") + +if (CMAKE_BUILD_TYPE STREQUAL "Release") + set(C_FLAGS "${C_FLAGS} -O2 -fvisibility=hidden -fvisibility-inlines-hidden") + set(LINKER_FLAGS "${LINKER_FLAGS} -Wl,-exclude-libs,ALL -Wl,--gc-sections") +else () + set(C_FLAGS "${C_FLAGS} -O0") +endif () + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${C_FLAGS}") + +set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${LINKER_FLAGS}") +set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${LINKER_FLAGS}") + +add_library(${MODULE_NAME} SHARED main.cpp) +target_link_libraries(${MODULE_NAME} log) +set_target_properties(${MODULE_NAME} PROPERTIES LINK_FLAGS_RELEASE -s) diff --git a/riru-module-xfingerprint-pay-taobao/jni/main/log.h b/module/src/main/cpp/log.h similarity index 100% rename from riru-module-xfingerprint-pay-taobao/jni/main/log.h rename to module/src/main/cpp/log.h diff --git a/riru-module-xfingerprint-pay-taobao/jni/main/main.cpp b/module/src/main/cpp/main.cpp old mode 100644 new mode 100755 similarity index 63% rename from riru-module-xfingerprint-pay-taobao/jni/main/main.cpp rename to module/src/main/cpp/main.cpp index a6977aa..cb05473 --- a/riru-module-xfingerprint-pay-taobao/jni/main/main.cpp +++ b/module/src/main/cpp/main.cpp @@ -1,8 +1,8 @@ #include #include +#include #include #include -#include #include "log.h" @@ -90,43 +90,49 @@ static void loadDex(JNIEnv *env, jstring jdexPath, jstring jodexPath, jstring jc env->CallStaticVoidMethod(javaClientClass, targetMethod, jarg1); } + +// You can remove functions you don't need + extern "C" { -__attribute__((visibility("default"))) -void nativeForkAndSpecializePre( - JNIEnv *env, jclass clazz, jint *_uid, jint *gid, jintArray *gids, jint *, - jobjectArray *rlimits, jint *_mount_external, jstring *se_info, jstring *jse_name, +#define EXPORT __attribute__((visibility("default"))) __attribute__((used)) +EXPORT void nativeForkAndSpecializePre( + JNIEnv *env, jclass clazz, jint *_uid, jint *gid, jintArray *gids, jint *runtimeFlags, + jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName, jintArray *fdsToClose, jintArray *fdsToIgnore, jboolean *is_child_zygote, - jstring *instructionSet, jstring *jappDataDir, jstring *packageName, - jobjectArray *packagesForUID, jobjectArray *visibleVolIDs) { - // packageName, packagesForUID, visibleVolIDs exists from Android Q - char *appDataDir = jstringToC(env, *jappDataDir); - if (appDataDir == NULL) { + jstring *instructionSet, jstring *appDataDir, jstring *packageName, + jobjectArray *packagesForUID, jstring *sandboxId) { + // packageName, packagesForUID, sandboxId are added from Android Q beta 2, removed from beta 5 + char *cAppDataDir = jstringToC(env, *appDataDir); + if (cAppDataDir == NULL) { LOGD("MEM ERR"); return; } - sAppDataDir = strdup(appDataDir); - free(appDataDir); + sAppDataDir = strdup(cAppDataDir); + free(cAppDataDir); if (sAppDataDir == NULL) { LOGD("MEM ERR"); return; } - char *niceName = jstringToC(env, *jse_name); - sHookEnable = equals(niceName, "com.taobao.taobao"); - if (niceName) { - free(niceName); + char *cNiceName = jstringToC(env, *niceName); + sHookEnable = equals(cNiceName, "com.taobao.taobao"); + if (cNiceName) { + free(cNiceName); } } -__attribute__((visibility("default"))) -int nativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) { +EXPORT int nativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) { if (res == 0) { // in app process if (sHookEnable) { char appCacheDir[PATH_MAX] = {0}; snprintf(appCacheDir, PATH_MAX - 1, "%s/cache", sAppDataDir); - loadDex(env, - env->NewStringUTF("/system/framework/libxfingerprint_pay_taobao.dex"), + const char *dexPath = "/data/local/tmp/libxfingerprint_pay_taobao.dex"; + if (access(dexPath, 0) != 0) { + dexPath = "/system/framework/libxfingerprint_pay_taobao.dex"; + } + loadDex(env, + env->NewStringUTF(dexPath), env->NewStringUTF(appCacheDir), env->NewStringUTF("com.yyxx.wechatfp.xposed.plugin.XposedTaobaoPlugin"), "main", @@ -140,15 +146,29 @@ int nativeForkAndSpecializePost(JNIEnv *env, jclass clazz, jint res) { return 0; } -__attribute__((visibility("default"))) -void nativeForkSystemServerPre( - JNIEnv *env, jclass clazz, uid_t *uid, gid_t *gid, jintArray *gids, jint *debug_flags, +EXPORT __attribute__((visibility("default"))) void specializeAppProcessPre( + JNIEnv *env, jclass clazz, jint *_uid, jint *gid, jintArray *gids, jint *runtimeFlags, + jobjectArray *rlimits, jint *mountExternal, jstring *seInfo, jstring *niceName, + jboolean *startChildZygote, jstring *instructionSet, jstring *appDataDir, + jstring *packageName, jobjectArray *packagesForUID, jstring *sandboxId) { + // this is added from Android Q beta, but seems Google disabled this in following updates + + // packageName, packagesForUID, sandboxId are added from Android Q beta 2, removed from beta 5 +} + +EXPORT __attribute__((visibility("default"))) int specializeAppProcessPost( + JNIEnv *env, jclass clazz) { + // this is added from Android Q beta, but seems Google disabled this in following updates + return 0; +} + +EXPORT void nativeForkSystemServerPre( + JNIEnv *env, jclass clazz, uid_t *uid, gid_t *gid, jintArray *gids, jint *runtimeFlags, jobjectArray *rlimits, jlong *permittedCapabilities, jlong *effectiveCapabilities) { } -__attribute__((visibility("default"))) -int nativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) { +EXPORT int nativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) { if (res == 0) { // in system server process } else { @@ -157,4 +177,14 @@ int nativeForkSystemServerPost(JNIEnv *env, jclass clazz, jint res) { } return 0; } + +EXPORT int shouldSkipUid(int uid) { + // by default, Riru only call module functions in "normal app processes" (10000 <= uid % 100000 <= 19999) + // false = don't skip + return false; +} + +EXPORT void onModuleLoaded() { + // called when the shared library of Riru core is loaded } +} \ No newline at end of file diff --git a/riru-core/build.gradle b/riru-core/build.gradle deleted file mode 100644 index 0626b5f..0000000 --- a/riru-core/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion rootProject.ext.targetSdkVersion - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - - externalNativeBuild { - ndkBuild { - abiFilters 'arm64-v8a', 'armeabi-v7a' - arguments "NDK_PROJECT_PATH=jni/" - } - } - } - externalNativeBuild { - ndkBuild { - path 'jni/Android.mk' - } - } -} - -task zip(type: Exec) { - workingDir '..' - commandLine 'sh', 'build.sh', project.name, 'v18' -} \ No newline at end of file diff --git a/riru-core/build.sh b/riru-core/build.sh deleted file mode 100644 index 9da4118..0000000 --- a/riru-core/build.sh +++ /dev/null @@ -1,12 +0,0 @@ -function copy_files { - cp $MODULE_NAME/template_override/config.sh $TMP_DIR_MAGISK - cp $MODULE_NAME/template_override/module.prop $TMP_DIR_MAGISK - - mkdir -p $TMP_DIR_MAGISK/common - cp $MODULE_NAME/template_override/post-fs-data.sh $TMP_DIR_MAGISK/common/post-fs-data.sh - - mv $TMP_DIR_MAGISK/system/lib/zygote_restart $TMP_DIR_MAGISK/zygote_restart_arm - mv $TMP_DIR_MAGISK/system/lib64/zygote_restart $TMP_DIR_MAGISK/zygote_restart_arm64 - mv $TMP_DIR_MAGISK/system_x86/lib/zygote_restart $TMP_DIR_MAGISK/zygote_restart_x86 - mv $TMP_DIR_MAGISK/system_x86/lib64/zygote_restart $TMP_DIR_MAGISK/zygote_restart_x64 -} \ No newline at end of file diff --git a/riru-core/jni/.gitattributes b/riru-core/jni/.gitattributes deleted file mode 100644 index 63f9e34..0000000 --- a/riru-core/jni/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -libs/** binary diff --git a/riru-core/jni/Android.mk b/riru-core/jni/Android.mk deleted file mode 100644 index 16d6dcf..0000000 --- a/riru-core/jni/Android.mk +++ /dev/null @@ -1,3 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(call all-makefiles-under, $(LOCAL_PATH)) \ No newline at end of file diff --git a/riru-core/jni/Application.mk b/riru-core/jni/Application.mk deleted file mode 100644 index 8d914af..0000000 --- a/riru-core/jni/Application.mk +++ /dev/null @@ -1,21 +0,0 @@ -APP_ABI := arm64-v8a armeabi-v7a x86 x86_64 -APP_PLATFORM := android-23 -APP_CFLAGS := -std=gnu99 -APP_CPPFLAGS := -std=c++11 -APP_STL := c++_static -APP_SHORT_COMMANDS := true - -SCS_FLAGS := -ffixed-x18 -APP_LDFLAGS += $(SCS_FLAGS) -APP_CFLAGS += $(SCS_FLAGS) -APP_CPPFLAGS += $(SCS_FLAGS) - -ifeq ($(NDK_DEBUG),1) -$(info building DEBUG version...) -APP_CFLAGS += -O0 -APP_CPPFLAGS += -O0 -else -$(info building RELEASE version...) -APP_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -O2 -APP_CPPFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -O2 -endif \ No newline at end of file diff --git a/riru-core/jni/external/Android.mk b/riru-core/jni/external/Android.mk deleted file mode 100644 index 04d3e48..0000000 --- a/riru-core/jni/external/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_MODULE := xhook -LOCAL_SRC_FILES := xhook/xhook.c \ - xhook/xh_core.c \ - xhook/xh_elf.c \ - xhook/xh_jni.c \ - xhook/xh_log.c \ - xhook/xh_util.c \ - xhook/xh_version.c -LOCAL_C_INCLUDES := $(LOCAL_PATH) -LOCAL_CFLAGS := -Wall -Wextra -Werror -fvisibility=hidden -LOCAL_CONLYFLAGS := -std=c11 -include $(BUILD_STATIC_LIBRARY) \ No newline at end of file diff --git a/riru-core/jni/external/include/xhook/xhook.h b/riru-core/jni/external/include/xhook/xhook.h deleted file mode 100644 index 93dd5b4..0000000 --- a/riru-core/jni/external/include/xhook/xhook.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XHOOK_H -#define XHOOK_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#define XHOOK_EXPORT __attribute__((visibility("default"))) - -int xhook_register(const char *pathname_regex_str, const char *symbol, - void *new_func, void **old_func) XHOOK_EXPORT; - -int xhook_ignore(const char *pathname_regex_str, const char *symbol) XHOOK_EXPORT; - -int xhook_refresh(int async) XHOOK_EXPORT; - -void xhook_clear() XHOOK_EXPORT; - -void xhook_enable_debug(int flag) XHOOK_EXPORT; - -void xhook_enable_sigsegv_protection(int flag) XHOOK_EXPORT; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/queue.h b/riru-core/jni/external/xhook/queue.h deleted file mode 100644 index c2443be..0000000 --- a/riru-core/jni/external/xhook/queue.h +++ /dev/null @@ -1,554 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: stable/9/sys/sys/queue.h 252365 2013-06-29 04:25:40Z lstewart $ - */ - -#ifndef QUEUE_H -#define QUEUE_H - -/* #include */ -#define __containerof(ptr, type, field) ((type *)((char *)(ptr) - ((char *)&((type *)0)->field))) - -/* - * This file defines four types of data structures: singly-linked lists, - * singly-linked tail queues, lists and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may be traversed in either direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * SLIST LIST STAILQ TAILQ - * _HEAD + + + + - * _HEAD_INITIALIZER + + + + - * _ENTRY + + + + - * _INIT + + + + - * _EMPTY + + + + - * _FIRST + + + + - * _NEXT + + + + - * _PREV - + - + - * _LAST - - + + - * _FOREACH + + + + - * _FOREACH_FROM + + + + - * _FOREACH_SAFE + + + + - * _FOREACH_FROM_SAFE + + + + - * _FOREACH_REVERSE - - - + - * _FOREACH_REVERSE_FROM - - - + - * _FOREACH_REVERSE_SAFE - - - + - * _FOREACH_REVERSE_FROM_SAFE - - - + - * _INSERT_HEAD + + + + - * _INSERT_BEFORE - + - + - * _INSERT_AFTER + + + + - * _INSERT_TAIL - - + + - * _CONCAT - - + + - * _REMOVE_AFTER + - + - - * _REMOVE_HEAD + - + - - * _REMOVE + + + + - * _SWAP + + + + - * - */ - -/* - * Singly-linked List declarations. - */ -#define SLIST_HEAD(name, type, qual) \ - struct name { \ - struct type *qual slh_first; /* first element */ \ - } - -#define SLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define SLIST_ENTRY(type, qual) \ - struct { \ - struct type *qual sle_next; /* next element */ \ - } - -/* - * Singly-linked List functions. - */ -#define SLIST_INIT(head) do { \ - SLIST_FIRST((head)) = NULL; \ - } while (0) - -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_FOREACH(var, head, field) \ - for ((var) = SLIST_FIRST((head)); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ - (var); \ - (var) = SLIST_NEXT((var), field)) - -#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = SLIST_FIRST((head)); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ - (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ - SLIST_FIRST((head)) = (elm); \ - } while (0) - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ - SLIST_NEXT((slistelm), field) = (elm); \ - } while (0) - -#define SLIST_REMOVE_AFTER(elm, field) do { \ - SLIST_NEXT(elm, field) = \ - SLIST_NEXT(SLIST_NEXT(elm, field), field); \ - } while (0) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ - } while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if (SLIST_FIRST((head)) == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = SLIST_FIRST((head)); \ - while (SLIST_NEXT(curelm, field) != (elm)) \ - curelm = SLIST_NEXT(curelm, field); \ - SLIST_REMOVE_AFTER(curelm, field); \ - } \ - } while (0) - -#define SLIST_SWAP(head1, head2, type) do { \ - struct type *swap_first = SLIST_FIRST(head1); \ - SLIST_FIRST(head1) = SLIST_FIRST(head2); \ - SLIST_FIRST(head2) = swap_first; \ - } while (0) - -/* - * List declarations. - */ -#define LIST_HEAD(name, type, qual) \ - struct name { \ - struct type *qual lh_first; /* first element */ \ - } - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type, qual) \ - struct { \ - struct type *qual le_next; /* next element */ \ - struct type *qual *le_prev; /* address of previous next element */ \ - } - -/* - * List functions. - */ -#define LIST_INIT(head) do { \ - LIST_FIRST((head)) = NULL; \ - } while (0) - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_PREV(elm, head, type, field) \ - ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ - __containerof((elm)->field.le_prev, struct type, field.le_next)) - -#define LIST_FOREACH(var, head, field) \ - for ((var) = LIST_FIRST((head)); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ - (var); \ - (var) = LIST_NEXT((var), field)) - -#define LIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = LIST_FIRST((head)); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ - (var) && ((tvar) = LIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ - LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field); \ - LIST_FIRST((head)) = (elm); \ - (elm)->field.le_prev = &LIST_FIRST((head)); \ - } while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - LIST_NEXT((elm), field) = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ - } while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL) \ - LIST_NEXT((listelm), field)->field.le_prev = \ - &LIST_NEXT((elm), field); \ - LIST_NEXT((listelm), field) = (elm); \ - (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ - } while (0) - -#define LIST_REMOVE(elm, field) do { \ - if (LIST_NEXT((elm), field) != NULL) \ - LIST_NEXT((elm), field)->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = LIST_NEXT((elm), field); \ - } while (0) - -#define LIST_SWAP(head1, head2, type, field) do { \ - struct type *swap_tmp = LIST_FIRST((head1)); \ - LIST_FIRST((head1)) = LIST_FIRST((head2)); \ - LIST_FIRST((head2)) = swap_tmp; \ - if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ - if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ - swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ - } while (0) - -/* - * Singly-linked Tail queue declarations. - */ -#define STAILQ_HEAD(name, type, qual) \ - struct name { \ - struct type *qual stqh_first;/* first element */ \ - struct type *qual *stqh_last;/* addr of last next element */ \ - } - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type, qual) \ - struct { \ - struct type *qual stqe_next; /* next element */ \ - } - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_INIT(head) do { \ - STAILQ_FIRST((head)) = NULL; \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ - } while (0) - -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_FIRST(head) ((head)->stqh_first) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_LAST(head, type, field) \ - (STAILQ_EMPTY((head)) ? NULL : \ - __containerof((head)->stqh_last, struct type, field.stqe_next)) - -#define STAILQ_FOREACH(var, head, field) \ - for((var) = STAILQ_FIRST((head)); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ - (var); \ - (var) = STAILQ_NEXT((var), field)) - -#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = STAILQ_FIRST((head)); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ - (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_FIRST((head)) = (elm); \ - } while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - STAILQ_NEXT((tqelm), field) = (elm); \ - } while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - STAILQ_NEXT((elm), field) = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - } while (0) - -#define STAILQ_CONCAT(head1, head2) do { \ - if (!STAILQ_EMPTY((head2))) { \ - *(head1)->stqh_last = (head2)->stqh_first; \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_INIT((head2)); \ - } \ - } while (0) - -#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ - if ((STAILQ_NEXT(elm, field) = \ - STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ - (head)->stqh_last = &STAILQ_NEXT((elm), field); \ - } while (0) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if ((STAILQ_FIRST((head)) = \ - STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ - (head)->stqh_last = &STAILQ_FIRST((head)); \ - } while (0) - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if (STAILQ_FIRST((head)) == (elm)) { \ - STAILQ_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = STAILQ_FIRST((head)); \ - while (STAILQ_NEXT(curelm, field) != (elm)) \ - curelm = STAILQ_NEXT(curelm, field); \ - STAILQ_REMOVE_AFTER(head, curelm, field); \ - } \ - } while (0) - -#define STAILQ_SWAP(head1, head2, type) do { \ - struct type *swap_first = STAILQ_FIRST(head1); \ - struct type **swap_last = (head1)->stqh_last; \ - STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ - (head1)->stqh_last = (head2)->stqh_last; \ - STAILQ_FIRST(head2) = swap_first; \ - (head2)->stqh_last = swap_last; \ - if (STAILQ_EMPTY(head1)) \ - (head1)->stqh_last = &STAILQ_FIRST(head1); \ - if (STAILQ_EMPTY(head2)) \ - (head2)->stqh_last = &STAILQ_FIRST(head2); \ - } while (0) - -/* - * Tail queue declarations. - */ -#define TAILQ_HEAD(name, type, qual) \ - struct name { \ - struct type *qual tqh_first; /* first element */ \ - struct type *qual *tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type, qual) \ - struct { \ - struct type *qual tqe_next; /* next element */ \ - struct type *qual *tqe_prev; /* address of previous next element */ \ - } - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) do { \ - TAILQ_FIRST((head)) = NULL; \ - (head)->tqh_last = &TAILQ_FIRST((head)); \ - } while (0) - -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_FOREACH(var, head, field) \ - for ((var) = TAILQ_FIRST((head)); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_FROM(var, head, field) \ - for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ - (var); \ - (var) = TAILQ_NEXT((var), field)) - -#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = TAILQ_FIRST((head)); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ - for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ - (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ - for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ - (var); \ - (var) = TAILQ_PREV((var), headname, field)) - -#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ - for ((var) = TAILQ_LAST((head), headname); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ - for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ - (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ - (var) = (tvar)) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ - TAILQ_FIRST((head))->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_FIRST((head)) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ - } while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - TAILQ_NEXT((elm), field) = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ - } while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - &TAILQ_NEXT((elm), field); \ - else \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - TAILQ_NEXT((listelm), field) = (elm); \ - (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ - } while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - TAILQ_NEXT((elm), field) = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &TAILQ_NEXT((elm), field); \ - } while (0) - -#define TAILQ_CONCAT(head1, head2, field) do { \ - if (!TAILQ_EMPTY(head2)) { \ - *(head1)->tqh_last = (head2)->tqh_first; \ - (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ - (head1)->tqh_last = (head2)->tqh_last; \ - TAILQ_INIT((head2)); \ - } \ - } while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - } while (0) - -#define TAILQ_SWAP(head1, head2, type, field) do { \ - struct type *swap_first = (head1)->tqh_first; \ - struct type **swap_last = (head1)->tqh_last; \ - (head1)->tqh_first = (head2)->tqh_first; \ - (head1)->tqh_last = (head2)->tqh_last; \ - (head2)->tqh_first = swap_first; \ - (head2)->tqh_last = swap_last; \ - if ((swap_first = (head1)->tqh_first) != NULL) \ - swap_first->field.tqe_prev = &(head1)->tqh_first; \ - else \ - (head1)->tqh_last = &(head1)->tqh_first; \ - if ((swap_first = (head2)->tqh_first) != NULL) \ - swap_first->field.tqe_prev = &(head2)->tqh_first; \ - else \ - (head2)->tqh_last = &(head2)->tqh_first; \ - } while (0) - -#endif diff --git a/riru-core/jni/external/xhook/tree.h b/riru-core/jni/external/xhook/tree.h deleted file mode 100644 index dc938ae..0000000 --- a/riru-core/jni/external/xhook/tree.h +++ /dev/null @@ -1,768 +0,0 @@ -/* $NetBSD: tree.h,v 1.8 2004/03/28 19:38:30 provos Exp $ */ -/* $OpenBSD: tree.h,v 1.7 2002/10/17 21:51:54 art Exp $ */ -/* $FreeBSD: stable/9/sys/sys/tree.h 189204 2009-03-01 04:57:23Z bms $ */ - -/*- - * Copyright 2002 Niels Provos - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TREE_H -#define TREE_H - -/* #include */ -#ifndef __unused -#define __unused __attribute__((__unused__)) -#endif - -/* - * This file defines data structures for different types of trees: - * splay trees and red-black trees. - * - * A splay tree is a self-organizing data structure. Every operation - * on the tree causes a splay to happen. The splay moves the requested - * node to the root of the tree and partly rebalances it. - * - * This has the benefit that request locality causes faster lookups as - * the requested nodes move to the top of the tree. On the other hand, - * every lookup causes memory writes. - * - * The Balance Theorem bounds the total access time for m operations - * and n inserts on an initially empty tree as O((m + n)lg n). The - * amortized cost for a sequence of m accesses to a splay tree is O(lg n); - * - * A red-black tree is a binary search tree with the node color as an - * extra attribute. It fulfills a set of conditions: - * - every search path from the root to a leaf consists of the - * same number of black nodes, - * - each red node (except for the root) has a black parent, - * - each leaf node is black. - * - * Every operation on a red-black tree is bounded as O(lg n). - * The maximum height of a red-black tree is 2lg (n+1). - */ - -#define SPLAY_HEAD(name, type) \ -struct name { \ - struct type *sph_root; /* root of the tree */ \ -} - -#define SPLAY_INITIALIZER(root) \ - { NULL } - -#define SPLAY_INIT(root) do { \ - (root)->sph_root = NULL; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ENTRY(type) \ -struct { \ - struct type *spe_left; /* left element */ \ - struct type *spe_right; /* right element */ \ -} - -#define SPLAY_LEFT(elm, field) (elm)->field.spe_left -#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right -#define SPLAY_ROOT(head) (head)->sph_root -#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL) - -/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */ -#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - (head)->sph_root = tmp; \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKLEFT(head, tmp, field) do { \ - SPLAY_LEFT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_LINKRIGHT(head, tmp, field) do { \ - SPLAY_RIGHT(tmp, field) = (head)->sph_root; \ - tmp = (head)->sph_root; \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \ -} while (/*CONSTCOND*/ 0) - -#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \ - SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \ - SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \ - SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \ -} while (/*CONSTCOND*/ 0) - -/* Generates prototypes and inline functions */ - -#define SPLAY_PROTOTYPE(name, type, field, cmp) \ -void name##_SPLAY(struct name *, struct type *); \ -void name##_SPLAY_MINMAX(struct name *, int); \ -struct type *name##_SPLAY_INSERT(struct name *, struct type *); \ -struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \ - \ -/* Finds the node with the same key as elm */ \ -static __inline struct type * \ -name##_SPLAY_FIND(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) \ - return(NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) \ - return (head->sph_root); \ - return (NULL); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_NEXT(struct name *head, struct type *elm) \ -{ \ - name##_SPLAY(head, elm); \ - if (SPLAY_RIGHT(elm, field) != NULL) { \ - elm = SPLAY_RIGHT(elm, field); \ - while (SPLAY_LEFT(elm, field) != NULL) { \ - elm = SPLAY_LEFT(elm, field); \ - } \ - } else \ - elm = NULL; \ - return (elm); \ -} \ - \ -static __inline struct type * \ -name##_SPLAY_MIN_MAX(struct name *head, int val) \ -{ \ - name##_SPLAY_MINMAX(head, val); \ - return (SPLAY_ROOT(head)); \ -} - -/* Main splay operation. - * Moves node close to the key of elm to top - */ -#define SPLAY_GENERATE(name, type, field, cmp) \ -struct type * \ -name##_SPLAY_INSERT(struct name *head, struct type *elm) \ -{ \ - if (SPLAY_EMPTY(head)) { \ - SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \ - } else { \ - int __comp; \ - name##_SPLAY(head, elm); \ - __comp = (cmp)(elm, (head)->sph_root); \ - if(__comp < 0) { \ - SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\ - SPLAY_RIGHT(elm, field) = (head)->sph_root; \ - SPLAY_LEFT((head)->sph_root, field) = NULL; \ - } else if (__comp > 0) { \ - SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\ - SPLAY_LEFT(elm, field) = (head)->sph_root; \ - SPLAY_RIGHT((head)->sph_root, field) = NULL; \ - } else \ - return ((head)->sph_root); \ - } \ - (head)->sph_root = (elm); \ - return (NULL); \ -} \ - \ -struct type * \ -name##_SPLAY_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *__tmp; \ - if (SPLAY_EMPTY(head)) \ - return (NULL); \ - name##_SPLAY(head, elm); \ - if ((cmp)(elm, (head)->sph_root) == 0) { \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \ - (head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\ - } else { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - (head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\ - name##_SPLAY(head, elm); \ - SPLAY_RIGHT((head)->sph_root, field) = __tmp; \ - } \ - return (elm); \ - } \ - return (NULL); \ -} \ - \ -void \ -name##_SPLAY(struct name *head, struct type *elm) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ - int __comp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if ((cmp)(elm, __tmp) > 0){ \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} \ - \ -/* Splay with either the minimum or the maximum element \ - * Used to find minimum or maximum element in tree. \ - */ \ -void name##_SPLAY_MINMAX(struct name *head, int __comp) \ -{ \ - struct type __node, *__left, *__right, *__tmp; \ -\ - SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\ - __left = __right = &__node; \ -\ - while (1) { \ - if (__comp < 0) { \ - __tmp = SPLAY_LEFT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp < 0){ \ - SPLAY_ROTATE_RIGHT(head, __tmp, field); \ - if (SPLAY_LEFT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKLEFT(head, __right, field); \ - } else if (__comp > 0) { \ - __tmp = SPLAY_RIGHT((head)->sph_root, field); \ - if (__tmp == NULL) \ - break; \ - if (__comp > 0) { \ - SPLAY_ROTATE_LEFT(head, __tmp, field); \ - if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\ - break; \ - } \ - SPLAY_LINKRIGHT(head, __left, field); \ - } \ - } \ - SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \ -} - -#define SPLAY_NEGINF -1 -#define SPLAY_INF 1 - -#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y) -#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y) -#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y) -#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y) -#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF)) -#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \ - : name##_SPLAY_MIN_MAX(x, SPLAY_INF)) - -#define SPLAY_FOREACH(x, name, head) \ - for ((x) = SPLAY_MIN(name, head); \ - (x) != NULL; \ - (x) = SPLAY_NEXT(name, head, x)) - -/* Macros that define a red-black tree */ -#define RB_HEAD(name, type) \ -struct name { \ - struct type *rbh_root; /* root of the tree */ \ -} - -#define RB_INITIALIZER(root) \ - { NULL } - -#define RB_INIT(root) do { \ - (root)->rbh_root = NULL; \ -} while (/*CONSTCOND*/ 0) - -#define RB_BLACK 0 -#define RB_RED 1 -#define RB_ENTRY(type) \ -struct { \ - struct type *rbe_left; /* left element */ \ - struct type *rbe_right; /* right element */ \ - struct type *rbe_parent; /* parent element */ \ - int rbe_color; /* node color */ \ -} - -#define RB_LEFT(elm, field) (elm)->field.rbe_left -#define RB_RIGHT(elm, field) (elm)->field.rbe_right -#define RB_PARENT(elm, field) (elm)->field.rbe_parent -#define RB_COLOR(elm, field) (elm)->field.rbe_color -#define RB_ROOT(head) (head)->rbh_root -#define RB_EMPTY(head) (RB_ROOT(head) == NULL) - -#define RB_SET(elm, parent, field) do { \ - RB_PARENT(elm, field) = parent; \ - RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \ - RB_COLOR(elm, field) = RB_RED; \ -} while (/*CONSTCOND*/ 0) - -#define RB_SET_BLACKRED(black, red, field) do { \ - RB_COLOR(black, field) = RB_BLACK; \ - RB_COLOR(red, field) = RB_RED; \ -} while (/*CONSTCOND*/ 0) - -#ifndef RB_AUGMENT -#define RB_AUGMENT(x) do {} while (0) -#endif - -#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \ - (tmp) = RB_RIGHT(elm, field); \ - if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \ - RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_LEFT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (/*CONSTCOND*/ 0) - -#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \ - (tmp) = RB_LEFT(elm, field); \ - if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \ - RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \ - } \ - RB_AUGMENT(elm); \ - if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \ - if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \ - RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \ - else \ - RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \ - } else \ - (head)->rbh_root = (tmp); \ - RB_RIGHT(tmp, field) = (elm); \ - RB_PARENT(elm, field) = (tmp); \ - RB_AUGMENT(tmp); \ - if ((RB_PARENT(tmp, field))) \ - RB_AUGMENT(RB_PARENT(tmp, field)); \ -} while (/*CONSTCOND*/ 0) - -/* Generates prototypes and inline functions */ -#define RB_PROTOTYPE(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp,) -#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \ - RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static) -#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \ -attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \ -attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\ -attr struct type *name##_RB_REMOVE(struct name *, struct type *); \ -attr struct type *name##_RB_INSERT(struct name *, struct type *); \ -attr struct type *name##_RB_FIND(struct name *, struct type *); \ -attr struct type *name##_RB_NFIND(struct name *, struct type *); \ -attr struct type *name##_RB_NEXT(struct type *); \ -attr struct type *name##_RB_PREV(struct type *); \ -attr struct type *name##_RB_MINMAX(struct name *, int); \ - \ - -/* Main rb operation. - * Moves node close to the key of elm to top - */ -#define RB_GENERATE(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp,) -#define RB_GENERATE_STATIC(name, type, field, cmp) \ - RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static) -#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \ -attr void \ -name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \ -{ \ - struct type *parent, *gparent, *tmp; \ - while ((parent = RB_PARENT(elm, field)) != NULL && \ - RB_COLOR(parent, field) == RB_RED) { \ - gparent = RB_PARENT(parent, field); \ - if (parent == RB_LEFT(gparent, field)) { \ - tmp = RB_RIGHT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_RIGHT(parent, field) == elm) { \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_RIGHT(head, gparent, tmp, field); \ - } else { \ - tmp = RB_LEFT(gparent, field); \ - if (tmp && RB_COLOR(tmp, field) == RB_RED) { \ - RB_COLOR(tmp, field) = RB_BLACK; \ - RB_SET_BLACKRED(parent, gparent, field);\ - elm = gparent; \ - continue; \ - } \ - if (RB_LEFT(parent, field) == elm) { \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = parent; \ - parent = elm; \ - elm = tmp; \ - } \ - RB_SET_BLACKRED(parent, gparent, field); \ - RB_ROTATE_LEFT(head, gparent, tmp, field); \ - } \ - } \ - RB_COLOR(head->rbh_root, field) = RB_BLACK; \ -} \ - \ -attr void \ -name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \ -{ \ - struct type *tmp; \ - while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \ - elm != RB_ROOT(head)) { \ - if (RB_LEFT(parent, field) == elm) { \ - tmp = RB_RIGHT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\ - struct type *oleft; \ - if ((oleft = RB_LEFT(tmp, field)) \ - != NULL) \ - RB_COLOR(oleft, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_RIGHT(head, tmp, oleft, field);\ - tmp = RB_RIGHT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_RIGHT(tmp, field)) \ - RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_LEFT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } else { \ - tmp = RB_LEFT(parent, field); \ - if (RB_COLOR(tmp, field) == RB_RED) { \ - RB_SET_BLACKRED(tmp, parent, field); \ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - if ((RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\ - (RB_RIGHT(tmp, field) == NULL || \ - RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\ - RB_COLOR(tmp, field) = RB_RED; \ - elm = parent; \ - parent = RB_PARENT(elm, field); \ - } else { \ - if (RB_LEFT(tmp, field) == NULL || \ - RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\ - struct type *oright; \ - if ((oright = RB_RIGHT(tmp, field)) \ - != NULL) \ - RB_COLOR(oright, field) = RB_BLACK;\ - RB_COLOR(tmp, field) = RB_RED; \ - RB_ROTATE_LEFT(head, tmp, oright, field);\ - tmp = RB_LEFT(parent, field); \ - } \ - RB_COLOR(tmp, field) = RB_COLOR(parent, field);\ - RB_COLOR(parent, field) = RB_BLACK; \ - if (RB_LEFT(tmp, field)) \ - RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\ - RB_ROTATE_RIGHT(head, parent, tmp, field);\ - elm = RB_ROOT(head); \ - break; \ - } \ - } \ - } \ - if (elm) \ - RB_COLOR(elm, field) = RB_BLACK; \ -} \ - \ -attr struct type * \ -name##_RB_REMOVE(struct name *head, struct type *elm) \ -{ \ - struct type *child, *parent, *old = elm; \ - int color; \ - if (RB_LEFT(elm, field) == NULL) \ - child = RB_RIGHT(elm, field); \ - else if (RB_RIGHT(elm, field) == NULL) \ - child = RB_LEFT(elm, field); \ - else { \ - struct type *left; \ - elm = RB_RIGHT(elm, field); \ - while ((left = RB_LEFT(elm, field)) != NULL) \ - elm = left; \ - child = RB_RIGHT(elm, field); \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ - if (RB_PARENT(elm, field) == old) \ - parent = elm; \ - (elm)->field = (old)->field; \ - if (RB_PARENT(old, field)) { \ - if (RB_LEFT(RB_PARENT(old, field), field) == old)\ - RB_LEFT(RB_PARENT(old, field), field) = elm;\ - else \ - RB_RIGHT(RB_PARENT(old, field), field) = elm;\ - RB_AUGMENT(RB_PARENT(old, field)); \ - } else \ - RB_ROOT(head) = elm; \ - RB_PARENT(RB_LEFT(old, field), field) = elm; \ - if (RB_RIGHT(old, field)) \ - RB_PARENT(RB_RIGHT(old, field), field) = elm; \ - if (parent) { \ - left = parent; \ - do { \ - RB_AUGMENT(left); \ - } while ((left = RB_PARENT(left, field)) != NULL); \ - } \ - goto color; \ - } \ - parent = RB_PARENT(elm, field); \ - color = RB_COLOR(elm, field); \ - if (child) \ - RB_PARENT(child, field) = parent; \ - if (parent) { \ - if (RB_LEFT(parent, field) == elm) \ - RB_LEFT(parent, field) = child; \ - else \ - RB_RIGHT(parent, field) = child; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = child; \ -color: \ - if (color == RB_BLACK) \ - name##_RB_REMOVE_COLOR(head, parent, child); \ - return (old); \ -} \ - \ -/* Inserts a node into the RB tree */ \ -attr struct type * \ -name##_RB_INSERT(struct name *head, struct type *elm) \ -{ \ - struct type *tmp; \ - struct type *parent = NULL; \ - int comp = 0; \ - tmp = RB_ROOT(head); \ - while (tmp) { \ - parent = tmp; \ - comp = (cmp)(elm, parent); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - RB_SET(elm, parent, field); \ - if (parent != NULL) { \ - if (comp < 0) \ - RB_LEFT(parent, field) = elm; \ - else \ - RB_RIGHT(parent, field) = elm; \ - RB_AUGMENT(parent); \ - } else \ - RB_ROOT(head) = elm; \ - name##_RB_INSERT_COLOR(head, elm); \ - return (NULL); \ -} \ - \ -/* Finds the node with the same key as elm */ \ -attr struct type * \ -name##_RB_FIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) \ - tmp = RB_LEFT(tmp, field); \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (NULL); \ -} \ - \ -/* Finds the first node greater than or equal to the search key */ \ -attr struct type * \ -name##_RB_NFIND(struct name *head, struct type *elm) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *res = NULL; \ - int comp; \ - while (tmp) { \ - comp = cmp(elm, tmp); \ - if (comp < 0) { \ - res = tmp; \ - tmp = RB_LEFT(tmp, field); \ - } \ - else if (comp > 0) \ - tmp = RB_RIGHT(tmp, field); \ - else \ - return (tmp); \ - } \ - return (res); \ -} \ - \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_NEXT(struct type *elm) \ -{ \ - if (RB_RIGHT(elm, field)) { \ - elm = RB_RIGHT(elm, field); \ - while (RB_LEFT(elm, field)) \ - elm = RB_LEFT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -/* ARGSUSED */ \ -attr struct type * \ -name##_RB_PREV(struct type *elm) \ -{ \ - if (RB_LEFT(elm, field)) { \ - elm = RB_LEFT(elm, field); \ - while (RB_RIGHT(elm, field)) \ - elm = RB_RIGHT(elm, field); \ - } else { \ - if (RB_PARENT(elm, field) && \ - (elm == RB_RIGHT(RB_PARENT(elm, field), field))) \ - elm = RB_PARENT(elm, field); \ - else { \ - while (RB_PARENT(elm, field) && \ - (elm == RB_LEFT(RB_PARENT(elm, field), field)))\ - elm = RB_PARENT(elm, field); \ - elm = RB_PARENT(elm, field); \ - } \ - } \ - return (elm); \ -} \ - \ -attr struct type * \ -name##_RB_MINMAX(struct name *head, int val) \ -{ \ - struct type *tmp = RB_ROOT(head); \ - struct type *parent = NULL; \ - while (tmp) { \ - parent = tmp; \ - if (val < 0) \ - tmp = RB_LEFT(tmp, field); \ - else \ - tmp = RB_RIGHT(tmp, field); \ - } \ - return (parent); \ -} - -#define RB_NEGINF -1 -#define RB_INF 1 - -#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y) -#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y) -#define RB_FIND(name, x, y) name##_RB_FIND(x, y) -#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y) -#define RB_NEXT(name, x, y) name##_RB_NEXT(y) -#define RB_PREV(name, x, y) name##_RB_PREV(y) -#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF) -#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF) - -#define RB_FOREACH(x, name, head) \ - for ((x) = RB_MIN(name, head); \ - (x) != NULL; \ - (x) = name##_RB_NEXT(x)) - -#define RB_FOREACH_FROM(x, name, y) \ - for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_SAFE(x, name, head, y) \ - for ((x) = RB_MIN(name, head); \ - ((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_REVERSE(x, name, head) \ - for ((x) = RB_MAX(name, head); \ - (x) != NULL; \ - (x) = name##_RB_PREV(x)) - -#define RB_FOREACH_REVERSE_FROM(x, name, y) \ - for ((x) = (y); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ - (x) = (y)) - -#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \ - for ((x) = RB_MAX(name, head); \ - ((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \ - (x) = (y)) - -#endif diff --git a/riru-core/jni/external/xhook/xh_core.c b/riru-core/jni/external/xhook/xh_core.c deleted file mode 100644 index 4d14ba4..0000000 --- a/riru-core/jni/external/xhook/xh_core.c +++ /dev/null @@ -1,656 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "queue.h" -#include "tree.h" -#include "xh_errno.h" -#include "xh_log.h" -#include "xh_elf.h" -#include "xh_version.h" -#include "xh_core.h" - -#define XH_CORE_DEBUG 0 - -//registered hook info collection -typedef struct xh_core_hook_info -{ -#if XH_CORE_DEBUG - char *pathname_regex_str; -#endif - regex_t pathname_regex; - char *symbol; - void *new_func; - void **old_func; - TAILQ_ENTRY(xh_core_hook_info,) link; -} xh_core_hook_info_t; -typedef TAILQ_HEAD(xh_core_hook_info_queue, xh_core_hook_info,) xh_core_hook_info_queue_t; - -//ignored hook info collection -typedef struct xh_core_ignore_info -{ -#if XH_CORE_DEBUG - char *pathname_regex_str; -#endif - regex_t pathname_regex; - char *symbol; //NULL meaning for all symbols - TAILQ_ENTRY(xh_core_ignore_info,) link; -} xh_core_ignore_info_t; -typedef TAILQ_HEAD(xh_core_ignore_info_queue, xh_core_ignore_info,) xh_core_ignore_info_queue_t; - -//required info from /proc/self/maps -typedef struct xh_core_map_info -{ - char *pathname; - uintptr_t base_addr; - xh_elf_t elf; - RB_ENTRY(xh_core_map_info) link; -} xh_core_map_info_t; -static __inline__ int xh_core_map_info_cmp(xh_core_map_info_t *a, xh_core_map_info_t *b) -{ - return strcmp(a->pathname, b->pathname); -} -typedef RB_HEAD(xh_core_map_info_tree, xh_core_map_info) xh_core_map_info_tree_t; -RB_GENERATE_STATIC(xh_core_map_info_tree, xh_core_map_info, link, xh_core_map_info_cmp) - -//signal handler for SIGSEGV -//for xh_elf_init(), xh_elf_hook(), xh_elf_check_elfheader() -static int xh_core_sigsegv_enable = 1; //enable by default -static struct sigaction xh_core_sigsegv_act_old; -static volatile int xh_core_sigsegv_flag = 0; -static sigjmp_buf xh_core_sigsegv_env; -static void xh_core_sigsegv_handler(int sig) -{ - (void)sig; - - if(xh_core_sigsegv_flag) - siglongjmp(xh_core_sigsegv_env, 1); - else - sigaction(SIGSEGV, &xh_core_sigsegv_act_old, NULL); -} -static int xh_core_add_sigsegv_handler() -{ - struct sigaction act; - - if(!xh_core_sigsegv_enable) return 0; - - if(0 != sigemptyset(&act.sa_mask)) return (0 == errno ? XH_ERRNO_UNKNOWN : errno); - act.sa_handler = xh_core_sigsegv_handler; - - if(0 != sigaction(SIGSEGV, &act, &xh_core_sigsegv_act_old)) - return (0 == errno ? XH_ERRNO_UNKNOWN : errno); - - return 0; -} -static void xh_core_del_sigsegv_handler() -{ - if(!xh_core_sigsegv_enable) return; - - sigaction(SIGSEGV, &xh_core_sigsegv_act_old, NULL); -} - - -static xh_core_hook_info_queue_t xh_core_hook_info = TAILQ_HEAD_INITIALIZER(xh_core_hook_info); -static xh_core_ignore_info_queue_t xh_core_ignore_info = TAILQ_HEAD_INITIALIZER(xh_core_ignore_info); -static xh_core_map_info_tree_t xh_core_map_info = RB_INITIALIZER(&xh_core_map_info); -static pthread_mutex_t xh_core_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_cond_t xh_core_cond = PTHREAD_COND_INITIALIZER; -static volatile int xh_core_inited = 0; -static volatile int xh_core_init_ok = 0; -static volatile int xh_core_async_inited = 0; -static volatile int xh_core_async_init_ok = 0; -static pthread_mutex_t xh_core_refresh_mutex = PTHREAD_MUTEX_INITIALIZER; -static pthread_t xh_core_refresh_thread_tid; -static volatile int xh_core_refresh_thread_running = 0; -static volatile int xh_core_refresh_thread_do = 0; - - -int xh_core_register(const char *pathname_regex_str, const char *symbol, - void *new_func, void **old_func) -{ - xh_core_hook_info_t *hi; - regex_t regex; - - if(NULL == pathname_regex_str || NULL == symbol || NULL == new_func) return XH_ERRNO_INVAL; - - if(xh_core_inited) - { - XH_LOG_ERROR("do not register hook after refresh(): %s, %s", pathname_regex_str, symbol); - return XH_ERRNO_INVAL; - } - - if(0 != regcomp(®ex, pathname_regex_str, REG_NOSUB)) return XH_ERRNO_INVAL; - - if(NULL == (hi = malloc(sizeof(xh_core_hook_info_t)))) return XH_ERRNO_NOMEM; - if(NULL == (hi->symbol = strdup(symbol))) - { - free(hi); - return XH_ERRNO_NOMEM; - } -#if XH_CORE_DEBUG - if(NULL == (hi->pathname_regex_str = strdup(pathname_regex_str))) - { - free(hi->symbol); - free(hi); - return XH_ERRNO_NOMEM; - } -#endif - hi->pathname_regex = regex; - hi->new_func = new_func; - hi->old_func = old_func; - - pthread_mutex_lock(&xh_core_mutex); - TAILQ_INSERT_TAIL(&xh_core_hook_info, hi, link); - pthread_mutex_unlock(&xh_core_mutex); - - return 0; -} - -int xh_core_ignore(const char *pathname_regex_str, const char *symbol) -{ - xh_core_ignore_info_t *ii; - regex_t regex; - - if(NULL == pathname_regex_str) return XH_ERRNO_INVAL; - - if(xh_core_inited) - { - XH_LOG_ERROR("do not ignore hook after refresh(): %s, %s", pathname_regex_str, symbol ? symbol : "ALL"); - return XH_ERRNO_INVAL; - } - - if(0 != regcomp(®ex, pathname_regex_str, REG_NOSUB)) return XH_ERRNO_INVAL; - - if(NULL == (ii = malloc(sizeof(xh_core_ignore_info_t)))) return XH_ERRNO_NOMEM; - if(NULL != symbol) - { - if(NULL == (ii->symbol = strdup(symbol))) - { - free(ii); - return XH_ERRNO_NOMEM; - } - } - else - { - ii->symbol = NULL; //ignore all symbols - } -#if XH_CORE_DEBUG - if(NULL == (ii->pathname_regex_str = strdup(pathname_regex_str))) - { - free(ii->symbol); - free(ii); - return XH_ERRNO_NOMEM; - } -#endif - ii->pathname_regex = regex; - - pthread_mutex_lock(&xh_core_mutex); - TAILQ_INSERT_TAIL(&xh_core_ignore_info, ii, link); - pthread_mutex_unlock(&xh_core_mutex); - - return 0; -} - -static int xh_core_check_elf_header(uintptr_t base_addr, const char *pathname) -{ - if(!xh_core_sigsegv_enable) - { - return xh_elf_check_elfheader(base_addr); - } - else - { - int ret = XH_ERRNO_UNKNOWN; - - xh_core_sigsegv_flag = 1; - if(0 == sigsetjmp(xh_core_sigsegv_env, 1)) - { - ret = xh_elf_check_elfheader(base_addr); - } - else - { - ret = XH_ERRNO_SEGVERR; - XH_LOG_WARN("catch SIGSEGV when check_elfheader: %s", pathname); - } - xh_core_sigsegv_flag = 0; - return ret; - } -} - -static void xh_core_hook_impl(xh_core_map_info_t *mi) -{ - //init - if(0 != xh_elf_init(&(mi->elf), mi->base_addr, mi->pathname)) return; - - //hook - xh_core_hook_info_t *hi; - xh_core_ignore_info_t *ii; - int ignore; - TAILQ_FOREACH(hi, &xh_core_hook_info, link) //find hook info - { - if(0 == regexec(&(hi->pathname_regex), mi->pathname, 0, NULL, 0)) - { - ignore = 0; - TAILQ_FOREACH(ii, &xh_core_ignore_info, link) //find ignore info - { - if(0 == regexec(&(ii->pathname_regex), mi->pathname, 0, NULL, 0)) - { - if(NULL == ii->symbol) //ignore all symbols - return; - - if(0 == strcmp(ii->symbol, hi->symbol)) //ignore the current symbol - { - ignore = 1; - break; - } - } - } - - if(0 == ignore) - xh_elf_hook(&(mi->elf), hi->symbol, hi->new_func, hi->old_func); - } - } -} - -static void xh_core_hook(xh_core_map_info_t *mi) -{ - if(!xh_core_sigsegv_enable) - { - xh_core_hook_impl(mi); - } - else - { - xh_core_sigsegv_flag = 1; - if(0 == sigsetjmp(xh_core_sigsegv_env, 1)) - { - xh_core_hook_impl(mi); - } - else - { - XH_LOG_WARN("catch SIGSEGV when init or hook: %s", mi->pathname); - } - xh_core_sigsegv_flag = 0; - } -} - -static void xh_core_refresh_impl() -{ - char line[512]; - FILE *fp; - uintptr_t base_addr; - char perm[5]; - unsigned long offset; - int pathname_pos; - char *pathname; - size_t pathname_len; - xh_core_map_info_t *mi, *mi_tmp; - xh_core_map_info_t mi_key; - xh_core_hook_info_t *hi; - xh_core_ignore_info_t *ii; - int match; - xh_core_map_info_tree_t map_info_refreshed = RB_INITIALIZER(&map_info_refreshed); - - if(NULL == (fp = fopen("/proc/self/maps", "r"))) - { - XH_LOG_ERROR("fopen /proc/self/maps failed"); - return; - } - - while(fgets(line, sizeof(line), fp)) - { - if(sscanf(line, "%"PRIxPTR"-%*lx %4s %lx %*x:%*x %*d%n", &base_addr, perm, &offset, &pathname_pos) != 3) continue; - - //check permission - if(perm[0] != 'r') continue; - if(perm[3] != 'p') continue; //do not touch the shared memory - - //check offset - // - //We are trying to find ELF header in memory. - //It can only be found at the beginning of a mapped memory regions - //whose offset is 0. - if(0 != offset) continue; - - //get pathname - while(isspace(line[pathname_pos]) && pathname_pos < (int)(sizeof(line) - 1)) - pathname_pos += 1; - if(pathname_pos >= (int)(sizeof(line) - 1)) continue; - pathname = line + pathname_pos; - pathname_len = strlen(pathname); - if(0 == pathname_len) continue; - if(pathname[pathname_len - 1] == '\n') - { - pathname[pathname_len - 1] = '\0'; - pathname_len -= 1; - } - if(0 == pathname_len) continue; - if('[' == pathname[0]) continue; - - //check pathname - //if we need to hook this elf? - match = 0; - TAILQ_FOREACH(hi, &xh_core_hook_info, link) //find hook info - { - if(0 == regexec(&(hi->pathname_regex), pathname, 0, NULL, 0)) - { - TAILQ_FOREACH(ii, &xh_core_ignore_info, link) //find ignore info - { - if(0 == regexec(&(ii->pathname_regex), pathname, 0, NULL, 0)) - { - if(NULL == ii->symbol) - goto check_finished; - - if(0 == strcmp(ii->symbol, hi->symbol)) - goto check_continue; - } - } - - match = 1; - check_continue: - break; - } - } - check_finished: - if(0 == match) continue; - - //check elf header format - //We are trying to do ELF header checking as late as possible. - if(0 != xh_core_check_elf_header(base_addr, pathname)) continue; - - //check existed map item - mi_key.pathname = pathname; - if(NULL != (mi = RB_FIND(xh_core_map_info_tree, &xh_core_map_info, &mi_key))) - { - //exist - RB_REMOVE(xh_core_map_info_tree, &xh_core_map_info, mi); - - //repeated? - //We only keep the first one, that is the real base address - if(NULL != RB_INSERT(xh_core_map_info_tree, &map_info_refreshed, mi)) - { -#if XH_CORE_DEBUG - XH_LOG_DEBUG("repeated map info when update: %s", line); -#endif - free(mi->pathname); - free(mi); - continue; - } - - //re-hook if base_addr changed - if(mi->base_addr != base_addr) - { - mi->base_addr = base_addr; - xh_core_hook(mi); - } - } - else - { - //not exist, create a new map info - if(NULL == (mi = (xh_core_map_info_t *)malloc(sizeof(xh_core_map_info_t)))) continue; - if(NULL == (mi->pathname = strdup(pathname))) - { - free(mi); - continue; - } - mi->base_addr = base_addr; - - //repeated? - //We only keep the first one, that is the real base address - if(NULL != RB_INSERT(xh_core_map_info_tree, &map_info_refreshed, mi)) - { -#if XH_CORE_DEBUG - XH_LOG_DEBUG("repeated map info when create: %s", line); -#endif - free(mi->pathname); - free(mi); - continue; - } - - //hook - xh_core_hook(mi); //hook - } - } - fclose(fp); - - //free all missing map item, maybe dlclosed? - RB_FOREACH_SAFE(mi, xh_core_map_info_tree, &xh_core_map_info, mi_tmp) - { -#if XH_CORE_DEBUG - XH_LOG_DEBUG("remove missing map info: %s", mi->pathname); -#endif - RB_REMOVE(xh_core_map_info_tree, &xh_core_map_info, mi); - if(mi->pathname) free(mi->pathname); - free(mi); - } - - //save the new refreshed map info tree - xh_core_map_info = map_info_refreshed; - - XH_LOG_INFO("map refreshed"); - -#if XH_CORE_DEBUG - RB_FOREACH(mi, xh_core_map_info_tree, &xh_core_map_info) - XH_LOG_DEBUG(" %"PRIxPTR" %s\n", mi->base_addr, mi->pathname); -#endif -} - -static void *xh_core_refresh_thread_func(void *arg) -{ - (void)arg; - - pthread_setname_np(pthread_self(), "xh_refresh_loop"); - - while(xh_core_refresh_thread_running) - { - //waiting for a refresh task or exit - pthread_mutex_lock(&xh_core_mutex); - while(!xh_core_refresh_thread_do && xh_core_refresh_thread_running) - { - pthread_cond_wait(&xh_core_cond, &xh_core_mutex); - } - if(!xh_core_refresh_thread_running) - { - pthread_mutex_unlock(&xh_core_mutex); - break; - } - xh_core_refresh_thread_do = 0; - pthread_mutex_unlock(&xh_core_mutex); - - //refresh - pthread_mutex_lock(&xh_core_refresh_mutex); - xh_core_refresh_impl(); - pthread_mutex_unlock(&xh_core_refresh_mutex); - } - - return NULL; -} - -static void xh_core_init_once() -{ - if(xh_core_inited) return; - - pthread_mutex_lock(&xh_core_mutex); - - if(xh_core_inited) goto end; - - xh_core_inited = 1; - - //dump debug info - XH_LOG_INFO("%s\n", xh_version_str_full()); -#if XH_CORE_DEBUG - xh_core_hook_info_t *hi; - TAILQ_FOREACH(hi, &xh_core_hook_info, link) - XH_LOG_INFO(" hook: %s @ %s, (%p, %p)\n", hi->symbol, hi->pathname_regex_str, - hi->new_func, hi->old_func); - xh_core_ignore_info_t *ii; - TAILQ_FOREACH(ii, &xh_core_ignore_info, link) - XH_LOG_INFO(" ignore: %s @ %s\n", ii->symbol ? ii->symbol : "ALL ", - ii->pathname_regex_str); -#endif - - //register signal handler - if(0 != xh_core_add_sigsegv_handler()) goto end; - - //OK - xh_core_init_ok = 1; - - end: - pthread_mutex_unlock(&xh_core_mutex); -} - -static void xh_core_init_async_once() -{ - if(xh_core_async_inited) return; - - pthread_mutex_lock(&xh_core_mutex); - - if(xh_core_async_inited) goto end; - - xh_core_async_inited = 1; - - //create async refresh thread - xh_core_refresh_thread_running = 1; - if(0 != pthread_create(&xh_core_refresh_thread_tid, NULL, &xh_core_refresh_thread_func, NULL)) - { - xh_core_refresh_thread_running = 0; - goto end; - } - - //OK - xh_core_async_init_ok = 1; - - end: - pthread_mutex_unlock(&xh_core_mutex); -} - -int xh_core_refresh(int async) -{ - //init - xh_core_init_once(); - if(!xh_core_init_ok) return XH_ERRNO_UNKNOWN; - - if(async) - { - //init for async - xh_core_init_async_once(); - if(!xh_core_async_init_ok) return XH_ERRNO_UNKNOWN; - - //refresh async - pthread_mutex_lock(&xh_core_mutex); - xh_core_refresh_thread_do = 1; - pthread_cond_signal(&xh_core_cond); - pthread_mutex_unlock(&xh_core_mutex); - } - else - { - //refresh sync - pthread_mutex_lock(&xh_core_refresh_mutex); - xh_core_refresh_impl(); - pthread_mutex_unlock(&xh_core_refresh_mutex); - } - - return 0; -} - -void xh_core_clear() -{ - //stop the async refresh thread - if(xh_core_async_init_ok) - { - pthread_mutex_lock(&xh_core_mutex); - xh_core_refresh_thread_running = 0; - pthread_cond_signal(&xh_core_cond); - pthread_mutex_unlock(&xh_core_mutex); - - pthread_join(xh_core_refresh_thread_tid, NULL); - xh_core_async_init_ok = 0; - } - xh_core_async_inited = 0; - - //unregister the sig handler - if(xh_core_init_ok) - { - xh_core_del_sigsegv_handler(); - xh_core_init_ok = 0; - } - xh_core_inited = 0; - - pthread_mutex_lock(&xh_core_mutex); - pthread_mutex_lock(&xh_core_refresh_mutex); - - //free all map info - xh_core_map_info_t *mi, *mi_tmp; - RB_FOREACH_SAFE(mi, xh_core_map_info_tree, &xh_core_map_info, mi_tmp) - { - RB_REMOVE(xh_core_map_info_tree, &xh_core_map_info, mi); - if(mi->pathname) free(mi->pathname); - free(mi); - } - - //free all hook info - xh_core_hook_info_t *hi, *hi_tmp; - TAILQ_FOREACH_SAFE(hi, &xh_core_hook_info, link, hi_tmp) - { - TAILQ_REMOVE(&xh_core_hook_info, hi, link); -#if XH_CORE_DEBUG - free(hi->pathname_regex_str); -#endif - regfree(&(hi->pathname_regex)); - free(hi->symbol); - free(hi); - } - - //free all ignore info - xh_core_ignore_info_t *ii, *ii_tmp; - TAILQ_FOREACH_SAFE(ii, &xh_core_ignore_info, link, ii_tmp) - { - TAILQ_REMOVE(&xh_core_ignore_info, ii, link); -#if XH_CORE_DEBUG - free(ii->pathname_regex_str); -#endif - regfree(&(ii->pathname_regex)); - free(ii->symbol); - free(ii); - } - - pthread_mutex_unlock(&xh_core_refresh_mutex); - pthread_mutex_unlock(&xh_core_mutex); -} - -void xh_core_enable_debug(int flag) -{ - xh_log_priority = (flag ? ANDROID_LOG_DEBUG : ANDROID_LOG_WARN); -} - -void xh_core_enable_sigsegv_protection(int flag) -{ - xh_core_sigsegv_enable = (flag ? 1 : 0); -} diff --git a/riru-core/jni/external/xhook/xh_core.h b/riru-core/jni/external/xhook/xh_core.h deleted file mode 100644 index 3508794..0000000 --- a/riru-core/jni/external/xhook/xh_core.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_CORE_H -#define XH_CORE_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -int xh_core_register(const char *pathname_regex_str, const char *symbol, - void *new_func, void **old_func); - -int xh_core_ignore(const char *pathname_regex_str, const char *symbol); - -int xh_core_refresh(int async); - -void xh_core_clear(); - -void xh_core_enable_debug(int flag); - -void xh_core_enable_sigsegv_protection(int flag); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/xh_elf.c b/riru-core/jni/external/xhook/xh_elf.c deleted file mode 100644 index 286ed87..0000000 --- a/riru-core/jni/external/xhook/xh_elf.c +++ /dev/null @@ -1,1042 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "xh_errno.h" -#include "xh_log.h" -#include "xh_util.h" -#include "xh_elf.h" - -#define XH_ELF_DEBUG 0 - -#ifndef EI_ABIVERSION -#define EI_ABIVERSION 8 -#endif - -#if defined(__arm__) -#define XH_ELF_R_GENERIC_JUMP_SLOT R_ARM_JUMP_SLOT //.rel.plt -#define XH_ELF_R_GENERIC_GLOB_DAT R_ARM_GLOB_DAT //.rel.dyn -#define XH_ELF_R_GENERIC_ABS R_ARM_ABS32 //.rel.dyn -#elif defined(__aarch64__) -#define XH_ELF_R_GENERIC_JUMP_SLOT R_AARCH64_JUMP_SLOT -#define XH_ELF_R_GENERIC_GLOB_DAT R_AARCH64_GLOB_DAT -#define XH_ELF_R_GENERIC_ABS R_AARCH64_ABS64 -#elif defined(__i386__) -#define XH_ELF_R_GENERIC_JUMP_SLOT R_386_JMP_SLOT -#define XH_ELF_R_GENERIC_GLOB_DAT R_386_GLOB_DAT -#define XH_ELF_R_GENERIC_ABS R_386_32 -#elif defined(__x86_64__) -#define XH_ELF_R_GENERIC_JUMP_SLOT R_X86_64_JUMP_SLOT -#define XH_ELF_R_GENERIC_GLOB_DAT R_X86_64_GLOB_DAT -#define XH_ELF_R_GENERIC_ABS R_X86_64_64 -#endif - -#if defined(__LP64__) -#define XH_ELF_R_SYM(info) ELF64_R_SYM(info) -#define XH_ELF_R_TYPE(info) ELF64_R_TYPE(info) -#else -#define XH_ELF_R_SYM(info) ELF32_R_SYM(info) -#define XH_ELF_R_TYPE(info) ELF32_R_TYPE(info) -#endif - -//iterator for plain PLT -typedef struct -{ - uint8_t *cur; - uint8_t *end; - int is_use_rela; -} xh_elf_plain_reloc_iterator_t; - -static void xh_elf_plain_reloc_iterator_init(xh_elf_plain_reloc_iterator_t *self, - ElfW(Addr) rel, ElfW(Word) rel_sz, int is_use_rela) -{ - self->cur = (uint8_t *)rel; - self->end = self->cur + rel_sz; - self->is_use_rela = is_use_rela; -} - -static void *xh_elf_plain_reloc_iterator_next(xh_elf_plain_reloc_iterator_t *self) -{ - if(self->cur >= self->end) return NULL; - - self->cur += (self->is_use_rela ? sizeof(ElfW(Rela)) : sizeof(ElfW(Rel))); - return (void *)(self->cur); -} - -//sleb128 decoder -typedef struct -{ - uint8_t *cur; - uint8_t *end; -} xh_elf_sleb128_decoder_t; - -static void xh_elf_sleb128_decoder_init(xh_elf_sleb128_decoder_t *self, - ElfW(Addr) rel, ElfW(Word) rel_sz) -{ - self->cur = (uint8_t *)rel; - self->end = self->cur + rel_sz; -} - -static int xh_elf_sleb128_decoder_next(xh_elf_sleb128_decoder_t *self, size_t *ret) -{ - size_t value = 0; - static const size_t size = 8 * sizeof(value); - size_t shift = 0; - uint8_t byte; - - do - { - if(self->cur >= self->end) - return XH_ERRNO_FORMAT; - - byte = *(self->cur)++; - value |= ((size_t)(byte & 127) << shift); - shift += 7; - } while(byte & 128); - - if(shift < size && (byte & 64)) - { - value |= -((size_t)(1) << shift); - } - - *ret = value; - return 0; -} - -//iterator for sleb128 decoded packed PLT -typedef struct -{ - xh_elf_sleb128_decoder_t decoder; - size_t relocation_count; - size_t group_size; - size_t group_flags; - size_t group_r_offset_delta; - size_t relocation_index; - size_t relocation_group_index; - ElfW(Rela) rela; - ElfW(Rel) rel; - ElfW(Addr) r_offset; - size_t r_info; - ssize_t r_addend; - int is_use_rela; -} xh_elf_packed_reloc_iterator_t; - -const size_t RELOCATION_GROUPED_BY_INFO_FLAG = 1; -const size_t RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG = 2; -const size_t RELOCATION_GROUPED_BY_ADDEND_FLAG = 4; -const size_t RELOCATION_GROUP_HAS_ADDEND_FLAG = 8; - -static int xh_elf_packed_reloc_iterator_init(xh_elf_packed_reloc_iterator_t *self, - ElfW(Addr) rel, ElfW(Word) rel_sz, int is_use_rela) -{ - int r; - - memset(self, 0, sizeof(xh_elf_packed_reloc_iterator_t)); - xh_elf_sleb128_decoder_init(&(self->decoder), rel, rel_sz); - self->is_use_rela = is_use_rela; - - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), &(self->relocation_count)))) return r; - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), (size_t *)&(self->r_offset)))) return r; - return 0; -} - -static int xh_elf_packed_reloc_iterator_read_group_fields(xh_elf_packed_reloc_iterator_t *self) -{ - int r; - size_t val; - - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), &(self->group_size)))) return r; - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), &(self->group_flags)))) return r; - - if(self->group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), &(self->group_r_offset_delta)))) return r; - - if(self->group_flags & RELOCATION_GROUPED_BY_INFO_FLAG) - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), (size_t *)&(self->r_info)))) return r; - - if((self->group_flags & RELOCATION_GROUP_HAS_ADDEND_FLAG) && - (self->group_flags & RELOCATION_GROUPED_BY_ADDEND_FLAG)) - { - if(0 == self->is_use_rela) - { - XH_LOG_ERROR("unexpected r_addend in android.rel section"); - return XH_ERRNO_FORMAT; - } - if(0 != (r = xh_elf_sleb128_decoder_next(&(self->decoder), &val))) return r; - self->r_addend += (ssize_t)val; - } - else if(0 == (self->group_flags & RELOCATION_GROUP_HAS_ADDEND_FLAG)) - { - self->r_addend = 0; - } - - self->relocation_group_index = 0; - return 0; -} - -static void *xh_elf_packed_reloc_iterator_next(xh_elf_packed_reloc_iterator_t *self) -{ - size_t val; - - if(self->relocation_index >= self->relocation_count) return NULL; - - if(self->relocation_group_index == self->group_size) - { - if(0 != xh_elf_packed_reloc_iterator_read_group_fields(self)) return NULL; - } - - if(self->group_flags & RELOCATION_GROUPED_BY_OFFSET_DELTA_FLAG) - { - self->r_offset += self->group_r_offset_delta; - } - else - { - if(0 != xh_elf_sleb128_decoder_next(&(self->decoder), &val)) return NULL; - self->r_offset += val; - } - - if(0 == (self->group_flags & RELOCATION_GROUPED_BY_INFO_FLAG)) - if(0 != xh_elf_sleb128_decoder_next(&(self->decoder), &(self->r_info))) return NULL; - - if(self->is_use_rela && - (self->group_flags & RELOCATION_GROUP_HAS_ADDEND_FLAG) && - (0 == (self->group_flags & RELOCATION_GROUPED_BY_ADDEND_FLAG))) - { - if(0 != xh_elf_sleb128_decoder_next(&(self->decoder), &val)) return NULL; - self->r_addend += (ssize_t)val; - } - - self->relocation_index++; - self->relocation_group_index++; - - if(self->is_use_rela) - { - self->rela.r_offset = self->r_offset; - self->rela.r_info = self->r_info; - self->rela.r_addend = self->r_addend; - return (void *)(&(self->rela)); - } - else - { - self->rel.r_offset = self->r_offset; - self->rel.r_info = self->r_info; - return (void *)(&(self->rel)); - } -} - -//ELF header checker -int xh_elf_check_elfheader(uintptr_t base_addr) -{ - ElfW(Ehdr) *ehdr = (ElfW(Ehdr) *)base_addr; - - //check magic - if(0 != memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) return XH_ERRNO_FORMAT; - - //check class (64/32) -#if defined(__LP64__) - if(ELFCLASS64 != ehdr->e_ident[EI_CLASS]) return XH_ERRNO_FORMAT; -#else - if(ELFCLASS32 != ehdr->e_ident[EI_CLASS]) return XH_ERRNO_FORMAT; -#endif - - //check endian (little/big) - if(ELFDATA2LSB != ehdr->e_ident[EI_DATA]) return XH_ERRNO_FORMAT; - - //check version - if(EV_CURRENT != ehdr->e_ident[EI_VERSION]) return XH_ERRNO_FORMAT; - - //check type - if(ET_EXEC != ehdr->e_type && ET_DYN != ehdr->e_type) return XH_ERRNO_FORMAT; - - //check machine -#if defined(__arm__) - if(EM_ARM != ehdr->e_machine) return XH_ERRNO_FORMAT; -#elif defined(__aarch64__) - if(EM_AARCH64 != ehdr->e_machine) return XH_ERRNO_FORMAT; -#elif defined(__i386__) - if(EM_386 != ehdr->e_machine) return XH_ERRNO_FORMAT; -#elif defined(__x86_64__) - if(EM_X86_64 != ehdr->e_machine) return XH_ERRNO_FORMAT; -#else - return XH_ERRNO_FORMAT; -#endif - - //check version - if(EV_CURRENT != ehdr->e_version) return XH_ERRNO_FORMAT; - - return 0; -} - -//ELF hash func -static uint32_t xh_elf_hash(const uint8_t *name) -{ - uint32_t h = 0, g; - - while (*name) { - h = (h << 4) + *name++; - g = h & 0xf0000000; - h ^= g; - h ^= g >> 24; - } - - return h; -} - -//GNU hash func -static uint32_t xh_elf_gnu_hash(const uint8_t *name) -{ - uint32_t h = 5381; - - while(*name != 0) - { - h += (h << 5) + *name++; - } - return h; -} - -static ElfW(Phdr) *xh_elf_get_first_segment_by_type(xh_elf_t *self, ElfW(Word) type) -{ - ElfW(Phdr) *phdr; - - for(phdr = self->phdr; phdr < self->phdr + self->ehdr->e_phnum; phdr++) - { - if(phdr->p_type == type) - { - return phdr; - } - } - return NULL; -} - -static ElfW(Phdr) *xh_elf_get_first_segment_by_type_offset(xh_elf_t *self, ElfW(Word) type, ElfW(Off) offset) -{ - ElfW(Phdr) *phdr; - - for(phdr = self->phdr; phdr < self->phdr + self->ehdr->e_phnum; phdr++) - { - if(phdr->p_type == type && phdr->p_offset == offset) - { - return phdr; - } - } - return NULL; -} - -static int xh_elf_hash_lookup(xh_elf_t *self, const char *symbol, uint32_t *symidx) -{ - uint32_t hash = xh_elf_hash((uint8_t *)symbol); - const char *symbol_cur; - uint32_t i; - - for(i = self->bucket[hash % self->bucket_cnt]; 0 != i; i = self->chain[i]) - { - symbol_cur = self->strtab + self->symtab[i].st_name; - - if(0 == strcmp(symbol, symbol_cur)) - { - *symidx = i; - XH_LOG_INFO("found %s at symidx: %u (ELF_HASH)\n", symbol, *symidx); - return 0; - } - } - - return XH_ERRNO_NOTFND; -} - -static int xh_elf_gnu_hash_lookup_def(xh_elf_t *self, const char *symbol, uint32_t *symidx) -{ - uint32_t hash = xh_elf_gnu_hash((uint8_t *)symbol); - - static uint32_t elfclass_bits = sizeof(ElfW(Addr)) * 8; - size_t word = self->bloom[(hash / elfclass_bits) % self->bloom_sz]; - size_t mask = 0 - | (size_t)1 << (hash % elfclass_bits) - | (size_t)1 << ((hash >> self->bloom_shift) % elfclass_bits); - - //if at least one bit is not set, this symbol is surely missing - if((word & mask) != mask) return XH_ERRNO_NOTFND; - - //ignore STN_UNDEF - uint32_t i = self->bucket[hash % self->bucket_cnt]; - if(i < self->symoffset) return XH_ERRNO_NOTFND; - - //loop through the chain - while(1) - { - const char *symname = self->strtab + self->symtab[i].st_name; - const uint32_t symhash = self->chain[i - self->symoffset]; - - if((hash | (uint32_t)1) == (symhash | (uint32_t)1) && 0 == strcmp(symbol, symname)) - { - *symidx = i; - XH_LOG_INFO("found %s at symidx: %u (GNU_HASH DEF)\n", symbol, *symidx); - return 0; - } - - //chain ends with an element with the lowest bit set to 1 - if(symhash & (uint32_t)1) break; - - i++; - } - - return XH_ERRNO_NOTFND; -} - -static int xh_elf_gnu_hash_lookup_undef(xh_elf_t *self, const char *symbol, uint32_t *symidx) -{ - uint32_t i; - - for(i = 0; i < self->symoffset; i++) - { - const char *symname = self->strtab + self->symtab[i].st_name; - if(0 == strcmp(symname, symbol)) - { - *symidx = i; - XH_LOG_INFO("found %s at symidx: %u (GNU_HASH UNDEF)\n", symbol, *symidx); - return 0; - } - } - return XH_ERRNO_NOTFND; -} - -static int xh_elf_gnu_hash_lookup(xh_elf_t *self, const char *symbol, uint32_t *symidx) -{ - if(0 == xh_elf_gnu_hash_lookup_def(self, symbol, symidx)) return 0; - if(0 == xh_elf_gnu_hash_lookup_undef(self, symbol, symidx)) return 0; - return XH_ERRNO_NOTFND; -} - -static int xh_elf_find_symidx_by_name(xh_elf_t *self, const char *symbol, uint32_t *symidx) -{ - if(self->is_use_gnu_hash) - return xh_elf_gnu_hash_lookup(self, symbol, symidx); - else - return xh_elf_hash_lookup(self, symbol, symidx); -} - -static int xh_elf_replace_function(xh_elf_t *self, const char *symbol, ElfW(Addr) addr, void *new_func, void **old_func) -{ - void *old_addr; - unsigned int old_prot = 0; - unsigned int need_prot = PROT_READ | PROT_WRITE; - int r; - - //already replaced? - //here we assume that we always have read permission, is this a problem? - if(*(void **)addr == new_func) return 0; - - //get old prot - if(0 != (r = xh_util_get_addr_protect(addr, self->pathname, &old_prot))) - { - XH_LOG_ERROR("get addr prot failed. ret: %d", r); - return r; - } - - if(old_prot != need_prot) - { - //set new prot - if(0 != (r = xh_util_set_addr_protect(addr, need_prot))) - { - XH_LOG_ERROR("set addr prot failed. ret: %d", r); - return r; - } - } - - //save old func - old_addr = *(void **)addr; - if(NULL != old_func) *old_func = old_addr; - - //replace func - *(void **)addr = new_func; //segmentation fault sometimes - - if(old_prot != need_prot) - { - //restore the old prot - if(0 != (r = xh_util_set_addr_protect(addr, old_prot))) - { - XH_LOG_WARN("restore addr prot failed. ret: %d", r); - } - } - - //clear cache - xh_util_flush_instruction_cache(addr); - - XH_LOG_INFO("XH_HK_OK %p: %p -> %p %s %s\n", (void *)addr, old_addr, new_func, symbol, self->pathname); - return 0; -} - -static int xh_elf_check(xh_elf_t *self) -{ - if(0 == self->base_addr) - { - XH_LOG_ERROR("base_addr == 0\n"); - return 1; - } - if(0 == self->bias_addr) - { - XH_LOG_ERROR("bias_addr == 0\n"); - return 1; - } - if(NULL == self->ehdr) - { - XH_LOG_ERROR("ehdr == NULL\n"); - return 1; - } - if(NULL == self->phdr) - { - XH_LOG_ERROR("phdr == NULL\n"); - return 1; - } - if(NULL == self->strtab) - { - XH_LOG_ERROR("strtab == NULL\n"); - return 1; - } - if(NULL == self->symtab) - { - XH_LOG_ERROR("symtab == NULL\n"); - return 1; - } - if(NULL == self->bucket) - { - XH_LOG_ERROR("bucket == NULL\n"); - return 1; - } - if(NULL == self->chain) - { - XH_LOG_ERROR("chain == NULL\n"); - return 1; - } - if(1 == self->is_use_gnu_hash && NULL == self->bloom) - { - XH_LOG_ERROR("bloom == NULL\n"); - return 1; - } - - return 0; -} - -#if XH_ELF_DEBUG - -static void xh_elf_dump_elfheader(xh_elf_t *self) -{ - static char alpha_tab[17] = "0123456789ABCDEF"; - int i; - uint8_t ch; - char buff[EI_NIDENT * 3 + 1]; - - for(i = 0; i < EI_NIDENT; i++) - { - ch = self->ehdr->e_ident[i]; - buff[i * 3 + 0] = alpha_tab[(int)((ch >> 4) & 0x0F)]; - buff[i * 3 + 1] = alpha_tab[(int)(ch & 0x0F)]; - buff[i * 3 + 2] = ' '; - } - buff[EI_NIDENT * 3] = '\0'; - - XH_LOG_DEBUG("Elf Header:\n"); - XH_LOG_DEBUG(" Magic: %s\n", buff); - XH_LOG_DEBUG(" Class: %#x\n", self->ehdr->e_ident[EI_CLASS]); - XH_LOG_DEBUG(" Data: %#x\n", self->ehdr->e_ident[EI_DATA]); - XH_LOG_DEBUG(" Version: %#x\n", self->ehdr->e_ident[EI_VERSION]); - XH_LOG_DEBUG(" OS/ABI: %#x\n", self->ehdr->e_ident[EI_OSABI]); - XH_LOG_DEBUG(" ABI Version: %#x\n", self->ehdr->e_ident[EI_ABIVERSION]); - XH_LOG_DEBUG(" Type: %#x\n", self->ehdr->e_type); - XH_LOG_DEBUG(" Machine: %#x\n", self->ehdr->e_machine); - XH_LOG_DEBUG(" Version: %#x\n", self->ehdr->e_version); - XH_LOG_DEBUG(" Entry point address: %"XH_UTIL_FMT_X"\n", self->ehdr->e_entry); - XH_LOG_DEBUG(" Start of program headers: %"XH_UTIL_FMT_X" (bytes into file)\n", self->ehdr->e_phoff); - XH_LOG_DEBUG(" Start of section headers: %"XH_UTIL_FMT_X" (bytes into file)\n", self->ehdr->e_shoff); - XH_LOG_DEBUG(" Flags: %#x\n", self->ehdr->e_flags); - XH_LOG_DEBUG(" Size of this header: %u (bytes)\n", self->ehdr->e_ehsize); - XH_LOG_DEBUG(" Size of program headers: %u (bytes)\n", self->ehdr->e_phentsize); - XH_LOG_DEBUG(" Number of program headers: %u\n", self->ehdr->e_phnum); - XH_LOG_DEBUG(" Size of section headers: %u (bytes)\n", self->ehdr->e_shentsize); - XH_LOG_DEBUG(" Number of section headers: %u\n", self->ehdr->e_shnum); - XH_LOG_DEBUG(" Section header string table index: %u\n", self->ehdr->e_shstrndx); -} - -static void xh_elf_dump_programheader(xh_elf_t *self) -{ - ElfW(Phdr) *phdr = self->phdr; - size_t i; - - XH_LOG_DEBUG("Program Headers:\n"); - XH_LOG_DEBUG(" %-8s " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-8s " \ - "%-s\n", - "Type", - "Offset", - "VirtAddr", - "PhysAddr", - "FileSiz", - "MemSiz", - "Flg", - "Align"); - for(i = 0; i < self->ehdr->e_phnum; i++, phdr++) - { - XH_LOG_DEBUG(" %-8x " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%-8x " \ - "%"XH_UTIL_FMT_X"\n", - phdr->p_type, - phdr->p_offset, - phdr->p_vaddr, - phdr->p_paddr, - phdr->p_filesz, - phdr->p_memsz, - phdr->p_flags, - phdr->p_align); - } -} - -static void xh_elf_dump_dynamic(xh_elf_t *self) -{ - ElfW(Dyn) *dyn = self->dyn; - size_t dyn_cnt = (self->dyn_sz / sizeof(ElfW(Dyn))); - size_t i; - - XH_LOG_DEBUG("Dynamic section contains %zu entries:\n", dyn_cnt); - XH_LOG_DEBUG(" %-"XH_UTIL_FMT_FIXED_S" " \ - "%s\n", - "Tag", - "Val"); - for(i = 0; i < dyn_cnt; i++, dyn++) - { - XH_LOG_DEBUG(" %-"XH_UTIL_FMT_FIXED_X" " \ - "%-"XH_UTIL_FMT_X"\n", - dyn->d_tag, - dyn->d_un.d_val); - } -} - -static void xh_elf_dump_rel(xh_elf_t *self, const char *type, ElfW(Addr) rel_addr, ElfW(Word) rel_sz) -{ - ElfW(Rela) *rela; - ElfW(Rel) *rel; - ElfW(Word) cnt; - ElfW(Word) i; - ElfW(Sym) *sym; - - if(self->is_use_rela) - { - rela = (ElfW(Rela) *)(rel_addr); - cnt = rel_sz / sizeof(ElfW(Rela)); - } - else - { - rel = (ElfW(Rel) *)(rel_addr); - cnt = rel_sz / sizeof(ElfW(Rel)); - } - - XH_LOG_DEBUG("Relocation section '.rel%s%s' contains %u entries:\n", - (self->is_use_rela ? "a" : ""), type, cnt); - XH_LOG_DEBUG(" %-"XH_UTIL_FMT_FIXED_S" " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%-8s " \ - "%-8s " \ - "%-8s " \ - "%s\n", - "Offset", - "Info", - "Type", - "Sym.Idx", - "Sym.Val", - "Sym.Name"); - const char *fmt = " %."XH_UTIL_FMT_FIXED_X" " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%.8x " \ - "%.8u " \ - "%.8x " \ - "%s\n"; - for(i = 0; i < cnt; i++) - { - if(self->is_use_rela) - { - sym = &(self->symtab[XH_ELF_R_SYM(rela[i].r_info)]); - XH_LOG_DEBUG(fmt, - rela[i].r_offset, - rela[i].r_info, - XH_ELF_R_TYPE(rela[i].r_info), - XH_ELF_R_SYM(rela[i].r_info), - sym->st_value, - self->strtab + sym->st_name); - } - else - { - sym = &(self->symtab[XH_ELF_R_SYM(rel[i].r_info)]); - XH_LOG_DEBUG(fmt, - rel[i].r_offset, - rel[i].r_info, - XH_ELF_R_TYPE(rel[i].r_info), - XH_ELF_R_SYM(rel[i].r_info), - sym->st_value, - self->strtab + sym->st_name); - } - } -} - -static void xh_elf_dump_symtab(xh_elf_t *self) -{ - if(self->is_use_gnu_hash) return; - - ElfW(Word) symtab_cnt = self->chain_cnt; - ElfW(Word) i; - - XH_LOG_DEBUG("Symbol table '.dynsym' contains %u entries:\n", symtab_cnt); - XH_LOG_DEBUG(" %-8s " \ - "%-"XH_UTIL_FMT_FIXED_S" " \ - "%s\n", - "Idx", - "Value", - "Name"); - for(i = 0; i < symtab_cnt; i++) - { - XH_LOG_DEBUG(" %-8u " \ - "%."XH_UTIL_FMT_FIXED_X" " \ - "%s\n", - i, - self->symtab[i].st_value, - self->strtab + self->symtab[i].st_name); - } -} - -static void xh_elf_dump(xh_elf_t *self) -{ - if(xh_log_priority < ANDROID_LOG_DEBUG) return; - - XH_LOG_DEBUG("Elf Pathname: %s\n", self->pathname); - XH_LOG_DEBUG("Elf bias addr: %p\n", (void *)self->bias_addr); - xh_elf_dump_elfheader(self); - xh_elf_dump_programheader(self); - xh_elf_dump_dynamic(self); - xh_elf_dump_rel(self, ".plt", self->relplt, self->relplt_sz); - xh_elf_dump_rel(self, ".dyn", self->reldyn, self->reldyn_sz); - xh_elf_dump_symtab(self); -} - -#endif - -int xh_elf_init(xh_elf_t *self, uintptr_t base_addr, const char *pathname) -{ - if(0 == base_addr || NULL == pathname) return XH_ERRNO_INVAL; - - //always reset - memset(self, 0, sizeof(xh_elf_t)); - - self->pathname = pathname; - self->base_addr = (ElfW(Addr))base_addr; - self->ehdr = (ElfW(Ehdr) *)base_addr; - self->phdr = (ElfW(Phdr) *)(base_addr + self->ehdr->e_phoff); //segmentation fault sometimes - - //find the first load-segment with offset 0 - ElfW(Phdr) *phdr0 = xh_elf_get_first_segment_by_type_offset(self, PT_LOAD, 0); - if(NULL == phdr0) - { - XH_LOG_ERROR("Can NOT found the first load segment. %s", pathname); - return XH_ERRNO_FORMAT; - } - -#if XH_ELF_DEBUG - if(0 != phdr0->p_vaddr) - XH_LOG_DEBUG("first load-segment vaddr NOT 0 (vaddr: %p). %s", - (void *)(phdr0->p_vaddr), pathname); -#endif - - //save load bias addr - if(self->base_addr < phdr0->p_vaddr) return XH_ERRNO_FORMAT; - self->bias_addr = self->base_addr - phdr0->p_vaddr; - - //find dynamic-segment - ElfW(Phdr) *dhdr = xh_elf_get_first_segment_by_type(self, PT_DYNAMIC); - if(NULL == dhdr) - { - XH_LOG_ERROR("Can NOT found dynamic segment. %s", pathname); - return XH_ERRNO_FORMAT; - } - - //parse dynamic-segment - self->dyn = (ElfW(Dyn) *)(self->bias_addr + dhdr->p_vaddr); - self->dyn_sz = dhdr->p_memsz; - ElfW(Dyn) *dyn = self->dyn; - ElfW(Dyn) *dyn_end = self->dyn + (self->dyn_sz / sizeof(ElfW(Dyn))); - uint32_t *raw; - for(; dyn < dyn_end; dyn++) - { - switch(dyn->d_tag) //segmentation fault sometimes - { - case DT_NULL: - //the end of the dynamic-section - dyn = dyn_end; - break; - case DT_STRTAB: - { - self->strtab = (const char *)(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))(self->strtab) < self->base_addr) return XH_ERRNO_FORMAT; - break; - } - case DT_SYMTAB: - { - self->symtab = (ElfW(Sym) *)(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))(self->symtab) < self->base_addr) return XH_ERRNO_FORMAT; - break; - } - case DT_PLTREL: - //use rel or rela? - self->is_use_rela = (dyn->d_un.d_val == DT_RELA ? 1 : 0); - break; - case DT_JMPREL: - { - self->relplt = (ElfW(Addr))(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))(self->relplt) < self->base_addr) return XH_ERRNO_FORMAT; - break; - } - case DT_PLTRELSZ: - self->relplt_sz = dyn->d_un.d_val; - break; - case DT_REL: - case DT_RELA: - { - self->reldyn = (ElfW(Addr))(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))(self->reldyn) < self->base_addr) return XH_ERRNO_FORMAT; - break; - } - case DT_RELSZ: - case DT_RELASZ: - self->reldyn_sz = dyn->d_un.d_val; - break; - case DT_ANDROID_REL: - case DT_ANDROID_RELA: - { - self->relandroid = (ElfW(Addr))(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))(self->relandroid) < self->base_addr) return XH_ERRNO_FORMAT; - break; - } - case DT_ANDROID_RELSZ: - case DT_ANDROID_RELASZ: - self->relandroid_sz = dyn->d_un.d_val; - break; - case DT_HASH: - { - raw = (uint32_t *)(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))raw < self->base_addr) return XH_ERRNO_FORMAT; - self->bucket_cnt = raw[0]; - self->chain_cnt = raw[1]; - self->bucket = &raw[2]; - self->chain = &(self->bucket[self->bucket_cnt]); - break; - } - case DT_GNU_HASH: - { - raw = (uint32_t *)(self->bias_addr + dyn->d_un.d_ptr); - if((ElfW(Addr))raw < self->base_addr) return XH_ERRNO_FORMAT; - self->bucket_cnt = raw[0]; - self->symoffset = raw[1]; - self->bloom_sz = raw[2]; - self->bloom_shift = raw[3]; - self->bloom = (ElfW(Addr) *)(&raw[4]); - self->bucket = (uint32_t *)(&(self->bloom[self->bloom_sz])); - self->chain = (uint32_t *)(&(self->bucket[self->bucket_cnt])); - self->is_use_gnu_hash = 1; - break; - } - default: - break; - } - } - - //check android rel/rela - if(0 != self->relandroid) - { - const char *rel = (const char *)self->relandroid; - if(self->relandroid_sz < 4 || - rel[0] != 'A' || - rel[1] != 'P' || - rel[2] != 'S' || - rel[3] != '2') - { - XH_LOG_ERROR("android rel/rela format error\n"); - return XH_ERRNO_FORMAT; - } - - self->relandroid += 4; - self->relandroid_sz -= 4; - } - - //check elf info - if(0 != xh_elf_check(self)) - { - XH_LOG_ERROR("elf init check failed. %s", pathname); - return XH_ERRNO_FORMAT; - } - -#if XH_ELF_DEBUG - xh_elf_dump(self); -#endif - - XH_LOG_INFO("init OK: %s (%s %s PLT:%u DYN:%u ANDROID:%u)\n", self->pathname, - self->is_use_rela ? "RELA" : "REL", - self->is_use_gnu_hash ? "GNU_HASH" : "ELF_HASH", - self->relplt_sz, self->reldyn_sz, self->relandroid_sz); - - return 0; -} - -static int xh_elf_find_and_replace_func(xh_elf_t *self, const char *section, - int is_plt, const char *symbol, - void *new_func, void **old_func, - uint32_t symidx, void *rel_common, - int *found) -{ - ElfW(Rela) *rela; - ElfW(Rel) *rel; - ElfW(Addr) r_offset; - size_t r_info; - size_t r_sym; - size_t r_type; - ElfW(Addr) addr; - int r; - - if(NULL != found) *found = 0; - - if(self->is_use_rela) - { - rela = (ElfW(Rela) *)rel_common; - r_info = rela->r_info; - r_offset = rela->r_offset; - } - else - { - rel = (ElfW(Rel) *)rel_common; - r_info = rel->r_info; - r_offset = rel->r_offset; - } - - //check sym - r_sym = XH_ELF_R_SYM(r_info); - if(r_sym != symidx) return 0; - - //check type - r_type = XH_ELF_R_TYPE(r_info); - if(is_plt && r_type != XH_ELF_R_GENERIC_JUMP_SLOT) return 0; - if(!is_plt && (r_type != XH_ELF_R_GENERIC_GLOB_DAT && r_type != XH_ELF_R_GENERIC_ABS)) return 0; - - //we found it - XH_LOG_INFO("found %s at %s offset: %p\n", symbol, section, (void *)r_offset); - if(NULL != found) *found = 1; - - //do replace - addr = self->bias_addr + r_offset; - if(addr < self->base_addr) return XH_ERRNO_FORMAT; - if(0 != (r = xh_elf_replace_function(self, symbol, addr, new_func, old_func))) - { - XH_LOG_ERROR("replace function failed: %s at %s\n", symbol, section); - return r; - } - - return 0; -} - -int xh_elf_hook(xh_elf_t *self, const char *symbol, void *new_func, void **old_func) -{ - uint32_t symidx; - void *rel_common; - xh_elf_plain_reloc_iterator_t plain_iter; - xh_elf_packed_reloc_iterator_t packed_iter; - int found; - int r; - - if(NULL == self->pathname) - { - XH_LOG_ERROR("not inited\n"); - return XH_ERRNO_ELFINIT; //not inited? - } - - if(NULL == symbol || NULL == new_func) return XH_ERRNO_INVAL; - - XH_LOG_INFO("hooking %s in %s\n", symbol, self->pathname); - - //find symbol index by symbol name - if(0 != (r = xh_elf_find_symidx_by_name(self, symbol, &symidx))) return 0; - - //replace for .rel(a).plt - if(0 != self->relplt) - { - xh_elf_plain_reloc_iterator_init(&plain_iter, self->relplt, self->relplt_sz, self->is_use_rela); - while(NULL != (rel_common = xh_elf_plain_reloc_iterator_next(&plain_iter))) - { - if(0 != (r = xh_elf_find_and_replace_func(self, - (self->is_use_rela ? ".rela.plt" : ".rel.plt"), 1, - symbol, new_func, old_func, - symidx, rel_common, &found))) return r; - if(found) break; - } - } - - //replace for .rel(a).dyn - if(0 != self->reldyn) - { - xh_elf_plain_reloc_iterator_init(&plain_iter, self->reldyn, self->reldyn_sz, self->is_use_rela); - while(NULL != (rel_common = xh_elf_plain_reloc_iterator_next(&plain_iter))) - { - if(0 != (r = xh_elf_find_and_replace_func(self, - (self->is_use_rela ? ".rela.dyn" : ".rel.dyn"), 0, - symbol, new_func, old_func, - symidx, rel_common, NULL))) return r; - } - } - - //replace for .rel(a).android - if(0 != self->relandroid) - { - xh_elf_packed_reloc_iterator_init(&packed_iter, self->relandroid, self->relandroid_sz, self->is_use_rela); - while(NULL != (rel_common = xh_elf_packed_reloc_iterator_next(&packed_iter))) - { - if(0 != (r = xh_elf_find_and_replace_func(self, - (self->is_use_rela ? ".rela.android" : ".rel.android"), 0, - symbol, new_func, old_func, - symidx, rel_common, NULL))) return r; - } - } - - return 0; -} diff --git a/riru-core/jni/external/xhook/xh_elf.h b/riru-core/jni/external/xhook/xh_elf.h deleted file mode 100644 index 1697dc4..0000000 --- a/riru-core/jni/external/xhook/xh_elf.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_ELF_H -#define XH_ELF_H 1 - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - const char *pathname; - - ElfW(Addr) base_addr; - ElfW(Addr) bias_addr; - - ElfW(Ehdr) *ehdr; - ElfW(Phdr) *phdr; - - ElfW(Dyn) *dyn; //.dynamic - ElfW(Word) dyn_sz; - - const char *strtab; //.dynstr (string-table) - ElfW(Sym) *symtab; //.dynsym (symbol-index to string-table's offset) - - ElfW(Addr) relplt; //.rel.plt or .rela.plt - ElfW(Word) relplt_sz; - - ElfW(Addr) reldyn; //.rel.dyn or .rela.dyn - ElfW(Word) reldyn_sz; - - ElfW(Addr) relandroid; //android compressed rel or rela - ElfW(Word) relandroid_sz; - - //for ELF hash - uint32_t *bucket; - uint32_t bucket_cnt; - uint32_t *chain; - uint32_t chain_cnt; //invalid for GNU hash - - //append for GNU hash - uint32_t symoffset; - ElfW(Addr) *bloom; - uint32_t bloom_sz; - uint32_t bloom_shift; - - int is_use_rela; - int is_use_gnu_hash; -} xh_elf_t; - -int xh_elf_init(xh_elf_t *self, uintptr_t base_addr, const char *pathname); -int xh_elf_hook(xh_elf_t *self, const char *symbol, void *new_func, void **old_func); - -int xh_elf_check_elfheader(uintptr_t base_addr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/xh_errno.h b/riru-core/jni/external/xhook/xh_errno.h deleted file mode 100644 index e628cd7..0000000 --- a/riru-core/jni/external/xhook/xh_errno.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_ERRNO_H -#define XH_ERRNO_H 1 - -#define XH_ERRNO_UNKNOWN 1001 -#define XH_ERRNO_INVAL 1002 -#define XH_ERRNO_NOMEM 1003 -#define XH_ERRNO_REPEAT 1004 -#define XH_ERRNO_NOTFND 1005 -#define XH_ERRNO_BADMAPS 1006 -#define XH_ERRNO_FORMAT 1007 -#define XH_ERRNO_ELFINIT 1008 -#define XH_ERRNO_SEGVERR 1009 - -#endif diff --git a/riru-core/jni/external/xhook/xh_jni.c b/riru-core/jni/external/xhook/xh_jni.c deleted file mode 100644 index f8ae223..0000000 --- a/riru-core/jni/external/xhook/xh_jni.c +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include -#include "xhook.h" - -#define JNI_API_DEF(f) Java_com_qiyi_xhook_NativeHandler_##f - -JNIEXPORT jint JNI_API_DEF(refresh)(JNIEnv *env, jobject obj, jboolean async) -{ - (void)env; - (void)obj; - - return xhook_refresh(async ? 1 : 0); -} - -JNIEXPORT void JNI_API_DEF(clear)(JNIEnv *env, jobject obj) -{ - (void)env; - (void)obj; - - xhook_clear(); -} - -JNIEXPORT void JNI_API_DEF(enableDebug)(JNIEnv *env, jobject obj, jboolean flag) -{ - (void)env; - (void)obj; - - xhook_enable_debug(flag ? 1 : 0); -} - -JNIEXPORT void JNI_API_DEF(enableSigSegvProtection)(JNIEnv *env, jobject obj, jboolean flag) -{ - (void)env; - (void)obj; - - xhook_enable_sigsegv_protection(flag ? 1 : 0); -} diff --git a/riru-core/jni/external/xhook/xh_log.c b/riru-core/jni/external/xhook/xh_log.c deleted file mode 100644 index 6cba947..0000000 --- a/riru-core/jni/external/xhook/xh_log.c +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include -#include "xh_log.h" - -android_LogPriority xh_log_priority = ANDROID_LOG_WARN; diff --git a/riru-core/jni/external/xhook/xh_log.h b/riru-core/jni/external/xhook/xh_log.h deleted file mode 100644 index e108c4b..0000000 --- a/riru-core/jni/external/xhook/xh_log.h +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_LOG_H -#define XH_LOG_H 1 - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -extern android_LogPriority xh_log_priority; - -#define XH_LOG_TAG "xhook" -#define XH_LOG_DEBUG(fmt, ...) do{if(xh_log_priority <= ANDROID_LOG_DEBUG) __android_log_print(ANDROID_LOG_DEBUG, XH_LOG_TAG, fmt, ##__VA_ARGS__);}while(0) -#define XH_LOG_INFO(fmt, ...) do{if(xh_log_priority <= ANDROID_LOG_INFO) __android_log_print(ANDROID_LOG_INFO, XH_LOG_TAG, fmt, ##__VA_ARGS__);}while(0) -#define XH_LOG_WARN(fmt, ...) do{if(xh_log_priority <= ANDROID_LOG_WARN) __android_log_print(ANDROID_LOG_WARN, XH_LOG_TAG, fmt, ##__VA_ARGS__);}while(0) -#define XH_LOG_ERROR(fmt, ...) do{if(xh_log_priority <= ANDROID_LOG_ERROR) __android_log_print(ANDROID_LOG_ERROR, XH_LOG_TAG, fmt, ##__VA_ARGS__);}while(0) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/xh_util.c b/riru-core/jni/external/xhook/xh_util.c deleted file mode 100644 index 0e2dca2..0000000 --- a/riru-core/jni/external/xhook/xh_util.c +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "xh_util.h" -#include "xh_errno.h" -#include "xh_log.h" - -#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)) - -int xh_util_get_mem_protect(uintptr_t addr, size_t len, const char *pathname, unsigned int *prot) -{ - uintptr_t start_addr = addr; - uintptr_t end_addr = addr + len; - FILE *fp; - char line[512]; - uintptr_t start, end; - char perm[5]; - int load0 = 1; - int found_all = 0; - - *prot = 0; - - if(NULL == (fp = fopen("/proc/self/maps", "r"))) return XH_ERRNO_BADMAPS; - - while(fgets(line, sizeof(line), fp)) - { - if(NULL != pathname) - if(NULL == strstr(line, pathname)) continue; - - if(sscanf(line, "%"PRIxPTR"-%"PRIxPTR" %4s ", &start, &end, perm) != 3) continue; - - if(perm[3] != 'p') continue; - - if(start_addr >= start && start_addr < end) - { - if(load0) - { - //first load segment - if(perm[0] == 'r') *prot |= PROT_READ; - if(perm[1] == 'w') *prot |= PROT_WRITE; - if(perm[2] == 'x') *prot |= PROT_EXEC; - load0 = 0; - } - else - { - //others - if(perm[0] != 'r') *prot &= ~PROT_READ; - if(perm[1] != 'w') *prot &= ~PROT_WRITE; - if(perm[2] != 'x') *prot &= ~PROT_EXEC; - } - - if(end_addr <= end) - { - found_all = 1; - break; //finished - } - else - { - start_addr = end; //try to find the next load segment - } - } - } - - fclose(fp); - - if(!found_all) return XH_ERRNO_SEGVERR; - - return 0; -} - -int xh_util_get_addr_protect(uintptr_t addr, const char *pathname, unsigned int *prot) -{ - return xh_util_get_mem_protect(addr, sizeof(addr), pathname, prot); -} - -int xh_util_set_addr_protect(uintptr_t addr, unsigned int prot) -{ - if(0 != mprotect((void *)PAGE_START(addr), PAGE_COVER(addr), (int)prot)) - return 0 == errno ? XH_ERRNO_UNKNOWN : errno; - - return 0; -} - -void xh_util_flush_instruction_cache(uintptr_t addr) -{ - __builtin___clear_cache((void *)PAGE_START(addr), (void *)PAGE_END(addr)); -} diff --git a/riru-core/jni/external/xhook/xh_util.h b/riru-core/jni/external/xhook/xh_util.h deleted file mode 100644 index b57f8dc..0000000 --- a/riru-core/jni/external/xhook/xh_util.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_UTILS_H -#define XH_UTILS_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__LP64__) -#define XH_UTIL_FMT_LEN "16" -#define XH_UTIL_FMT_X "llx" -#else -#define XH_UTIL_FMT_LEN "8" -#define XH_UTIL_FMT_X "x" -#endif - -#define XH_UTIL_FMT_FIXED_X XH_UTIL_FMT_LEN XH_UTIL_FMT_X -#define XH_UTIL_FMT_FIXED_S XH_UTIL_FMT_LEN "s" - -int xh_util_get_mem_protect(uintptr_t addr, size_t len, const char *pathname, unsigned int *prot); -int xh_util_get_addr_protect(uintptr_t addr, const char *pathname, unsigned int *prot); -int xh_util_set_addr_protect(uintptr_t addr, unsigned int prot); -void xh_util_flush_instruction_cache(uintptr_t addr); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/xh_version.c b/riru-core/jni/external/xhook/xh_version.c deleted file mode 100644 index b237f16..0000000 --- a/riru-core/jni/external/xhook/xh_version.c +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include "xh_version.h" - -#define XH_VERSION_MAJOR 1 -#define XH_VERSION_MINOR 1 -#define XH_VERSION_EXTRA 9 - -#define XH_VERSION ((XH_VERSION_MAJOR << 16) | (XH_VERSION_MINOR << 8) | (XH_VERSION_EXTRA)) - -#define XH_VERSION_TO_STR_HELPER(x) #x -#define XH_VERSION_TO_STR(x) XH_VERSION_TO_STR_HELPER(x) - -#define XH_VERSION_STR XH_VERSION_TO_STR(XH_VERSION_MAJOR) "." \ - XH_VERSION_TO_STR(XH_VERSION_MINOR) "." \ - XH_VERSION_TO_STR(XH_VERSION_EXTRA) - -#if defined(__arm__) -#define XH_VERSION_ARCH "arm" -#elif defined(__aarch64__) -#define XH_VERSION_ARCH "aarch64" -#elif defined(__i386__) -#define XH_VERSION_ARCH "x86" -#elif defined(__x86_64__) -#define XH_VERSION_ARCH "x86_64" -#else -#define XH_VERSION_ARCH "unknown" -#endif - -#define XH_VERSION_STR_FULL "libxhook "XH_VERSION_STR" ("XH_VERSION_ARCH")" - -unsigned int xh_version() -{ - return XH_VERSION; -} - -const char *xh_version_str() -{ - return XH_VERSION_STR; -} - -const char *xh_version_str_full() -{ - return XH_VERSION_STR_FULL; -} diff --git a/riru-core/jni/external/xhook/xh_version.h b/riru-core/jni/external/xhook/xh_version.h deleted file mode 100644 index b70b4f2..0000000 --- a/riru-core/jni/external/xhook/xh_version.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XH_VERSION_H -#define XH_VERSION_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -unsigned int xh_version(); - -const char *xh_version_str(); - -const char *xh_version_str_full(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/external/xhook/xhook.c b/riru-core/jni/external/xhook/xhook.c deleted file mode 100644 index 49dfc59..0000000 --- a/riru-core/jni/external/xhook/xhook.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#include "xh_core.h" -#include "xhook.h" - -int xhook_register(const char *pathname_regex_str, const char *symbol, - void *new_func, void **old_func) -{ - return xh_core_register(pathname_regex_str, symbol, new_func, old_func); -} - -int xhook_ignore(const char *pathname_regex_str, const char *symbol) -{ - return xh_core_ignore(pathname_regex_str, symbol); -} - -int xhook_refresh(int async) -{ - return xh_core_refresh(async); -} - -void xhook_clear() -{ - return xh_core_clear(); -} - -void xhook_enable_debug(int flag) -{ - return xh_core_enable_debug(flag); -} - -void xhook_enable_sigsegv_protection(int flag) -{ - return xh_core_enable_sigsegv_protection(flag); -} diff --git a/riru-core/jni/external/xhook/xhook.h b/riru-core/jni/external/xhook/xhook.h deleted file mode 100644 index b14b8de..0000000 --- a/riru-core/jni/external/xhook/xhook.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2018-present, iQIYI, Inc. All rights reserved. -// -// 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 2018-04-11. - -#ifndef XHOOK_H -#define XHOOK_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -#define XHOOK_EXPORT - -int xhook_register(const char *pathname_regex_str, const char *symbol, - void *new_func, void **old_func) XHOOK_EXPORT; - -int xhook_ignore(const char *pathname_regex_str, const char *symbol) XHOOK_EXPORT; - -int xhook_refresh(int async) XHOOK_EXPORT; - -void xhook_clear() XHOOK_EXPORT; - -void xhook_enable_debug(int flag) XHOOK_EXPORT; - -void xhook_enable_sigsegv_protection(int flag) XHOOK_EXPORT; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/riru-core/jni/main/Android.mk b/riru-core/jni/main/Android.mk deleted file mode 100644 index 3673326..0000000 --- a/riru-core/jni/main/Android.mk +++ /dev/null @@ -1,14 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := libmemtrack -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH) \ - jni/external/include -LOCAL_STATIC_LIBRARIES := xhook -LOCAL_LDLIBS += -ldl -llog -LOCAL_LDFLAGS := -Wl,--hash-style=both - -LOCAL_SRC_FILES:= main.cpp jni_native_method.cpp misc.cpp wrap.cpp redirect_memtrack.cpp version.cpp api.cpp - -include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/riru-core/jni/main/JNIHelper.h b/riru-core/jni/main/JNIHelper.h deleted file mode 100644 index 399ad86..0000000 --- a/riru-core/jni/main/JNIHelper.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef JNIHELPER_H -#define JNIHELPER_H - -#include -#include "logging.h" - -static int ClearException(JNIEnv *env) { - jthrowable exception = env->ExceptionOccurred(); - if (exception != nullptr) { - env->ExceptionDescribe(); - env->ExceptionClear(); - return true; - } - return false; -} - -#define JNI_FindClass(env, name) \ - env->FindClass(name); \ - if (ClearException(env)) LOGE("FindClass " #name); - -#define JNI_GetObjectClass(env, obj) \ - env->GetObjectClass(obj); \ - if (ClearException(env)) LOGE("GetObjectClass " #obj); - -#define JNI_GetFieldID(env, class, name, sig) \ - env->GetFieldID(class, name, sig); \ - if (ClearException(env)) LOGE("GetFieldID " #name); - -#define JNI_GetObjectField(env, class, fieldId) \ - env->GetObjectField(class, fieldId); \ - if (ClearException(env)) LOGE("GetObjectField " #fieldId); - -#define JNI_GetMethodID(env, class, name, sig) \ - env->GetMethodID(class, name, sig); \ - if (ClearException(env)) LOGE("GetMethodID " #name); - -#define JNI_CallObjectMethod(env, obj, ...) \ - env->CallObjectMethod(obj, __VA_ARGS__); \ - if (ClearException(env)) LOGE("CallObjectMethod " #obj " " #__VA_ARGS__); - -#define JNI_CallVoidMethod(env, obj, ...) \ - env->CallVoidMethod(obj, __VA_ARGS__); \ - if (ClearException(env)) LOGE("CallVoidMethod " #obj " " #__VA_ARGS__); - -#define JNI_GetStaticFieldID(env, class, name, sig) \ - env->GetStaticFieldID(class, name, sig); \ - if (ClearException(env)) LOGE("GetStaticFieldID " #name " " #sig); - -#define JNI_GetStaticObjectField(env, class, fieldId) \ - env->GetStaticObjectField(class, fieldId); \ - if (ClearException(env)) LOGE("GetStaticObjectField " #fieldId); - -#define JNI_GetStaticMethodID(env, class, name, sig) \ - env->GetStaticMethodID(class, name, sig); \ - if (ClearException(env)) LOGE("GetStaticMethodID " #name); - -#define JNI_CallStaticVoidMethod(env, obj, ...) \ - env->CallStaticVoidMethod(obj, __VA_ARGS__); \ - if (ClearException(env)) LOGE("CallStaticVoidMethod " #obj " " #__VA_ARGS__); - -#define JNI_GetArrayLength(env, array) \ - env->GetArrayLength(array); \ - if (ClearException(env)) LOGE("GetArrayLength " #array); - -#define JNI_NewObject(env, class, ...) \ - env->NewObject(class, __VA_ARGS__); \ - if (ClearException(env)) LOGE("NewObject " #class " " #__VA_ARGS__); - -#define JNI_RegisterNatives(env, class, methods, size) \ - env->RegisterNatives(class, methods, size); \ - if (ClearException(env)) LOGE("RegisterNatives " #class); - -#endif // JNIHELPER_H diff --git a/riru-core/jni/main/api.cpp b/riru-core/jni/main/api.cpp deleted file mode 100644 index 11cdc13..0000000 --- a/riru-core/jni/main/api.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include -#include -#include -#include -#include - -#include "logging.h" -#include "module.h" -#include "api.h" - -struct JNINativeMethodHolder { - const JNINativeMethod *methods; - int count; - - JNINativeMethodHolder(const JNINativeMethod *methods, int count) : - methods(methods), count(count) {} -}; - -static auto *native_methods = new std::map(); - -std::vector *get_modules() { - static auto *modules = new std::vector({new module(strdup(MODULE_NAME_CORE))}); - return modules; -} - -void put_native_method(const char *className, const JNINativeMethod *methods, int numMethods) { - (*native_methods)[className] = new JNINativeMethodHolder(methods, numMethods); -} - -static unsigned long get_module_index(const char *name) { - if (!name) - return 0; - - for (unsigned long i = 0; i < get_modules()->size(); ++i) { - if (strcmp(get_modules()->at(i)->name, name) == 0) - return i + 1; - } - return 0; -} - -extern "C" { -const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, - const char *signature) { - auto it = native_methods->find(className); - if (it != native_methods->end()) { - if (!name && !signature) - return it->second->methods; - - auto holder = it->second; - for (int i = 0; i < holder->count; ++i) { - auto method = &holder->methods[i]; - if ((!name || strcmp(method->name, name) == 0) - && (!signature || strcmp(method->signature, signature) == 0)) - return method; - } - } - return nullptr; -} - -void *riru_get_func(const char *module_name, const char *name) { - unsigned long index = get_module_index(module_name); - if (index == 0) - return nullptr; - - index -= 1; - - //LOGV("get_func %s %s", module_name, name); - - // find if it is set by previous modules - if (index != 0) { - for (unsigned long i = index - 1; i >= 0; --i) { - auto module = get_modules()->at(i); - auto it = module->funcs->find(name); - if (module->funcs->end() != it) - return it->second; - - if (i == 0) break; - } - } - - return nullptr; -} - -void *riru_get_native_method_func(const char *module_name, const char *className, const char *name, - const char *signature) { - unsigned long index = get_module_index(module_name); - if (index == 0) - return nullptr; - - index -= 1; - - //LOGV("get_func %s %s %s %s", module_name, className, name, signature); - - // find if it is set by previous modules - if (index != 0) { - for (unsigned long i = index - 1; i >= 0; --i) { - auto module = get_modules()->at(i); - auto it = module->funcs->find(std::string(className) + name + signature); - if (module->funcs->end() != it) - return it->second; - - if (i == 0) break; - } - } - - const JNINativeMethod *jniNativeMethod = riru_get_original_native_methods(className, name, - signature); - return jniNativeMethod ? jniNativeMethod->fnPtr : nullptr; -} - -void riru_set_func(const char *module_name, const char *name, void *func) { - unsigned long index = get_module_index(module_name); - if (index == 0) - return; - - //LOGV("set_func %s %s %p", module_name, name, func); - - auto module = get_modules()->at(index - 1); - (*module->funcs)[name] = func; -} - -void riru_set_native_method_func(const char *module_name, const char *className, const char *name, - const char *signature, void *func) { - riru_set_func(module_name, (std::string(className) + name + signature).c_str(), func); -} -} diff --git a/riru-core/jni/main/api.h b/riru-core/jni/main/api.h deleted file mode 100644 index 955c0d4..0000000 --- a/riru-core/jni/main/api.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef RIRU_API_H -#define RIRU_API_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define EXPORT __attribute__((visibility("default"))) __attribute__((used)) - -int riru_get_version(void) EXPORT; - -void *riru_get_func(const char *module_name, const char *name) EXPORT; - -void *riru_get_native_method_func(const char *module_name, const char *className, const char *name, - const char *signature) EXPORT; - -void riru_set_func(const char *module_name, const char *name, void *func) EXPORT; - -void riru_set_native_method_func(const char *module_name, const char *className, const char *name, - const char *signature, void *func) EXPORT; - -const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, - const char *signature) EXPORT; - -int riru_is_zygote_methods_replaced() EXPORT; - -int riru_get_nativeForkAndSpecialize_calls_count() EXPORT; - -int riru_get_nativeForkSystemServer_calls_count() EXPORT; - -#ifdef __cplusplus -} -#endif - -#endif // RIRU_API_H diff --git a/riru-core/jni/main/jni_native_method.cpp b/riru-core/jni/main/jni_native_method.cpp deleted file mode 100644 index 5042034..0000000 --- a/riru-core/jni/main/jni_native_method.cpp +++ /dev/null @@ -1,431 +0,0 @@ -#include -#include -#include -#include - -#include "jni_native_method.h" -#include "logging.h" -#include "misc.h" -#include "module.h" -#include "api.h" - -static void *_nativeForkAndSpecialize = nullptr; -static void *_nativeSpecializeBlastula = nullptr; -static void *_nativeForkSystemServer = nullptr; -static void *_SystemProperties_set = nullptr; - -void set_nativeForkAndSpecialize(void *addr) { - _nativeForkAndSpecialize = addr; -} - -void set_nativeSpecializeBlastula(void *addr) { - _nativeSpecializeBlastula = addr; -} - -void set_nativeForkSystemServer(void *addr) { - _nativeForkSystemServer = addr; -} - -void set_SystemProperties_set(void *addr) { - _SystemProperties_set = addr; -} - -static int shouldSkipUid(int uid) { - int appId = uid % 100000; - - // limit only regular app, or strange situation will happen, such as zygote process not start (dead for no reason and leave no clues?) - // https://android.googlesource.com/platform/frameworks/base/+/android-9.0.0_r8/core/java/android/os/UserHandle.java#151 - if (appId >= 10000 && appId <= 19999) return 0; - return 1; -} - -int nativeForkAndSpecialize_calls_count = 0; - -int riru_get_nativeForkAndSpecialize_calls_count() { - return nativeForkAndSpecialize_calls_count; -} - -int nativeForkSystemServer_calls_count = 0; - -int riru_get_nativeForkSystemServer_calls_count() { - return nativeForkSystemServer_calls_count; -} - -// ----------------------------------------------------------------- - -static void nativeForkAndSpecialize_pre( - JNIEnv *env, jclass clazz, jint &uid, jint &gid, jintArray &gids, jint &runtime_flags, - jobjectArray &rlimits, jint &mount_external, jstring &se_info, jstring &se_name, - jintArray &fdsToClose, jintArray &fdsToIgnore, jboolean &is_child_zygote, - jstring &instructionSet, jstring &appDataDir, jstring &packageName, - jobjectArray &packagesForUID, jobjectArray &visibleVolIDs) { - - nativeForkAndSpecialize_calls_count++; - - for (auto module : *get_modules()) { - if (!module->forkAndSpecializePre) - continue; - - if (module->shouldSkipUid && ((shouldSkipUid_t) module->shouldSkipUid)(uid)) - continue; - - if (!module->shouldSkipUid && shouldSkipUid(uid)) - continue; - - if (module->apiVersion >= 3) { - ((nativeForkAndSpecialize_pre_v3_t) module->forkAndSpecializePre)( - env, clazz, &uid, &gid, &gids, &runtime_flags, &rlimits, &mount_external, - &se_info, &se_name, &fdsToClose, &fdsToIgnore, &is_child_zygote, - &instructionSet, &appDataDir, &packageName, &packagesForUID, &visibleVolIDs); - } else if (module->apiVersion == 2) { - ((nativeForkAndSpecialize_pre_v2_t) module->forkAndSpecializePre)( - env, clazz, &uid, &gid, &gids, &runtime_flags, &rlimits, &mount_external, - &se_info, &se_name, &fdsToClose, &fdsToIgnore, &is_child_zygote, - &instructionSet, &appDataDir); - } else { - ((nativeForkAndSpecialize_pre_t) module->forkAndSpecializePre)( - env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, - se_name, fdsToClose, fdsToIgnore, is_child_zygote, instructionSet, appDataDir); - } - } -} - -static void nativeForkAndSpecialize_post(JNIEnv *env, jclass clazz, jint uid, jint res) { - - for (auto module : *get_modules()) { - if (!module->forkAndSpecializePost) - continue; - - if (module->shouldSkipUid && ((shouldSkipUid_t) module->shouldSkipUid)(uid)) - continue; - - if (!module->shouldSkipUid && shouldSkipUid(uid)) - continue; - - /* - * Magic problem: - * There is very low change that zygote process stop working and some processes forked from zygote - * become zombie process. - * When the problem happens: - * The following log (%s: forkAndSpecializePost) is not printed - * strace zygote: futex(0x6265a70698, FUTEX_WAIT_BITSET_PRIVATE, 2, NULL, 0xffffffff - * zygote maps: 6265a70000-6265a71000 rw-p 00020000 103:04 1160 /system/lib64/liblog.so - * 6265a70698-6265a70000+20000 is nothing in liblog - * - * Don't known why, so we just don't print log in zygote and see what will happen - */ - if (res == 0) LOGV("%s: forkAndSpecializePost", module->name); - ((nativeForkAndSpecialize_post_t) module->forkAndSpecializePost)(env, clazz, res); - } -} - -// ----------------------------------------------------------------- - -static void nativeSpecializeBlastula_pre( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtimeFlags, - jobjectArray rlimits, jint mountExternal, jstring seInfo, jstring niceName, - jboolean startChildZygote, jstring instructionSet, jstring appDataDir, jstring packageName, - jobjectArray packagesForUID, jobjectArray visibleVolIDs) { - /*const char *cPackageName = env->GetStringUTFChars(packageName, nullptr); - LOGI("nativeSpecializeBlastulaPre: uid=%d, packageName=%s, from_uid=%d", uid, cPackageName, getuid()); - env->ReleaseStringUTFChars(packageName, cPackageName);*/ -} - -static void nativeSpecializeBlastula_post(JNIEnv *env, jclass clazz) { - //LOGI("nativeSpecializeBlastulaPost: from_uid=%d", getuid()); -} - -// ----------------------------------------------------------------- - -static void nativeForkSystemServer_pre( - JNIEnv *env, jclass clazz, uid_t &uid, gid_t &gid, jintArray &gids, jint &debug_flags, - jobjectArray &rlimits, jlong &permittedCapabilities, jlong &effectiveCapabilities) { - - nativeForkSystemServer_calls_count++; - - for (auto module : *get_modules()) { - if (!module->forkSystemServerPre) - continue; - - if (module->apiVersion >= 2) { - ((nativeForkSystemServer_pre_v2_t) module->forkSystemServerPre)( - env, clazz, &uid, &gid, &gids, &debug_flags, &rlimits, &permittedCapabilities, - &effectiveCapabilities); - } else { - ((nativeForkSystemServer_pre_t) module->forkSystemServerPre)( - env, clazz, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, - effectiveCapabilities); - } - } -} - -static void nativeForkSystemServer_post(JNIEnv *env, jclass clazz, jint res) { - for (auto module : *get_modules()) { - if (!module->forkSystemServerPost) - continue; - - if (res == 0) LOGV("%s: forkSystemServerPost", module->name); - ((nativeForkSystemServer_post_t) module->forkSystemServerPost)(env, clazz, res); - } -} - -// ----------------------------------------------------------------- - -jint nativeForkAndSpecialize_marshmallow( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jstring instructionSet, jstring appDataDir) { - - jintArray fdsToIgnore = nullptr; - jboolean is_child_zygote = JNI_FALSE; - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_marshmallow_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, se_info, se_name, - fdsToClose, instructionSet, appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_oreo( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jstring instructionSet, jstring appDataDir) { - - jboolean is_child_zygote = JNI_FALSE; - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_oreo_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, se_info, se_name, - fdsToClose, fdsToIgnore, instructionSet, appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_p( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir) { - - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_p_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, se_name, - fdsToClose, fdsToIgnore, is_child_zygote, instructionSet, appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_q( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir, jstring packageName, - jobjectArray packagesForUID, jobjectArray visibleVolIDs) { - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_q_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, se_name, - fdsToClose, fdsToIgnore, is_child_zygote, instructionSet, appDataDir, packageName, - packagesForUID, visibleVolIDs); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_samsung_p( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir) { - - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_samsung_p_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, runtime_flags, rlimits, mount_external, se_info, category, - accessInfo, se_name, fdsToClose, fdsToIgnore, is_child_zygote, instructionSet, - appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_samsung_o( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jintArray fdsToIgnore, jstring instructionSet, - jstring appDataDir) { - - jboolean is_child_zygote = JNI_FALSE; - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_samsung_o_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, se_info, category, - accessInfo, se_name, fdsToClose, fdsToIgnore, instructionSet, appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_samsung_n( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jstring instructionSet, jstring appDataDir, - jint a1) { - - jintArray fdsToIgnore = nullptr; - jboolean is_child_zygote = JNI_FALSE; - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_samsung_n_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, se_info, category, - accessInfo, se_name, fdsToClose, instructionSet, appDataDir, a1); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -jint nativeForkAndSpecialize_samsung_m( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jstring instructionSet, jstring appDataDir) { - - jintArray fdsToIgnore = nullptr; - jboolean is_child_zygote = JNI_FALSE; - jstring packageName = nullptr; - jobjectArray packagesForUID = nullptr; - jobjectArray visibleVolIDs = nullptr; - - nativeForkAndSpecialize_pre(env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, - se_info, se_name, fdsToClose, fdsToIgnore, is_child_zygote, - instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - jint res = ((nativeForkAndSpecialize_samsung_m_t) _nativeForkAndSpecialize)( - env, clazz, uid, gid, gids, debug_flags, rlimits, mount_external, se_info, category, - accessInfo, se_name, fdsToClose, instructionSet, appDataDir); - - nativeForkAndSpecialize_post(env, clazz, uid, res); - return res; -} - -// ----------------------------------------------------------------- - -void nativeSpecializeBlastula( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtimeFlags, - jobjectArray rlimits, jint mountExternal, jstring seInfo, jstring niceName, - jboolean startChildZygote, jstring instructionSet, jstring appDataDir, jstring packageName, - jobjectArray packagesForUID, jobjectArray visibleVolIDs) { - - nativeSpecializeBlastula_pre( - env, clazz, uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, - startChildZygote, instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - ((nativeSpecializeBlastula_t) _nativeSpecializeBlastula)( - env, clazz, uid, gid, gids, runtimeFlags, rlimits, mountExternal, seInfo, niceName, - startChildZygote, instructionSet, appDataDir, packageName, packagesForUID, - visibleVolIDs); - - nativeSpecializeBlastula_post(env, clazz); -} - -// ----------------------------------------------------------------- - -jint nativeForkSystemServer( - JNIEnv *env, jclass clazz, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities) { - - nativeForkSystemServer_pre( - env, clazz, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, - effectiveCapabilities); - - jint res = ((nativeForkSystemServer_t) _nativeForkSystemServer)( - env, clazz, uid, gid, gids, debug_flags, rlimits, permittedCapabilities, - effectiveCapabilities); - - nativeForkSystemServer_post(env, clazz, res); - return res; -} - -/* - * On Android 9+, in very rare cases, SystemProperties.set("sys.user." + userId + ".ce_available", "true") - * will throw an exception (we don't known if this is caused by Riru) and user data will be wiped. - * So we hook it and clear the exception to prevent this problem from happening. - * - * log: - * UserDataPreparer: Setting property: sys.user.0.ce_available=true - * PackageManager: Destroying user 0 on volume null because we failed to prepare: java.lang.RuntimeException: failed to set system property - * - * http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/pm/UserDataPreparer.java#107 - * -> http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/pm/UserDataPreparer.java#112 - * -> http://androidxref.com/9.0.0_r3/xref/system/vold/VoldNativeService.cpp#751 - * -> http://androidxref.com/9.0.0_r3/xref/system/vold/Ext4Crypt.cpp#743 - * -> http://androidxref.com/9.0.0_r3/xref/system/vold/Ext4Crypt.cpp#221 - */ -void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ, jstring valJ) { - const char *key = env->GetStringUTFChars(keyJ, JNI_FALSE); - char user[16]; - int no_throw = sscanf(key, "sys.user.%[^.].ce_available", user) == 1; - env->ReleaseStringUTFChars(keyJ, key); - - ((SystemProperties_set_t) _SystemProperties_set)(env, clazz, keyJ, valJ); - - jthrowable exception = env->ExceptionOccurred(); - if (exception && no_throw) { - LOGW("prevented data destroy"); - - env->ExceptionDescribe(); - env->ExceptionClear(); - } -} \ No newline at end of file diff --git a/riru-core/jni/main/jni_native_method.h b/riru-core/jni/main/jni_native_method.h deleted file mode 100644 index f3c6892..0000000 --- a/riru-core/jni/main/jni_native_method.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef _JNI_NATIVE_METHOD_H -#define _JNI_NATIVE_METHOD_H - -#include - -void set_nativeForkAndSpecialize(void *addr); - -void set_nativeSpecializeBlastula(void *addr); - -void set_nativeForkSystemServer(void *addr); - -void set_SystemProperties_set(void *addr); - -const static char *nativeForkAndSpecialize_marshmallow_sig = "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_marshmallow_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jstring, - jintArray, jstring, jstring); - -jint nativeForkAndSpecialize_marshmallow( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jstring instructionSet, jstring appDataDir); - -const static char *nativeForkAndSpecialize_oreo_sig = "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_oreo_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jstring, - jintArray, jintArray, jstring, jstring); - -jint nativeForkAndSpecialize_oreo( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jstring instructionSet, jstring appDataDir); - -const static char *nativeForkAndSpecialize_p_sig = "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_p_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jstring, - jintArray, jintArray, jboolean, jstring, jstring); - -jint nativeForkAndSpecialize_p( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir); - -const static char *nativeForkAndSpecialize_q_sig = "(II[II[[IILjava/lang/String;Ljava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_q_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jstring, - jintArray, jintArray, jboolean, jstring, jstring, jstring, jobjectArray, jobjectArray); - -jint nativeForkAndSpecialize_q( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jstring se_name, - jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir, jstring packageName, - jobjectArray packagesForUID, jobjectArray visibleVolIDs); - -const static char *nativeForkAndSpecialize_samsung_p_sig = "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[IZLjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_samsung_p_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jint, jint, - jstring, jintArray, jintArray, jboolean, jstring, jstring); - -jint nativeForkAndSpecialize_samsung_p( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtime_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jintArray fdsToIgnore, jboolean is_child_zygote, - jstring instructionSet, jstring appDataDir); - -const static char *nativeForkAndSpecialize_samsung_o_sig = "(II[II[[IILjava/lang/String;IILjava/lang/String;[I[ILjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_samsung_o_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jint, jint, - jstring, jintArray, jintArray, jstring, jstring); - -jint nativeForkAndSpecialize_samsung_o( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jintArray fdsToIgnore, jstring instructionSet, - jstring appDataDir); - -const static char *nativeForkAndSpecialize_samsung_n_sig = "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;I)I"; - -typedef jint (*nativeForkAndSpecialize_samsung_n_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jint, jint, - jstring, jintArray, jstring, jstring, jint); - -jint nativeForkAndSpecialize_samsung_n( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jstring instructionSet, jstring appDataDir, jint); - -const static char *nativeForkAndSpecialize_samsung_m_sig = "(II[II[[IILjava/lang/String;IILjava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I"; - -typedef jint (*nativeForkAndSpecialize_samsung_m_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jint, jint, - jstring, jintArray, jstring, jstring); - -jint nativeForkAndSpecialize_samsung_m( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jint mount_external, jstring se_info, jint category, jint accessInfo, - jstring se_name, jintArray fdsToClose, jstring instructionSet, jstring appDataDir); - -// ----------------------------------------------------------------- - -const static char *nativeSpecializeBlastula_sig = "(II[II[[IILjava/lang/String;Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)V"; - -typedef void (*nativeSpecializeBlastula_t)( - JNIEnv *, jclass, jint, jint, jintArray, jint, jobjectArray, jint, jstring, jstring, - jboolean, jstring, jstring, jstring, jobjectArray, jobjectArray); - -void nativeSpecializeBlastula( - JNIEnv *env, jclass clazz, jint uid, jint gid, jintArray gids, jint runtimeFlags, - jobjectArray rlimits, jint mountExternal, jstring seInfo, jstring niceName, - jboolean startChildZygote, jstring instructionSet, jstring appDataDir, jstring packageName, - jobjectArray packagesForUID, jobjectArray visibleVolIDs); - -// ----------------------------------------------------------------- - -const static char *nativeForkSystemServer_sig = "(II[II[[IJJ)I"; - -typedef jint (*nativeForkSystemServer_t)( - JNIEnv *, jclass, uid_t, gid_t, jintArray, jint, jobjectArray, jlong, jlong); - -jint nativeForkSystemServer( - JNIEnv *env, jclass, uid_t uid, gid_t gid, jintArray gids, jint debug_flags, - jobjectArray rlimits, jlong permittedCapabilities, jlong effectiveCapabilities); - -typedef jint (*SystemProperties_set_t)(JNIEnv *, jobject, jstring, jstring); - -void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ, jstring valJ); - -#endif // _JNI_NATIVE_METHOD_H diff --git a/riru-core/jni/main/logging.h b/riru-core/jni/main/logging.h deleted file mode 100644 index 7462723..0000000 --- a/riru-core/jni/main/logging.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef LOGGING_H -#define LOGGING_H - -#include -#include "android/log.h" - -#ifndef LOG_TAG -#define LOG_TAG "Riru" -#endif - -#ifdef DEBUG -#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) -#else -#define LOGD(...) -#endif -#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, 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__) -#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) - -#endif // LOGGING_H diff --git a/riru-core/jni/main/main.cpp b/riru-core/jni/main/main.cpp deleted file mode 100644 index 4b3e7af..0000000 --- a/riru-core/jni/main/main.cpp +++ /dev/null @@ -1,329 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "misc.h" -#include "jni_native_method.h" -#include "logging.h" -#include "wrap.h" -#include "module.h" -#include "JNIHelper.h" -#include "api.h" - -#define CONFIG_DIR "/data/misc/riru" - -#ifdef __LP64__ -#define MODULE_PATH_FMT "/system/lib64/libriru_%s.so" -#else -#define MODULE_PATH_FMT "/system/lib/libriru_%s.so" -#endif - -static int methods_replaced = 0; -static int sdkLevel; -static char androidVersionName[PROP_VALUE_MAX + 1]; - -int riru_is_zygote_methods_replaced() { - return methods_replaced; -} - -static int isQ() { - return strcmp("Q", androidVersionName) == 0 || sdkLevel >= 29; -} - -static void load_modules() { - DIR *dir; - struct dirent *entry; - char path[PATH_MAX], module_prop[PATH_MAX], api[PATH_MAX]; - int moduleApiVersion; - void *handle; - - if (!(dir = _opendir(CONFIG_DIR "/modules"))) - return; - - while ((entry = _readdir(dir))) { - if (entry->d_type == DT_DIR) { - if (entry->d_name[0] == '.') - continue; - - snprintf(path, PATH_MAX, MODULE_PATH_FMT, entry->d_name); - - if (access(path, F_OK) != 0) { - PLOGE("access %s", path); - continue; - } - - snprintf(module_prop, PATH_MAX, CONFIG_DIR "/modules/%s/module.prop", entry->d_name); - if (access(module_prop, F_OK) != 0) { - PLOGE("access %s", module_prop); - continue; - } - - moduleApiVersion = -1; - if (get_prop(module_prop, "api", api) > 0) { - moduleApiVersion = atoi(api); - } - - if (isQ() && moduleApiVersion < 3) { - LOGW("module %s does not support Android Q", entry->d_name); - continue; - } - - handle = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (!handle) { - PLOGE("dlopen %s", path); - continue; - } - - auto *module = new struct module(strdup(entry->d_name)); - module->handle = handle; - module->onModuleLoaded = dlsym(handle, "onModuleLoaded"); - module->forkAndSpecializePre = dlsym(handle, "nativeForkAndSpecializePre"); - module->forkAndSpecializePost = dlsym(handle, "nativeForkAndSpecializePost"); - module->forkSystemServerPre = dlsym(handle, "nativeForkSystemServerPre"); - module->forkSystemServerPost = dlsym(handle, "nativeForkSystemServerPost"); - module->shouldSkipUid = dlsym(handle, "shouldSkipUid"); - get_modules()->push_back(module); - - if (moduleApiVersion == -1) { - // only for api v2 - module->getApiVersion = dlsym(handle, "getApiVersion"); - - if (module->getApiVersion) { - module->apiVersion = ((getApiVersion_t) module->getApiVersion)(); - } - } else { - module->apiVersion = moduleApiVersion; - } - - void *sym = dlsym(handle, "riru_set_module_name"); - if (sym) - ((void (*)(const char *)) sym)(module->name); - -#ifdef __LP64__ - LOGI("module loaded: %s (api %d)", module->name, module->apiVersion); -#else - LOGI("module loaded: %s %u", module->name, get_modules()->size()); -#endif - - if (module->onModuleLoaded) { - LOGV("%s: onModuleLoaded", module->name); - - ((loaded_t) module->onModuleLoaded)(); - } - } - } - - closedir(dir); -} - -static JNINativeMethod *onRegisterZygote(JNIEnv *env, const char *className, - const JNINativeMethod *methods, int numMethods) { - int replaced = 0; - - auto *newMethods = new JNINativeMethod[numMethods]; - memcpy(newMethods, methods, sizeof(JNINativeMethod) * numMethods); - - JNINativeMethod method; - for (int i = 0; i < numMethods; ++i) { - method = methods[i]; - - if (strcmp(method.name, "nativeForkAndSpecialize") == 0) { - set_nativeForkAndSpecialize(method.fnPtr); - - if (strcmp(nativeForkAndSpecialize_marshmallow_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_marshmallow; - else if (strcmp(nativeForkAndSpecialize_oreo_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_oreo; - else if (strcmp(nativeForkAndSpecialize_p_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_p; - else if (strcmp(nativeForkAndSpecialize_q_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_q; - else if (strcmp(nativeForkAndSpecialize_samsung_p_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_samsung_p; - else if (strcmp(nativeForkAndSpecialize_samsung_o_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_samsung_o; - else if (strcmp(nativeForkAndSpecialize_samsung_n_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_samsung_n; - else if (strcmp(nativeForkAndSpecialize_samsung_m_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkAndSpecialize_samsung_m; - else - LOGW("found nativeForkAndSpecialize but signature %s mismatch", method.signature); - - if (newMethods[i].fnPtr != methods[i].fnPtr) { - LOGI("replaced com.android.internal.os.Zygote#nativeForkAndSpecialize"); - riru_set_native_method_func(MODULE_NAME_CORE, className, newMethods[i].name, - newMethods[i].signature, newMethods[i].fnPtr); - - replaced += 1; - } - } else if (strcmp(method.name, "nativeSpecializeBlastula") == 0) { - set_nativeSpecializeBlastula(method.fnPtr); - - if (strcmp(nativeSpecializeBlastula_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeSpecializeBlastula; - else - LOGW("found nativeSpecializeBlastula but signature %s mismatch", method.signature); - - if (newMethods[i].fnPtr != methods[i].fnPtr) { - LOGI("replaced com.android.internal.os.Zygote#nativeSpecializeBlastula"); - riru_set_native_method_func(MODULE_NAME_CORE, className, newMethods[i].name, - newMethods[i].signature, newMethods[i].fnPtr); - - //replaced += 1; - } - } else if (strcmp(method.name, "nativeForkSystemServer") == 0) { - set_nativeForkSystemServer(method.fnPtr); - - if (strcmp(nativeForkSystemServer_sig, method.signature) == 0) - newMethods[i].fnPtr = (void *) nativeForkSystemServer; - else - LOGW("found nativeForkSystemServer but signature %s mismatch", method.signature); - - if (newMethods[i].fnPtr != methods[i].fnPtr) { - LOGI("replaced com.android.internal.os.Zygote#nativeForkSystemServer"); - riru_set_native_method_func(MODULE_NAME_CORE, className, newMethods[i].name, - newMethods[i].signature, newMethods[i].fnPtr); - - replaced += 1; - } - } - } - - methods_replaced = replaced == 2/*(isQ() ? 3 : 2)*/; - - return newMethods; -} - -static JNINativeMethod *onRegisterSystemProperties(JNIEnv *env, const char *className, - const JNINativeMethod *methods, int numMethods) { - auto *newMethods = new JNINativeMethod[numMethods]; - memcpy(newMethods, methods, sizeof(JNINativeMethod) * numMethods); - - JNINativeMethod method; - for (int i = 0; i < numMethods; ++i) { - method = methods[i]; - - if (strcmp(method.name, "native_set") == 0) { - set_SystemProperties_set(method.fnPtr); - - if (strcmp("(Ljava/lang/String;Ljava/lang/String;)V", method.signature) == 0) - newMethods[i].fnPtr = (void *) SystemProperties_set; - else - LOGW("found native_set but signature %s mismatch", method.signature); - - if (newMethods[i].fnPtr != methods[i].fnPtr) { - LOGI("replaced android.os.SystemProperties#native_set"); - - riru_set_native_method_func(MODULE_NAME_CORE, className, newMethods[i].name, - newMethods[i].signature, newMethods[i].fnPtr); - } - } - } - return newMethods; -} - -#define XHOOK_REGISTER(PATH_REGEX, NAME) \ - if (xhook_register(PATH_REGEX, #NAME, (void*) new_##NAME, (void **) &old_##NAME) != 0) \ - LOGE("failed to register hook " #NAME "."); \ - -#define NEW_FUNC_DEF(ret, func, ...) \ - static ret (*old_##func)(__VA_ARGS__); \ - static ret new_##func(__VA_ARGS__) - -NEW_FUNC_DEF(int, jniRegisterNativeMethods, JNIEnv *env, const char *className, - const JNINativeMethod *methods, int numMethods) { - put_native_method(className, methods, numMethods); - - LOGV("jniRegisterNativeMethods %s", className); - - JNINativeMethod *newMethods = nullptr; - if (strcmp("com/android/internal/os/Zygote", className) == 0) { - newMethods = onRegisterZygote(env, className, methods, numMethods); - } else if (strcmp("android/os/SystemProperties", className) == 0) { - // hook android.os.SystemProperties#native_set to prevent a critical problem on Android 9+ - // see comment of SystemProperties_set in jni_native_method.cpp for detail - newMethods = onRegisterSystemProperties(env, className, methods, numMethods); - } - - int res = old_jniRegisterNativeMethods(env, className, newMethods ? newMethods : methods, - numMethods); - delete newMethods; - return res; -} - -void unhook_jniRegisterNativeMethods() { - xhook_register(".*\\libandroid_runtime.so$", "jniRegisterNativeMethods", - (void *) old_jniRegisterNativeMethods, - nullptr); - if (xhook_refresh(0) == 0) { - xhook_clear(); - LOGI("hook removed"); - } -} - -static void read_prop() { - char sdk[PROP_VALUE_MAX + 1]; - if (__system_property_get("ro.build.version.sdk", sdk) > 0) - sdkLevel = atoi(sdk); - - __system_property_get("ro.build.version.release", androidVersionName); - - LOGI("system version %s (api %d)", androidVersionName, sdkLevel); -} - -extern "C" void constructor() __attribute__((constructor)); - -void constructor() { - static int loaded = 0; - if (loaded) - return; - - loaded = 1; - - if (getuid() != 0) - return; - - char cmdline[ARG_MAX + 1]; - get_self_cmdline(cmdline); - - if (!strstr(cmdline, "--zygote")) - return; - -#ifdef __LP64__ - LOGI("riru in zygote64"); -#else - LOGI("riru in zygote"); -#endif - - if (access(CONFIG_DIR "/.disable", F_OK) == 0) { - LOGI(CONFIG_DIR - "/.disable exists, do nothing."); - return; - } - - read_prop(); - - XHOOK_REGISTER(".*\\libandroid_runtime.so$", jniRegisterNativeMethods); - - if (xhook_refresh(0) == 0) { - xhook_clear(); - LOGI("hook installed"); - } else { - LOGE("failed to refresh hook"); - } - - load_modules(); -} \ No newline at end of file diff --git a/riru-core/jni/main/main.h b/riru-core/jni/main/main.h deleted file mode 100644 index d08e5c9..0000000 --- a/riru-core/jni/main/main.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _MAIN_H -#define _MAIN_H - -void unhook_jniRegisterNativeMethods(); - -#endif // _MAIN_H diff --git a/riru-core/jni/main/misc.cpp b/riru-core/jni/main/misc.cpp deleted file mode 100644 index b541c6a..0000000 --- a/riru-core/jni/main/misc.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "wrap.h" - -ssize_t fdgets(char *buf, size_t size, int fd) { - ssize_t len = 0; - buf[0] = '\0'; - while (len < size - 1) { - ssize_t ret = read(fd, buf + len, 1); - if (ret < 0) - return -1; - if (ret == 0) - break; - if (buf[len] == '\0' || buf[len++] == '\n') { - break; - } - } - buf[len] = '\0'; - buf[size - 1] = '\0'; - return len; -} - -ssize_t get_self_cmdline(char *cmdline) { - int fd; - ssize_t size; - - char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "/proc/self/cmdline"); - if (access(buf, R_OK) == -1 || (fd = open(buf, O_RDONLY)) == -1) - return 1; - - if ((size = read(fd, cmdline, ARG_MAX)) > 0) { - for (ssize_t i = 0; i < size - 1; ++i) { - if (cmdline[i] == 0) - cmdline[i] = ' '; - } - } else { - cmdline[0] = 0; - } - - close(fd); - return size; -} - -char *trim(char *str) { - size_t len = 0; - char *frontp = str; - char *endp = nullptr; - - if (str == nullptr) { return nullptr; } - if (str[0] == '\0') { return str; } - - len = strlen(str); - endp = str + len; - - /* Move the front and back pointers to address the first non-whitespace - * characters from each end. - */ - while (isspace((unsigned char) *frontp)) { ++frontp; } - if (endp != frontp) { - while (isspace((unsigned char) *(--endp)) && endp != frontp) {} - } - - if (str + len - 1 != endp) - *(endp + 1) = '\0'; - else if (frontp != str && endp == frontp) - *str = '\0'; - - /* Shift the string so that it starts at str so that if it's dynamically - * allocated, we can still free it on the returned pointer. Note the reuse - * of endp to mean the front of the string buffer now. - */ - endp = str; - if (frontp != str) { - while (*frontp) { *endp++ = *frontp++; } - *endp = '\0'; - } - - return str; -} - -int get_prop(const char *file, const char *key, char *value) { - int fd = open(file, O_RDONLY); - if (fd == -1) - return -1; - - char buf[512]; - char *trimmed, *_key, *_value; - while (fdgets(buf, 512, fd) > 0) { - if (*buf == 0 || *buf == '#' || !strstr(buf, "=")) - continue; - - trimmed = trim(buf); - - _value = trimmed; - _key = strsep(&_value, "="); - if (!_key) - continue; - - if (strcmp(key, _key) == 0) { - strcpy(value, _value); - close(fd); - return static_cast(strlen(value)); - } - } - close(fd); - return -1; -} \ No newline at end of file diff --git a/riru-core/jni/main/misc.h b/riru-core/jni/main/misc.h deleted file mode 100644 index de3758d..0000000 --- a/riru-core/jni/main/misc.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _MISC_H -#define _MISC_H - -#include -#include - -ssize_t fdgets(char *buf, size_t size, int fd); -ssize_t get_self_cmdline(char *cmdline); -char *trim(char *str); -int get_prop(const char *file, const char *key, char *value); - -#endif // _MISC_H diff --git a/riru-core/jni/main/module.h b/riru-core/jni/main/module.h deleted file mode 100644 index 2655054..0000000 --- a/riru-core/jni/main/module.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef MODULE_H -#define MODULE_H - -#include -#include -#include - -#define MODULE_NAME_CORE "core" - -typedef void (*loaded_t)(); - -typedef void (*nativeForkAndSpecialize_pre_t)(JNIEnv *, jclass, jint, jint, jintArray, jint, - jobjectArray, jint, jstring, jstring, jintArray, - jintArray, jboolean, jstring, jstring); - -typedef void (*nativeForkAndSpecialize_pre_v2_t)(JNIEnv *, jclass, jint *, jint *, jintArray *, - jint *, jobjectArray *, jint *, jstring *, - jstring *, jintArray *, jintArray *, jboolean *, - jstring *, jstring *); - -typedef void (*nativeForkAndSpecialize_pre_v3_t)(JNIEnv *, jclass, jint *, jint *, jintArray *, - jint *, jobjectArray *, jint *, jstring *, - jstring *, jintArray *, jintArray *, jboolean *, - jstring *, jstring *, jstring *, jobjectArray *, - jobjectArray *); - -typedef int (*nativeForkAndSpecialize_post_t)(JNIEnv *, jclass, jint); - -typedef void (*nativeForkSystemServer_pre_t)(JNIEnv *, jclass, uid_t, gid_t, jintArray, - jint, jobjectArray, jlong, jlong); - -typedef void (*nativeForkSystemServer_pre_v2_t)(JNIEnv *, jclass, uid_t *, gid_t *, jintArray *, - jint *, jobjectArray *, jlong *, jlong *); - -typedef int (*nativeForkSystemServer_post_t)(JNIEnv *, jclass, jint); - -typedef int (*shouldSkipUid_t)(int); - -typedef int (*getApiVersion_t)(); - -struct module { - void *handle{}; - char *name; - void *onModuleLoaded{}; - void *forkAndSpecializePre{}; - void *forkAndSpecializePost{}; - void *forkSystemServerPre{}; - void *forkSystemServerPost{}; - void *shouldSkipUid{}; - void *getApiVersion{}; - int apiVersion = 0; - std::map *funcs; - - explicit module(char *name) : name(name) { - funcs = new std::map(); - } -}; - -std::vector *get_modules(); - -void put_native_method(const char *className, const JNINativeMethod *methods, int numMethods); - -#endif // MODULE_H diff --git a/riru-core/jni/main/redirect_memtrack.cpp b/riru-core/jni/main/redirect_memtrack.cpp deleted file mode 100644 index fd81daf..0000000 --- a/riru-core/jni/main/redirect_memtrack.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include -#include - -#ifdef __LP64__ -#define MEMTRACK_LIBRARY "/system/lib64/libmemtrack_real.so" -#else -#define MEMTRACK_LIBRARY "/system/lib/libmemtrack_real.so" -#endif - -extern "C" { -static void *handle = dlopen(MEMTRACK_LIBRARY, RTLD_NOW | RTLD_GLOBAL); - -#define FUNC_DEF(NAME, RET, ...) \ - static void* sym_##NAME = handle ? dlsym(handle, #NAME) : NULL; \ - typedef RET (* NAME##_t)(__VA_ARGS__); \ - __attribute__((visibility("default"))) RET NAME(__VA_ARGS__) - -FUNC_DEF(memtrack_init, int) {// pre-Oreo - if (!sym_memtrack_init) - return -1; - - return ((memtrack_init_t) sym_memtrack_init)(); -} - -FUNC_DEF(memtrack_proc_destroy, void, struct memtrack_proc *p) { - if (!sym_memtrack_proc_destroy) - return; - - ((memtrack_proc_destroy_t) sym_memtrack_proc_destroy)(p); -} - -FUNC_DEF(memtrack_proc_get, int, struct memtrack_proc *p, pid_t pid) { - if (!sym_memtrack_proc_get) - return -1; - - return ((memtrack_proc_get_t) sym_memtrack_proc_get)(p, pid); -} - -FUNC_DEF(memtrack_proc_gl_pss, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_gl_pss) - return 0; - - return ((memtrack_proc_gl_pss_t) sym_memtrack_proc_gl_pss)(p); -} - -FUNC_DEF(memtrack_proc_gl_total, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_gl_total) - return 0; - - return ((memtrack_proc_gl_total_t) sym_memtrack_proc_gl_total)(p); -} - -FUNC_DEF(memtrack_proc_graphics_pss, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_graphics_pss) - return 0; - - return ((memtrack_proc_graphics_pss_t) sym_memtrack_proc_graphics_pss)(p); -} - -FUNC_DEF(memtrack_proc_graphics_total, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_graphics_total) - return 0; - - return ((memtrack_proc_graphics_total_t) sym_memtrack_proc_graphics_total)(p); -} - -FUNC_DEF(memtrack_proc_new, struct memtrack_proc *) { - if (!sym_memtrack_proc_new) - return NULL; - - return ((memtrack_proc_new_t) sym_memtrack_proc_new)(); -} - -FUNC_DEF(memtrack_proc_other_pss, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_other_pss) - return 0; - - return ((memtrack_proc_other_pss_t) sym_memtrack_proc_other_pss)(p); -} - -FUNC_DEF(memtrack_proc_other_total, ssize_t, struct memtrack_proc *p) { - if (!sym_memtrack_proc_other_total) - return 0; - - return ((memtrack_proc_other_total_t) sym_memtrack_proc_other_total)(p); -} - -FUNC_DEF(_ZN7android2spINS_8hardware8memtrack4V1_09IMemtrackEED2Ev, void, int a1) { - if (!sym__ZN7android2spINS_8hardware8memtrack4V1_09IMemtrackEED2Ev) - return; - - return ((_ZN7android2spINS_8hardware8memtrack4V1_09IMemtrackEED2Ev_t) sym__ZN7android2spINS_8hardware8memtrack4V1_09IMemtrackEED2Ev)( - a1); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEm, void, int *a1, int a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEm) - return; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEm_t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEm)(a1, a2); -} - -FUNC_DEF(_ZNSt3__114__split_bufferIN7android8hardware8memtrack4V1_014MemtrackRecordERNS_9allocatorIS5_EEEC2EjjS8_, int, uint a1, uint a2, void *a3) { - if (!sym__ZNSt3__114__split_bufferIN7android8hardware8memtrack4V1_014MemtrackRecordERNS_9allocatorIS5_EEEC2EjjS8_) - return 0; - - return ((_ZNSt3__114__split_bufferIN7android8hardware8memtrack4V1_014MemtrackRecordERNS_9allocatorIS5_EEEC2EjjS8__t) sym__ZNSt3__114__split_bufferIN7android8hardware8memtrack4V1_014MemtrackRecordERNS_9allocatorIS5_EEEC2EjjS8_)(a1, a2, a3); -} - -FUNC_DEF(_ZNSt3__113__vector_baseIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEED2Ev, void, void **a1) { - if (!sym__ZNSt3__113__vector_baseIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEED2Ev) - return; - - return ((_ZNSt3__113__vector_baseIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEED2Ev_t) sym__ZNSt3__113__vector_baseIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEED2Ev)(a1); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEj, int, int a1, uint a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEj) - return 0; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEj_t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8__appendEj)(a1, a2); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE26__swap_out_circular_bufferERNS_14__split_bufferIS5_RS7_EE, int, int *a1, void *a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE26__swap_out_circular_bufferERNS_14__split_bufferIS5_RS7_EE) - return 0; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE26__swap_out_circular_bufferERNS_14__split_bufferIS5_RS7_EE_t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE26__swap_out_circular_bufferERNS_14__split_bufferIS5_RS7_EE)(a1, a2); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8allocateEj, int, void *a1, uint a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8allocateEj) - return 0; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8allocateEj_t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE8allocateEj)(a1, a2); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE6resizeEj, int, int a1, uint a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE6resizeEj) - return 0; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE6resizeEj_t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEE6resizeEj)(a1, a2); -} - -FUNC_DEF(_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEEC2ERKS8_, int, void *a1, void *a2) { - if (!sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEEC2ERKS8_) - return 0; - - return ((_ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEEC2ERKS8__t) sym__ZNSt3__16vectorIN7android8hardware8memtrack4V1_014MemtrackRecordENS_9allocatorIS5_EEEC2ERKS8_)(a1, a2); -} - -struct memtrack_proc; -} \ No newline at end of file diff --git a/riru-core/jni/main/version.cpp b/riru-core/jni/main/version.cpp deleted file mode 100644 index a8c6ccf..0000000 --- a/riru-core/jni/main/version.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "api.h" - -#define VERSION 19 - -extern "C" { -int riru_get_version(void) { - return VERSION; -} -} \ No newline at end of file diff --git a/riru-core/jni/main/wrap.cpp b/riru-core/jni/main/wrap.cpp deleted file mode 100644 index 267e892..0000000 --- a/riru-core/jni/main/wrap.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "logging.h" -#include "misc.h" - -DIR* _opendir(const char *path) -{ - DIR *d = opendir(path); - if (d == NULL) { - PLOGE("opendir %s", path); - } - return d; -} - -struct dirent *_readdir(DIR *dir) -{ - errno = 0; - struct dirent *ent = readdir(dir); - if (errno && ent == NULL) { - PLOGE("readdir"); - } - return ent; -} \ No newline at end of file diff --git a/riru-core/jni/main/wrap.h b/riru-core/jni/main/wrap.h deleted file mode 100644 index c04c542..0000000 --- a/riru-core/jni/main/wrap.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _WRAP_H -#define _WRAP_H - -#include - -DIR* _opendir(const char *path); - -struct dirent *_readdir(DIR* dir); - -#endif // _WRAP_H diff --git a/riru-core/jni/zygote_restart/Android.mk b/riru-core/jni/zygote_restart/Android.mk deleted file mode 100644 index 4e8b943..0000000 --- a/riru-core/jni/zygote_restart/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := zygote_restart -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH) -LOCAL_LDLIBS += -ldl -llog -LOCAL_LDFLAGS := -Wl,--hash-style=both - -LOCAL_SRC_FILES:= main.cpp pmparser.c - -include $(BUILD_EXECUTABLE) \ No newline at end of file diff --git a/riru-core/jni/zygote_restart/main.cpp b/riru-core/jni/zygote_restart/main.cpp deleted file mode 100644 index 8eed9cc..0000000 --- a/riru-core/jni/zygote_restart/main.cpp +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "pmparser.h" -} - -#ifdef __LP64__ -#define CHECK_LIB_NAME "/system/lib64/libmemtrack_real.so" -#define ZYGOTE_NAME "zygote64" -#define RESTART_NAME "zygote_secondary" -#else -#define CHECK_LIB_NAME "/system/lib/libmemtrack_real.so" -#define ZYGOTE_NAME "zygote" -#define RESTART_NAME "zygote" -#endif - -#define LOG_TAG "Riru" - -#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, 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__) -#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) - -static ssize_t fdgets(char *buf, const size_t size, int fd) { - ssize_t len = 0; - buf[0] = '\0'; - while (len < size - 1) { - ssize_t ret = read(fd, buf + len, 1); - if (ret < 0) - return -1; - if (ret == 0) - break; - if (buf[len] == '\0' || buf[len++] == '\n') { - buf[len] = '\0'; - break; - } - } - buf[len] = '\0'; - buf[size - 1] = '\0'; - return len; -} - -static int is_proc_name_equals(int pid, const char *name) { - int fd; - - char buf[1024]; - snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); - if (access(buf, R_OK) == -1 || (fd = open(buf, O_RDONLY)) == -1) - return 0; - if (fdgets(buf, sizeof(buf), fd) == 0) { - snprintf(buf, sizeof(buf), "/proc/%d/comm", pid); - close(fd); - if (access(buf, R_OK) == -1 || (fd = open(buf, O_RDONLY)) == -1) - return 0; - fdgets(buf, sizeof(buf), fd); - } - close(fd); - - return strcmp(buf, name) == 0; -} - -static int is_num(const char *s) { - size_t len = strlen(s); - for (size_t i = 0; i < len; ++i) - if (s[i] < '0' || s[i] > '9') - return 0; - return 1; -} - -static pid_t get_pid_by_name_and_uid(const char *name, uid_t uid) { - DIR *dir; - struct dirent *entry; - - if (!(dir = opendir("/proc"))) - return -1; - - struct stat st; - char path[32]; - - while ((entry = readdir(dir))) { - if (entry->d_type == DT_DIR) { - if (is_num(entry->d_name)) { - pid_t pid = atoi(entry->d_name); - if (is_proc_name_equals(pid, name)) { - sprintf(path, "/proc/%s", entry->d_name); - stat(path, &st); - if (uid == st.st_uid) - return pid; - } - } - } - } - - closedir(dir); - return -1; -} - -static int is_path_in_maps(int pid, const char *path) { - procmaps_iterator *maps = pmparser_parse(pid); - if (maps == nullptr) { - LOGE("[map]: cannot parse the memory map of %d", pid); - return false; - } - - procmaps_struct *maps_tmp = nullptr; - while ((maps_tmp = pmparser_next(maps)) != nullptr) { - if (strstr(maps_tmp->pathname, path)) - return true; - } - pmparser_free(maps); - return false; -} - -int main(int argc, char **argv) { - if (fork() != 0) - return 1; - - pid_t pid; - while ((pid = get_pid_by_name_and_uid(ZYGOTE_NAME, 0)) == -1) { - LOGV(ZYGOTE_NAME " not started, wait 1s"); - sleep(1); - } - - if (!is_path_in_maps(pid, CHECK_LIB_NAME)) { - LOGW("no Riru found in %s (pid=%d), restart required", ZYGOTE_NAME, pid); - } else { - LOGI("found Riru in %s (pid=%d)", ZYGOTE_NAME, pid); - return 0; - } - - // wait for magisk mount - while (access(CHECK_LIB_NAME, F_OK) != 0) { - LOGV("not mounted, wait 1s"); - sleep(1); - } - - // check if zygote is restarted by other - if ((pid = get_pid_by_name_and_uid(ZYGOTE_NAME, 0)) != -1 - && is_path_in_maps(pid, CHECK_LIB_NAME)) { - LOGI("found Riru in %s (pid=%d), abort restart", ZYGOTE_NAME, pid); - return 0; - } - - LOGI("restart " RESTART_NAME); - // restart zygote_secondary will also restart zygote, see init.zygote64_32.rc - __system_property_set("ctl.restart", const_cast(RESTART_NAME)); - - return 0; -} \ No newline at end of file diff --git a/riru-core/jni/zygote_restart/pmparser.c b/riru-core/jni/zygote_restart/pmparser.c deleted file mode 100644 index a07bf34..0000000 --- a/riru-core/jni/zygote_restart/pmparser.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - @Author : ouadimjamal@gmail.com - @date : December 2015 - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. No representations are made about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. -*/ - -#include "pmparser.h" - -/** - * gobal variables - */ -//procmaps_struct* g_last_head=NULL; -//procmaps_struct* g_current=NULL; - -#include "android/log.h" - -#define printf(...) __android_log_print(ANDROID_LOG_DEBUG, "TAG", __VA_ARGS__); - -procmaps_iterator* pmparser_parse(int pid){ - procmaps_iterator* maps_it = malloc(sizeof(procmaps_iterator)); - char maps_path[500]; - if(pid>=0 ){ - sprintf(maps_path,"/proc/%d/maps",pid); - }else{ - sprintf(maps_path,"/proc/self/maps"); - } - FILE* file=fopen(maps_path,"r"); - if(!file){ - fprintf(stderr,"pmparser : cannot open the memory maps, %s\n",strerror(errno)); - return NULL; - } - int ind=0;char buf[PROCMAPS_LINE_MAX_LENGTH]; - int c; - procmaps_struct* list_maps=NULL; - procmaps_struct* tmp; - procmaps_struct* current_node=list_maps; - char addr1[20],addr2[20], perm[8], offset[20], dev[10],inode[30],pathname[PATH_MAX]; - while( !feof(file) ){ - fgets(buf,PROCMAPS_LINE_MAX_LENGTH,file); - //allocate a node - tmp=(procmaps_struct*)malloc(sizeof(procmaps_struct)); - //fill the node - _pmparser_split_line(buf,addr1,addr2,perm,offset, dev,inode,pathname); - //printf("#%s",buf); - //printf("%s-%s %s %s %s %s\t%s\n",addr1,addr2,perm,offset,dev,inode,pathname); - //addr_start & addr_end - unsigned long l_addr_start; - sscanf(addr1,"%lx",(long unsigned *)&tmp->addr_start ); - sscanf(addr2,"%lx",(long unsigned *)&tmp->addr_end ); - //size - tmp->length=(unsigned long)(tmp->addr_end-tmp->addr_start); - //perm - strcpy(tmp->perm,perm); - tmp->is_r=(perm[0]=='r'); - tmp->is_w=(perm[1]=='w'); - tmp->is_x=(perm[2]=='x'); - tmp->is_p=(perm[3]=='p'); - - //offset - sscanf(offset,"%lx",&tmp->offset ); - //device - strcpy(tmp->dev,dev); - //inode - tmp->inode=atoi(inode); - //pathname - strcpy(tmp->pathname,pathname); - tmp->next=NULL; - //attach the node - if(ind==0){ - list_maps=tmp; - list_maps->next=NULL; - current_node=list_maps; - } - current_node->next=tmp; - current_node=tmp; - ind++; - //printf("%s",buf); - } - - //close file - fclose(file); - - - //g_last_head=list_maps; - maps_it->head = list_maps; - maps_it->current = list_maps; - return maps_it; -} - - -procmaps_struct* pmparser_next(procmaps_iterator* p_procmaps_it){ - if(p_procmaps_it->current == NULL) - return NULL; - procmaps_struct* p_current = p_procmaps_it->current; - p_procmaps_it->current = p_procmaps_it->current->next; - return p_current; - /* - if(g_current==NULL){ - g_current=g_last_head; - }else - g_current=g_current->next; - - return g_current; - */ -} - - - -void pmparser_free(procmaps_iterator* p_procmaps_it){ - procmaps_struct* maps_list = p_procmaps_it->head; - if(maps_list==NULL) return ; - procmaps_struct* act=maps_list; - procmaps_struct* nxt=act->next; - while(act!=NULL){ - free(act); - act=nxt; - if(nxt!=NULL) - nxt=nxt->next; - } - -} - - -void _pmparser_split_line( - char*buf,char*addr1,char*addr2, - char*perm,char* offset,char* device,char*inode, - char* pathname){ - // - int orig=0; - int i=0; - //addr1 - while(buf[i]!='-'){ - addr1[i-orig]=buf[i]; - i++; - } - addr1[i]='\0'; - i++; - //addr2 - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - addr2[i-orig]=buf[i]; - i++; - } - addr2[i-orig]='\0'; - - //perm - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - perm[i-orig]=buf[i]; - i++; - } - perm[i-orig]='\0'; - //offset - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - offset[i-orig]=buf[i]; - i++; - } - offset[i-orig]='\0'; - //dev - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - device[i-orig]=buf[i]; - i++; - } - device[i-orig]='\0'; - //inode - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' '){ - inode[i-orig]=buf[i]; - i++; - } - inode[i-orig]='\0'; - //pathname - pathname[0]='\0'; - while(buf[i]=='\t' || buf[i]==' ') - i++; - orig=i; - while(buf[i]!='\t' && buf[i]!=' ' && buf[i]!='\n'){ - pathname[i-orig]=buf[i]; - i++; - } - pathname[i-orig]='\0'; - -} - -void pmparser_print(procmaps_struct* map, int order){ - - procmaps_struct* tmp=map; - int id=0; - if(order<0) order=-1; - while(tmp!=NULL){ - //(unsigned long) tmp->addr_start; - if(order==id || order==-1){ - printf("Backed by:\t%s\n",strlen(tmp->pathname)==0?"[anonym*]":tmp->pathname); - printf("Range:\t\t%p-%p\n",tmp->addr_start,tmp->addr_end); - printf("Length:\t\t%ld\n",tmp->length); - printf("Offset:\t\t%ld\n",tmp->offset); - printf("Permissions:\t%s\n",tmp->perm); - printf("Inode:\t\t%d\n",tmp->inode); - printf("Device:\t\t%s\n",tmp->dev); - } - if(order!=-1 && id>order) - tmp=NULL; - else if(order==-1){ - printf("#################################\n"); - tmp=tmp->next; - }else tmp=tmp->next; - - id++; - } -} diff --git a/riru-core/jni/zygote_restart/pmparser.h b/riru-core/jni/zygote_restart/pmparser.h deleted file mode 100644 index 1162470..0000000 --- a/riru-core/jni/zygote_restart/pmparser.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - @Author : ouadimjamal@gmail.com - @date : December 2015 - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. No representations are made about the suitability of this -software for any purpose. It is provided "as is" without express or -implied warranty. - - */ - -#ifndef H_PMPARSER -#define H_PMPARSER -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//maximum line length in a procmaps file -#define PROCMAPS_LINE_MAX_LENGTH (PATH_MAX + 100) -/** - * procmaps_struct - * @desc hold all the information about an area in the process's VM - */ -typedef struct procmaps_struct{ - void* addr_start; //< start address of the area - void* addr_end; //< end address - unsigned long length; //< size of the range - - char perm[5]; //< permissions rwxp - short is_r; //< rewrote of perm with short flags - short is_w; - short is_x; - short is_p; - - long offset; //< offset - char dev[12]; //< dev major:minor - int inode; //< inode of the file that backs the area - - char pathname[600]; //< the path of the file that backs the area - //chained list - struct procmaps_struct* next; // diff --git a/riru-core/template_override/config.sh b/riru-core/template_override/config.sh deleted file mode 100644 index c5e81c0..0000000 --- a/riru-core/template_override/config.sh +++ /dev/null @@ -1,156 +0,0 @@ -########################################################################################## -# -# Magisk Module Template Config Script -# by topjohnwu -# -########################################################################################## -########################################################################################## -# -# Instructions: -# -# 1. Place your files into system folder (delete the placeholder file) -# 2. Fill in your module's info into module.prop -# 3. Configure the settings in this file (config.sh) -# 4. If you need boot scripts, add them into common/post-fs-data.sh or common/service.sh -# 5. Add your additional or modified system properties into common/system.prop -# -########################################################################################## - -########################################################################################## -# Configs -########################################################################################## - -# Set to true if you need to enable Magic Mount -# Most mods would like it to be enabled -AUTOMOUNT=true - -# Set to true if you need to load system.prop -PROPFILE=false - -# Set to true if you need post-fs-data script -POSTFSDATA=true - -# Set to true if you need late_start service script -LATESTARTSERVICE=false - -########################################################################################## -# Installation Message -########################################################################################## - -# Set what you want to show when installing your mod - -print_modname() { - ui_print "***********" - ui_print "Riru - Core" - ui_print "***********" -} - -########################################################################################## -# Replace list -########################################################################################## - -# List all directories you want to directly replace in the system -# Check the documentations for more info about how Magic Mount works, and why you need this - -# This is an example -REPLACE=" -/system/app/Youtube -/system/priv-app/SystemUI -/system/priv-app/Settings -/system/framework -" - -# Construct your own list here, it will override the example above -# !DO NOT! remove this if you don't need to replace anything, leave it empty as it is now -REPLACE=" -" - -########################################################################################## -# Permissions -########################################################################################## - -set_permissions() { - # Only some special files require specific permissions - # The default permissions should be good enough for most cases - - # Here are some examples for the set_perm functions: - - # set_perm_recursive (default: u:object_r:system_file:s0) - # set_perm_recursive $MODPATH/system/lib 0 0 0755 0644 - - # set_perm (default: u:object_r:system_file:s0) - # set_perm $MODPATH/system/bin/app_process32 0 2000 0755 u:object_r:zygote_exec:s0 - # set_perm $MODPATH/system/bin/dex2oat 0 2000 0755 u:object_r:dex2oat_exec:s0 - # set_perm $MODPATH/system/lib/libart.so 0 0 0644 - - # The following is default permissions, DO NOT remove - set_perm_recursive $MODPATH 0 0 0755 0644 -} - -########################################################################################## -# Custom Functions -########################################################################################## - -# This file (config.sh) will be sourced by the main flash script after util_functions.sh -# If you need custom logic, please add them here as functions, and call these functions in -# update-binary. Refrain from adding code directly into update-binary, as it will make it -# difficult for you to migrate your modules to newer template versions. -# Make update-binary as clean as possible, try to only do function calls in it. -check_architecture() { - if [[ "$ARCH" != "arm" && "$ARCH" != "arm64" && "$ARCH" != "x86" && "$ARCH" != "x64" ]]; then - ui_print "- Unsupported platform: $ARCH" - exit 1 - else - ui_print "- Device platform: $ARCH" - fi -} - -copy_file_from() { - FROM_PATH=$1 - FULL_PATH="/system/$FROM_PATH/libmemtrack_real.so" - if [[ -f "$FULL_PATH" ]]; then - ui_print "- Found $FULL_PATH" - else - FULL_PATH="/system/$FROM_PATH/libmemtrack.so" - if [[ -f "$FULL_PATH" ]]; then - ui_print "- Found $FULL_PATH" - else - ui_print "- $FULL_PATH not found" - exit 1 - fi - fi - - cp "$FULL_PATH" "$MODPATH/system/$FROM_PATH/libmemtrack_real.so" || exit 1 - return 0 -} - -copy_files() { - mkdir -p "/data/misc/riru/modules" - - if [[ "$ARCH" == "x86" || "$ARCH" == "x64" ]]; then - ui_print "- Removing arm/arm64 libraries" - rm -rf "$MODPATH/system/lib" - rm -rf "$MODPATH/system/lib64" - ui_print "- Extracting x86/64 libraries" - unzip -o "$ZIP" 'system_x86/*' -d $MODPATH >&2 - mv "$MODPATH/system_x86/lib" "$MODPATH/system/lib" - mv "$MODPATH/system_x86/lib64" "$MODPATH/system/lib64" - fi - - if [[ "$IS64BIT" = true ]]; then - copy_file_from lib64 - else - ui_print "- Removing 64-bit libraries" - rm -rf "$MODPATH/system/lib64" - fi - copy_file_from lib - - ui_print "- Extracting zygote_restart executable" - mkdir -p "/data/misc/riru/bin" - unzip -j "$ZIP" "zygote_restart_$ARCH" -d "/data/misc/riru/bin" >&2 - mv "/data/misc/riru/bin/zygote_restart_$ARCH" "/data/misc/riru/bin/zygote_restart" - set_perm "/data/misc/riru/bin/zygote_restart" 0 0 0700 u:object_r:system_file:s0 - - ui_print "- Writing api_version file" - echo -n "3" > "/data/misc/riru/api_version" -} \ No newline at end of file diff --git a/riru-core/template_override/module.prop b/riru-core/template_override/module.prop deleted file mode 100644 index bd52c10..0000000 --- a/riru-core/template_override/module.prop +++ /dev/null @@ -1,7 +0,0 @@ -id=riru-core -name=Riru - Core -version=v18 -versionCode=19 -author=Rikka -description=Inject zygote process by replace libmemtrack.so, provide interface to other Riru modules. -minMagisk=17000 diff --git a/riru-core/template_override/post-fs-data.sh b/riru-core/template_override/post-fs-data.sh deleted file mode 100644 index c02a96a..0000000 --- a/riru-core/template_override/post-fs-data.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/system/bin/sh -# Please don't hardcode /magisk/modname/... ; instead, please use $MODDIR/... -# This will make your scripts compatible even if Magisk change its mount point in the future -MODDIR=${0%/*} - -# This script will be executed in late_start service mode -# More info in the main Magisk thread -ZYGOTE_RESTART=/data/misc/riru/bin/zygote_restart -[[ ! -f "/data/misc/riru/config/disable_auto_restart" ]] && $ZYGOTE_RESTART \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/.gitignore b/riru-module-xfingerprint-pay-taobao/.gitignore deleted file mode 100644 index c4de86b..0000000 --- a/riru-module-xfingerprint-pay-taobao/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.externalNativeBuild -/build \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/build.gradle b/riru-module-xfingerprint-pay-taobao/build.gradle deleted file mode 100644 index 064a639..0000000 --- a/riru-module-xfingerprint-pay-taobao/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion rootProject.ext.targetSdkVersion - defaultConfig { - minSdkVersion rootProject.ext.minSdkVersion - targetSdkVersion rootProject.ext.targetSdkVersion - - externalNativeBuild { - ndkBuild { - abiFilters 'arm64-v8a', 'armeabi-v7a' - arguments "NDK_PROJECT_PATH=jni/" - } - } - } - externalNativeBuild { - ndkBuild { - path 'jni/Android.mk' - } - } -} - -task zip(type: Exec) { - workingDir '..' - commandLine 'sh', 'build.sh', project.name, 'v3.9.2' -} \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/build.sh b/riru-module-xfingerprint-pay-taobao/build.sh deleted file mode 100644 index 40dd786..0000000 --- a/riru-module-xfingerprint-pay-taobao/build.sh +++ /dev/null @@ -1,16 +0,0 @@ -function copy_files { - # /data/misc/riru/modules/template exists -> libriru_template.so will be loaded - # Change "template" to your module name - # You can also use this folder as your config folder - NAME="xfingerprint_pay_taobao" - mkdir -p $TMP_DIR_MAGISK/data/misc/riru/modules/$NAME - cp $MODULE_NAME/template_override/riru_module.prop $TMP_DIR_MAGISK/data/misc/riru/modules/$NAME/module.prop - - cp $MODULE_NAME/template_override/config.sh $TMP_DIR_MAGISK - cp $MODULE_NAME/template_override/module.prop $TMP_DIR_MAGISK - - mkdir -p $TMP_DIR_MAGISK/system/framework - - 7za e -o$TMP_DIR_MAGISK/system/framework/ $MODULE_NAME/libs/fingerprint-pay-taobao-magisk.apk classes.dex - mv -f $TMP_DIR_MAGISK/system/framework/classes.dex $TMP_DIR_MAGISK/system/framework/libxfingerprint_pay_taobao.dex -} \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/jni/.gitattributes b/riru-module-xfingerprint-pay-taobao/jni/.gitattributes deleted file mode 100644 index 63f9e34..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -libs/** binary diff --git a/riru-module-xfingerprint-pay-taobao/jni/Android.mk b/riru-module-xfingerprint-pay-taobao/jni/Android.mk deleted file mode 100644 index 16d6dcf..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/Android.mk +++ /dev/null @@ -1,3 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(call all-makefiles-under, $(LOCAL_PATH)) \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/jni/Application.mk b/riru-module-xfingerprint-pay-taobao/jni/Application.mk deleted file mode 100644 index 1a60ee8..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/Application.mk +++ /dev/null @@ -1,22 +0,0 @@ -APP_ABI := arm64-v8a armeabi-v7a x86 x86_64 -APP_PLATFORM := android-23 -APP_CFLAGS := -std=gnu99 -llog -APP_CPPFLAGS := -std=c++11 -llog -APP_STL := c++_static -APP_SHORT_COMMANDS := true - -ifeq ($(NDK_DEBUG),1) -$(info building DEBUG version...) -APP_CFLAGS += -O0 -APP_CPPFLAGS += -O0 -else -$(info building RELEASE version...) -APP_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -O2 -APP_CPPFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden -O2 -endif - -# do not remove this, or your module will crash apps on Android Q -SCS_FLAGS := -ffixed-x18 -APP_LDFLAGS += $(SCS_FLAGS) -APP_CFLAGS += $(SCS_FLAGS) -APP_CPPFLAGS += $(SCS_FLAGS) \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/jni/main/Android.mk b/riru-module-xfingerprint-pay-taobao/jni/main/Android.mk deleted file mode 100644 index 3c625de..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/main/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -# Change "libriru_template" to your module name, must start with "libriru_" -LOCAL_MODULE := libriru_xfingerprint_pay_taobao -LOCAL_C_INCLUDES := \ - $(LOCAL_PATH) -LOCAL_LDLIBS += -ldl -llog -LOCAL_LDFLAGS := -Wl,--hash-style=both - -LOCAL_SRC_FILES:= main.cpp - -include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/jni/main/riru.c b/riru-module-xfingerprint-pay-taobao/jni/main/riru.c deleted file mode 100644 index e471e64..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/main/riru.c +++ /dev/null @@ -1,118 +0,0 @@ -#include -#include -#include - -#ifdef __LP64__ -#define LIB "/system/lib64/libmemtrack.so" -#else -#define LIB "/system/lib/libmemtrack.so" -#endif - -static void *riru_handle; -static char *riru_module_name; - -static void *get_handle() { - if (riru_handle == NULL) - riru_handle = dlopen(LIB, RTLD_NOW | RTLD_GLOBAL); - - return riru_handle; -} - -const char *riru_get_module_name() { - return riru_module_name; -} - -void riru_set_module_name(const char *name) { - riru_module_name = strdup(name); -} - -int riru_get_version() { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return -1; - if (sym == NULL) sym = dlsym(handle, "riru_get_version"); - if (sym) return ((int (*)()) sym)(); - return -1; -} - -void *riru_get_func(const char *name) { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return NULL; - if (sym == NULL) sym = dlsym(handle, "riru_get_func"); - if (sym) return ((void *(*)(const char *, const char *)) sym)(riru_get_module_name(), name); - return NULL; -} - -void *riru_get_native_method_func(const char *className, const char *name, const char *signature) { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return NULL; - if (sym == NULL) sym = dlsym(handle, "riru_get_native_method_func"); - if (sym) - return ((void *(*)(const char *, const char *, const char *, const char *)) sym)( - riru_get_module_name(), className, name, signature); - return NULL; -} - -void riru_set_func(const char *name, void *func) { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return; - if (sym == NULL) sym = dlsym(handle, "riru_set_func"); - if (sym) - ((void *(*)(const char *, const char *, void *)) sym)(riru_get_module_name(), name, func); -} - -void riru_set_native_method_func(const char *className, const char *name, const char *signature, - void *func) { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return; - if (sym == NULL) sym = dlsym(handle, "riru_set_native_method_func"); - if (sym) - ((void *(*)(const char *, const char *, const char *, const char *, void *)) sym)( - riru_get_module_name(), className, name, signature, func); -} - -const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, - const char *signature) { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return NULL; - if (sym == NULL) sym = dlsym(handle, "riru_get_original_native_methods"); - if (sym) - return ((JNINativeMethod *(*)(const char *, const char *, const char *)) sym) - (className, name, signature); - return NULL; -} - -int riru_is_zygote_methods_replaced() { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return 0; - if (sym == NULL) sym = dlsym(handle, "riru_is_zygote_methods_replaced"); - if (sym) - return ((int (*)()) sym)(); - return 0; -} - -int riru_get_nativeForkAndSpecialize_calls_count() { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return 0; - if (sym == NULL) sym = dlsym(handle, "riru_get_nativeForkAndSpecialize_calls_count"); - if (sym) - return ((int (*)()) sym)(); - return 0; -} - -int riru_get_nativeForkSystemServer_calls_count() { - static void **sym; - void *handle; - if ((handle = get_handle()) == NULL) return 0; - if (sym == NULL) sym = dlsym(handle, "riru_get_nativeForkSystemServer_calls_count"); - if (sym) - return ((int (*)()) sym)(); - return 0; -} \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/jni/main/riru.h b/riru-module-xfingerprint-pay-taobao/jni/main/riru.h deleted file mode 100644 index 601a3d6..0000000 --- a/riru-module-xfingerprint-pay-taobao/jni/main/riru.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef RIRU_H -#define RIRU_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif -__attribute__((visibility("default"))) void riru_set_module_name(const char *name); - -/** - * Get Riru version. - * - * @return Riru version - */ -int riru_get_version(); - -/* - * Get new_func address from last module which hook func. - * Use this as your old_func if you want to hook func. - * - * @param name a unique name - * @return new_func from last module or null - */ -void *riru_get_func(const char *name); - -/* - * Java native version of riru_get_func. - * - * @param className class name - * @param name method name - * @param signature method signature - * @return new_func address from last module or original address - */ -void *riru_get_native_method_func(const char *className, const char *name, const char *signature); - -/* - * Set new_func address for next module which wants to hook func. - * - * @param name a unique name - * @param func your new_func address - */ -void riru_set_func(const char *name, void *func); - -/* - * Java native method version of riru_set_func. - * - * @param className class name - * @param name method name - * @param signature method signature - * @param func your new_func address - */ -void riru_set_native_method_func(const char *className, const char *name, const char *signature, - void *func); - -/** - * Get native methods from Riru's jniRegisterNativeMethods hook. - * If both name and signature are null, all the class's methods will be returned. - * - * @param className className - * @param name method name, null for the method with specific signature - * @param signature method signature, null for the method with specific name - * @return JNINativeMethod* - */ -const JNINativeMethod *riru_get_original_native_methods(const char *className, const char *name, - const char *signature); - -/** - * Return if Zygote class's native method nativeForkAndSpecialize & nativeForkSystemServer is replaced by - * Riru. - * - * @return methods replaced - */ -int riru_is_zygote_methods_replaced(); - -/** - * Return calls count of Zygote class's native method nativeForkAndSpecialize replaced by Riru. - * - * @return nativeForkAndSpecialize calls count - */ -int riru_get_nativeForkAndSpecialize_calls_count(); - -/** - * Return calls count of Zygote class native's method nativeForkSystemServer replaced by Riru. - * - * @return nativeForkAndSpecialize calls count - */ -int riru_get_nativeForkSystemServer_calls_count(); -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/libs/fingerprint-pay-taobao-magisk.apk b/riru-module-xfingerprint-pay-taobao/libs/fingerprint-pay-taobao-magisk.apk deleted file mode 100644 index 302b24e..0000000 Binary files a/riru-module-xfingerprint-pay-taobao/libs/fingerprint-pay-taobao-magisk.apk and /dev/null differ diff --git a/riru-module-xfingerprint-pay-taobao/src/main/AndroidManifest.xml b/riru-module-xfingerprint-pay-taobao/src/main/AndroidManifest.xml deleted file mode 100644 index 8a34770..0000000 --- a/riru-module-xfingerprint-pay-taobao/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/riru-module-xfingerprint-pay-taobao/template_override/config.sh b/riru-module-xfingerprint-pay-taobao/template_override/config.sh deleted file mode 100644 index 5601725..0000000 --- a/riru-module-xfingerprint-pay-taobao/template_override/config.sh +++ /dev/null @@ -1,149 +0,0 @@ -########################################################################################## -# -# Magisk Module Template Config Script -# by topjohnwu -# -########################################################################################## -########################################################################################## -# -# Instructions: -# -# 1. Place your files into system folder (delete the placeholder file) -# 2. Fill in your module's info into module.prop -# 3. Configure the settings in this file (config.sh) -# 4. If you need boot scripts, add them into common/post-fs-data.sh or common/service.sh -# 5. Add your additional or modified system properties into common/system.prop -# -########################################################################################## - -########################################################################################## -# Configs -########################################################################################## - -# Set to true if you need to enable Magic Mount -# Most mods would like it to be enabled -AUTOMOUNT=true - -# Set to true if you need to load system.prop -PROPFILE=false - -# Set to true if you need post-fs-data script -POSTFSDATA=false - -# Set to true if you need late_start service script -LATESTARTSERVICE=false - -########################################################################################## -# Installation Message -########################################################################################## - -# Set what you want to show when installing your mod - -print_modname() { - ui_print "*******************************" - ui_print " Riru - Module Fingerprint pay for Taobao " - ui_print "*******************************" -} - -########################################################################################## -# Replace list -########################################################################################## - -# List all directories you want to directly replace in the system -# Check the documentations for more info about how Magic Mount works, and why you need this - -# This is an example -REPLACE=" -/system/app/Youtube -/system/priv-app/SystemUI -/system/priv-app/Settings -/system/framework -" - -# Construct your own list here, it will override the example above -# !DO NOT! remove this if you don't need to replace anything, leave it empty as it is now -REPLACE=" -" - -########################################################################################## -# Permissions -########################################################################################## - -set_permissions() { - # Only some special files require specific permissions - # The default permissions should be good enough for most cases - - # Here are some examples for the set_perm functions: - - # set_perm_recursive (default: u:object_r:system_file:s0) - # set_perm_recursive $MODPATH/system/lib 0 0 0755 0644 - - # set_perm (default: u:object_r:system_file:s0) - # set_perm $MODPATH/system/bin/app_process32 0 2000 0755 u:object_r:zygote_exec:s0 - # set_perm $MODPATH/system/bin/dex2oat 0 2000 0755 u:object_r:dex2oat_exec:s0 - # set_perm $MODPATH/system/lib/libart.so 0 0 0644 - - # The following is default permissions, DO NOT remove - set_perm_recursive $MODPATH 0 0 0755 0644 -} - -########################################################################################## -# Custom Functions -########################################################################################## - -# This file (config.sh) will be sourced by the main flash script after util_functions.sh -# If you need custom logic, please add them here as functions, and call these functions in -# update-binary. Refrain from adding code directly into update-binary, as it will make it -# difficult for you to migrate your modules to newer template versions. -# Make update-binary as clean as possible, try to only do function calls in it. -fail() { - echo "$1" - exit 1 -} - -check_riru_version() { - [[ ! -f "/data/misc/riru/api_version" ]] && fail "! Please Install Riru - Core v18 or above" - VERSION=$(cat "/data/misc/riru/api_version") - ui_print "- Riru API version is $VERSION" - [[ "$VERSION" -ge 3 ]] || fail "! Please Install Riru - Core v18 or above" -} - -check_architecture() { - if [[ "$ARCH" != "arm" && "$ARCH" != "arm64" ]]; then - ui_print "- Unsupported platform: $ARCH" - exit 1 - else - ui_print "- Device platform: $ARCH" - fi - - check_riru_version -} - -copy_files() { - if [[ "$ARCH" == "x86" || "$ARCH" == "x64" ]]; then - ui_print "- Removing arm/arm64 libraries" - rm -rf "$MODPATH/system/lib" - rm -rf "$MODPATH/system/lib64" - ui_print "- Extracting x86/64 libraries" - unzip -o "$ZIP" 'system_x86/*' -d $MODPATH >&2 - mv "$MODPATH/system_x86/lib" "$MODPATH/system/lib" - mv "$MODPATH/system_x86/lib64" "$MODPATH/system/lib64" - fi - - if [[ "$IS64BIT" = false ]]; then - ui_print "- Removing 64-bit libraries" - rm -rf "$MODPATH/system/lib64" - fi - - ui_print "- Extracting extra files" - unzip -o "$ZIP" 'data/*' -d "$MODPATH" >&2 - - TARGET="/data/misc/riru/modules" - - [[ -d "$TARGET" ]] || mkdir -p "$TARGET" || fail "- Can't mkdir -p $TARGET" - cp -af "$MODPATH$TARGET/." "$TARGET" || fail "- Can't cp -af $MODPATH$TARGET/. $TARGET" - - rm -rf "$MODPATH/data" 2>/dev/null - - ui_print "- Files copied" -} \ No newline at end of file diff --git a/riru-module-xfingerprint-pay-taobao/template_override/module.prop b/riru-module-xfingerprint-pay-taobao/template_override/module.prop deleted file mode 100644 index 56ac44b..0000000 --- a/riru-module-xfingerprint-pay-taobao/template_override/module.prop +++ /dev/null @@ -1,7 +0,0 @@ -id=riru-module-xfingerprint-pay-taobao -name=指纹支付-淘宝 -version=v3.9.2 -versionCode=1 -author=Jason Eric -description=让淘宝支持指纹支付 Fingerprint pay for Taobao -minMagisk=17000 diff --git a/riru-module-xfingerprint-pay-taobao/template_override/riru_module.prop b/riru-module-xfingerprint-pay-taobao/template_override/riru_module.prop deleted file mode 100644 index c668a51..0000000 --- a/riru-module-xfingerprint-pay-taobao/template_override/riru_module.prop +++ /dev/null @@ -1,6 +0,0 @@ -name=指纹支付-淘宝 -version=v3.9.2 -versionCode=1 -author=Jason Eric -description=让淘宝支持指纹支付\nFingerprint pay for Taobao -api=3 \ No newline at end of file diff --git a/run.sh b/run.sh index c6fa80a..c486966 100755 --- a/run.sh +++ b/run.sh @@ -1 +1,7 @@ -./gradlew clean && ./gradlew :riru-module-xfingerprint-pay-taobao:zip && adb push ./release/* /sdcard/Download/ +#!/bin/bash +set -e +cd ${0%/*} +./gradlew clean +./gradlew :module:assembleRelease +adb shell rm -fv "/data/local/tmp/libxfingerprint_pay_taobao.dex" +adb push ./out/*.zip /sdcard/Download/ diff --git a/settings.gradle b/settings.gradle index abb5ebf..3fda755 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1 @@ -include ':riru-core', ':riru-module-xfingerprint-pay-taobao', ':riru-location-report-enabler', ':riru-storage-redirect', ':app' +include ':module' \ No newline at end of file diff --git a/template/magisk/META-INF/com/google/android/update-binary b/template/magisk/META-INF/com/google/android/update-binary deleted file mode 100644 index f7e3cc1..0000000 --- a/template/magisk/META-INF/com/google/android/update-binary +++ /dev/null @@ -1,159 +0,0 @@ -#!/sbin/sh -########################################################################################## -# -# Magisk Module Template Install Script -# by topjohnwu -# -########################################################################################## - -TMPDIR=/dev/tmp -INSTALLER=$TMPDIR/install -# Always mount under tmp -MOUNTPATH=$TMPDIR/magisk_img - -# Default permissions -umask 022 - -# Initial cleanup -rm -rf $TMPDIR 2>/dev/null -mkdir -p $INSTALLER - -# echo before loading util_functions -ui_print() { echo "$1"; } - -require_new_magisk() { - ui_print "*******************************" - ui_print " Please install Magisk v17.0+! " - ui_print "*******************************" - exit 1 -} - -########################################################################################## -# Environment -########################################################################################## - -OUTFD=$2 -ZIP=$3 - -mount /data 2>/dev/null - -# Load utility functions -if [ -f /data/adb/magisk/util_functions.sh ]; then - . /data/adb/magisk/util_functions.sh -elif [ -f /data/magisk/util_functions.sh ]; then - NVBASE=/data - . /data/magisk/util_functions.sh -else - require_new_magisk -fi - -# Use alternative image if in BOOTMODE -$BOOTMODE && IMG=$NVBASE/magisk_merge.img - -# Preperation for flashable zips -setup_flashable - -# Mount partitions -mount_partitions - -# Detect version and architecture -api_level_arch_detect - -# You can get the Android API version from $API, the CPU architecture from $ARCH -# Useful if you are creating Android version / platform dependent mods - -# Setup busybox and binaries -$BOOTMODE && boot_actions || recovery_actions - -########################################################################################## -# Preparation -########################################################################################## - -# Extract common files -unzip -o "$ZIP" module.prop config.sh 'common/*' -d $INSTALLER >&2 - -[ ! -f $INSTALLER/config.sh ] && abort "! Unable to extract zip file!" -# Load configurations -. $INSTALLER/config.sh - -# Check architecture -check_architecture - -# Check the installed magisk version -MIN_VER=`grep_prop minMagisk $INSTALLER/module.prop` -[ ! -z $MAGISK_VER_CODE -a $MAGISK_VER_CODE -ge $MIN_VER ] || require_new_magisk -MODID=`grep_prop id $INSTALLER/module.prop` -MODPATH=$MOUNTPATH/$MODID - -# Print mod name -print_modname - -# Please leave this message in your flashable zip for credits :) -ui_print "******************************" -ui_print "Powered by Magisk (@topjohnwu)" -ui_print "******************************" - -########################################################################################## -# Install -########################################################################################## - -# Get the variable reqSizeM. Use your own method to determine reqSizeM if needed -request_zip_size_check "$ZIP" - -# This function will mount $IMG to $MOUNTPATH, and resize the image based on $reqSizeM -mount_magisk_img - -# Create mod paths -rm -rf $MODPATH 2>/dev/null -mkdir -p $MODPATH - -# Extract files to system. Use your own method if needed -ui_print "- Extracting module files" -unzip -o "$ZIP" 'system/*' -d $MODPATH >&2 - -# Remove placeholder -rm -f $MODPATH/system/placeholder 2>/dev/null - -# Extra copy file function -copy_files - -# Handle replace folders -for TARGET in $REPLACE; do - mktouch $MODPATH$TARGET/.replace -done - -# Auto Mount -$AUTOMOUNT && touch $MODPATH/auto_mount - -# prop files -$PROPFILE && cp -af $INSTALLER/common/system.prop $MODPATH/system.prop - -# Module info -cp -af $INSTALLER/module.prop $MODPATH/module.prop -if $BOOTMODE; then - # Update info for Magisk Manager - mktouch /sbin/.core/img/$MODID/update - cp -af $INSTALLER/module.prop /sbin/.core/img/$MODID/module.prop -fi - -# post-fs-data mode scripts -$POSTFSDATA && cp -af $INSTALLER/common/post-fs-data.sh $MODPATH/post-fs-data.sh - -# service mode scripts -$LATESTARTSERVICE && cp -af $INSTALLER/common/service.sh $MODPATH/service.sh - -ui_print "- Setting permissions" -set_permissions - -########################################################################################## -# Finalizing -########################################################################################## - -# Unmount magisk image and shrink if possible -unmount_magisk_img - -$BOOTMODE || recovery_cleanup -rm -rf $TMPDIR - -ui_print "- Done" -exit 0 diff --git a/template/magisk/.gitattributes b/template/magisk_module/.gitattributes old mode 100644 new mode 100755 similarity index 84% rename from template/magisk/.gitattributes rename to template/magisk_module/.gitattributes index 8980df1..cba5bea --- a/template/magisk/.gitattributes +++ b/template/magisk_module/.gitattributes @@ -3,6 +3,8 @@ META-INF/** text eol=lf *.prop text eol=lf *.sh text eol=lf *.md text eol=lf +sepolicy.rule eol=lf # Denote all files that are truly binary and should not be modified. system/** binary +system_x86/** binary \ No newline at end of file diff --git a/template/magisk_module/META-INF/com/google/android/update-binary b/template/magisk_module/META-INF/com/google/android/update-binary new file mode 100755 index 0000000..d19eeb5 --- /dev/null +++ b/template/magisk_module/META-INF/com/google/android/update-binary @@ -0,0 +1,173 @@ +#!/sbin/sh + +################# +# Initialization +################# + +umask 022 + +# Global vars +TMPDIR=/dev/tmp +PERSISTDIR=/sbin/.magisk/mirror/persist + +rm -rf $TMPDIR 2>/dev/null +mkdir -p $TMPDIR + +# echo before loading util_functions +ui_print() { echo "$1"; } + +require_new_magisk() { + ui_print "*******************************" + ui_print " Please install Magisk v19.0+! " + ui_print "*******************************" + exit 1 +} + +is_legacy_script() { + unzip -l "$ZIPFILE" install.sh | grep -q install.sh + return $? +} + +print_modname() { + local len + len=`echo -n $MODNAME | wc -c` + len=$((len + 2)) + local pounds=`printf "%${len}s" | tr ' ' '*'` + ui_print "$pounds" + ui_print " $MODNAME " + ui_print "$pounds" + ui_print "*******************" + ui_print " Powered by Magisk " + ui_print "*******************" +} + +############## +# Environment +############## + +OUTFD=$2 +ZIPFILE=$3 + +mount /data 2>/dev/null + +# Load utility functions +[ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk +. /data/adb/magisk/util_functions.sh +[ $MAGISK_VER_CODE -gt 18100 ] || require_new_magisk + +# Preperation for flashable zips +setup_flashable + +# Mount partitions +mount_partitions + +# Detect version and architecture +api_level_arch_detect + +# Setup busybox and binaries +$BOOTMODE && boot_actions || recovery_actions + +############## +# Preparation +############## + +# Extract prop file +unzip -o "$ZIPFILE" module.prop -d $TMPDIR >&2 +[ ! -f $TMPDIR/module.prop ] && abort "! Unable to extract zip file!" + +$BOOTMODE && MODDIRNAME=modules_update || MODDIRNAME=modules +MODULEROOT=$NVBASE/$MODDIRNAME +MODID=`grep_prop id $TMPDIR/module.prop` +MODPATH=$MODULEROOT/$MODID +MODNAME=`grep_prop name $TMPDIR/module.prop` + +# Create mod paths +rm -rf $MODPATH 2>/dev/null +mkdir -p $MODPATH + +########## +# Install +########## + +if is_legacy_script; then + unzip -oj "$ZIPFILE" module.prop install.sh uninstall.sh 'common/*' -d $TMPDIR >&2 + + # Load install script + . $TMPDIR/install.sh + + # Callbacks + print_modname + on_install + + # Custom uninstaller + [ -f $TMPDIR/uninstall.sh ] && cp -af $TMPDIR/uninstall.sh $MODPATH/uninstall.sh + + # Skip mount + $SKIPMOUNT && touch $MODPATH/skip_mount + + # prop file + $PROPFILE && cp -af $TMPDIR/system.prop $MODPATH/system.prop + + # Module info + cp -af $TMPDIR/module.prop $MODPATH/module.prop + + # post-fs-data scripts + $POSTFSDATA && cp -af $TMPDIR/post-fs-data.sh $MODPATH/post-fs-data.sh + + # service scripts + $LATESTARTSERVICE && cp -af $TMPDIR/service.sh $MODPATH/service.sh + + ui_print "- Setting permissions" + set_permissions +else + print_modname + + unzip -o "$ZIPFILE" customize.sh -d $MODPATH >&2 + + if ! grep -q '^SKIPUNZIP=1$' $MODPATH/customize.sh 2>/dev/null; then + ui_print "- Extracting module files" + unzip -o "$ZIPFILE" -x 'META-INF/*' -d $MODPATH >&2 + + # Default permissions + set_perm_recursive $MODPATH 0 0 0755 0644 + fi + + # Load customization script + [ -f $MODPATH/customize.sh ] && . $MODPATH/customize.sh +fi + +# Handle replace folders +for TARGET in $REPLACE; do + ui_print "- Replace target: $TARGET" + mktouch $MODPATH$TARGET/.replace +done + +if $BOOTMODE; then + # Update info for Magisk Manager + mktouch $NVBASE/modules/$MODID/update + cp -af $MODPATH/module.prop $NVBASE/modules/$MODID/module.prop +fi + +# Copy over custom sepolicy rules +if [ -f $MODPATH/sepolicy.rule -a -e $PERSISTDIR ]; then + ui_print "- Installing custom sepolicy patch" + PERSISTMOD=$PERSISTDIR/magisk/$MODID + mkdir -p $PERSISTMOD + cp -af $MODPATH/sepolicy.rule $PERSISTMOD/sepolicy.rule +fi + +# Remove stuffs that don't belong to modules +rm -rf \ +$MODPATH/system/placeholder $MODPATH/customize.sh \ +$MODPATH/README.md $MODPATH/.git* 2>/dev/null + +############## +# Finalizing +############## + +cd / +$BOOTMODE || recovery_cleanup +rm -rf $TMPDIR + +ui_print "- Done" +exit 0 \ No newline at end of file diff --git a/template/magisk/META-INF/com/google/android/updater-script b/template/magisk_module/META-INF/com/google/android/updater-script old mode 100644 new mode 100755 similarity index 100% rename from template/magisk/META-INF/com/google/android/updater-script rename to template/magisk_module/META-INF/com/google/android/updater-script diff --git a/template/magisk_module/README.md b/template/magisk_module/README.md new file mode 100755 index 0000000..c316e8b --- /dev/null +++ b/template/magisk_module/README.md @@ -0,0 +1 @@ +# Riru - Template \ No newline at end of file diff --git a/template/magisk_module/customize.sh b/template/magisk_module/customize.sh new file mode 100755 index 0000000..89675f5 --- /dev/null +++ b/template/magisk_module/customize.sh @@ -0,0 +1,65 @@ +SKIPUNZIP=1 +RIRU_PATH="/data/misc/riru" +RIRU_MODULES_PATH="$RIRU_PATH/modules" + +# check architecture +if [[ "$ARCH" != "arm" && "$ARCH" != "arm64" && "$ARCH" != "x86" && "$ARCH" != "x64" ]]; then + abort "! Unsupported platform: $ARCH" +else + ui_print "- Device platform: $ARCH" +fi + +# check Riru version +if [[ ! -f "$RIRU_PATH/api_version" ]]; then + ui_print "*********************************************************" + ui_print "! 'Riru - Core' is not installed" + ui_print "! You can download from 'Magisk Manager' or https://github.com/RikkaApps/Riru/releases" + abort "*********************************************************" +fi +RIRU_API_VERSION=$(cat "$RIRU_PATH/api_version") +ui_print "- Riru API version: $RIRU_API_VERSION" +if [[ "$RIRU_API_VERSION" -lt 4 ]]; then + ui_print "*********************************************************" + ui_print "! The latest version of 'Riru - Core' is required" + ui_print "! You can download from 'Magisk Manager' or https://github.com/RikkaApps/Riru/releases" + abort "*********************************************************" +fi + +# extract verify.sh +unzip -o "$ZIPFILE" 'verify.sh' -d "$TMPDIR" >&2 +if [[ ! -f "$TMPDIR/verify.sh" ]]; then + ui_print "*********************************************************" + ui_print "! Unable to extract verify.sh!" + ui_print "! This zip may be corrupted, please try downloading again" + abort "*********************************************************" +fi +. $TMPDIR/verify.sh + +# extract libs +ui_print "- Extracting module files" +vunzip -o "$ZIPFILE" 'module.prop' 'post-fs-data.sh' 'uninstall.sh' -d "$MODPATH" + +if [[ "$ARCH" == "x86" || "$ARCH" == "x64" ]]; then + ui_print "- Extracting x86/64 libraries" + vunzip -o "$ZIPFILE" 'system_x86/*' -d "$MODPATH" + mv "$MODPATH/system_x86/lib" "$MODPATH/system/lib" + mv "$MODPATH/system_x86/lib64" "$MODPATH/system/lib64" +else + ui_print "- Extracting arm/arm64 libraries" + vunzip -o "$ZIPFILE" 'system/*' -d "$MODPATH" +fi + +if [[ "$IS64BIT" == "false" ]]; then + ui_print "- Removing 64-bit libraries" + rm -rf "$MODPATH/system/lib64" +fi + +# Riru files +ui_print "- Extracting extra files" +unzip -o "$ZIPFILE" 'data/*' -d "$TMPDIR" >&2 +[[ -d "$RIRU_MODULES_PATH" ]] || mkdir -p "$RIRU_MODULES_PATH" || abort "! Can't mkdir -p $RIRU_MODULES_PATH" +cp -af "$TMPDIR$RIRU_MODULES_PATH/." "$RIRU_MODULES_PATH" || abort "! Can't cp -af $TMPDIR$RIRU_MODULES_PATH/. $RIRU_MODULES_PATH" + +# set permissions +ui_print "- Setting permissions" +set_perm_recursive "$MODPATH" 0 0 0755 0644 diff --git a/template/magisk_module/post-fs-data.sh b/template/magisk_module/post-fs-data.sh new file mode 100755 index 0000000..e1477f9 --- /dev/null +++ b/template/magisk_module/post-fs-data.sh @@ -0,0 +1,12 @@ +#!/system/bin/sh +MODDIR=${0%/*} +MODULE_ID="module_xfingerprint_pay_taobao" + +# Reset context jsut in case +chcon -R u:object_r:system_file:s0 "$MODDIR" + +# Rename module.prop.new +if [ -f "/data/misc/riru/modules/$MODULE_ID/module.prop.new" ]; then + rm "/data/misc/riru/modules/$MODULE_ID/module.prop" + mv "/data/misc/riru/modules/$MODULE_ID/module.prop.new" "/data/misc/riru/modules/$MODULE_ID/module.prop" +fi \ No newline at end of file diff --git a/template/magisk_module/uninstall.sh b/template/magisk_module/uninstall.sh new file mode 100755 index 0000000..e96c19b --- /dev/null +++ b/template/magisk_module/uninstall.sh @@ -0,0 +1,5 @@ +#!/sbin/sh +RIRU_MODULE_PATH="/data/misc/riru/modules" +MODULE_ID="module_xfingerprint_pay_taobao" + +rm -rf "$RIRU_MODULE_PATH/$MODULE_ID" \ No newline at end of file diff --git a/template/magisk_module/verify.sh b/template/magisk_module/verify.sh new file mode 100755 index 0000000..cb78852 --- /dev/null +++ b/template/magisk_module/verify.sh @@ -0,0 +1,123 @@ +########################################################################################## +# +# Verifier for Magisk Module Installer +# +########################################################################################## +########################################################################################## +# +# Instructions: +# +# 1. Copy the code below to .git/hooks/pre-commit or execute it manually every time +# 2. Replace unzip xxx with vunzip in install.sh +# 3. To see the output of verification, remove >&2 from the end of unzip +# +# #!/bin/sh +# find -type f \ +# -not -path "./.git/*" \ +# -not -path "./.git*" \ +# -not -path "./META-INF/*" \ +# -not -path "./README.md" \ +# -not -name "*.sha256sum" \ +# -exec echo "Generating {}.sha256sum" \; \ +# -exec sh -c "sha256sum -b {} | cut -d \" \" -f 1 | tr -d '\n' > {}.sha256sum" \; \ +# -exec git add "{}.sha256sum" \; +# +########################################################################################## + +TMPDIR_FOR_VERIFY=$TMPDIR/.vunzip + +abort_verify() { + ui_print "*********************************************************" + ui_print "! $1" + ui_print "! This zip may be corrupted, please try downloading again" + abort "*********************************************************" +} + +verify_and_move() { + # Ignore .sha256sum file itself + if [[ $1 = *.sha256sum ]]; then + ui_print "- Ignore $1.sha256sum" + return + fi + + file=$TMPDIR_FOR_VERIFY/$1 + if [[ ! -f $file.sha256sum ]]; then + unzip -o -j $ZIPFILE "$1.sha256sum" -d $2 >&2 + fi + + if [[ ! -f $file.sha256sum ]]; then + abort_verify "$1.sha256sum not exists" + return + fi + + (echo "$(cat $file.sha256sum) $file" | sha256sum -c -s -) || abort_verify "Failed to verify $1" + + ui_print "- Verified $1" >&1 + + rm -f $file.sha256sum + + dir=$3 + restore_paths=$4 + + if [[ $restore_paths = true ]]; then + mkdir -p "$(dirname "$dir/$1")" + mv $file $dir/$1 + else + mkdir -p $dir + mv $file $dir/"$(basename $1)" + fi +} + +verify_and_move_recurse() { + for file in $1/*; do + if [ -d $file ];then + verify_and_move_recurse $file $2 $3 $4 + elif [ -f $file ]; then + verify_and_move $(echo $file | cut -c $2-) $1 $3 $4 + fi + done +} + +vunzip() { + rm -rf $TMPDIR_FOR_VERIFY + mkdir $TMPDIR_FOR_VERIFY + + new_args="" + dir_exists=0 + dir="" + restore_paths=true + + for arg in "$@" + do + # To get .sha256sum file from original structure, ignore -j + if [[ $arg = "-j" ]]; then + restore_paths=false + else + # Change -d path to our tmp path + if [[ $dir_exists -eq 1 ]]; then + dir_exists=2 + dir=$arg + new_args=$(eval echo $new_args $TMPDIR_FOR_VERIFY) + else + new_args=$(eval echo $new_args $arg) + fi + if [[ $arg = "-d" ]]; then + dir_exists=1 + fi + fi + done + + # Use pwd if -d not set + if [[ $dir_exists -eq 0 ]]; then + dir=$(pwd) + new_args=$(eval echo $new_args -d $TMPDIR_FOR_VERIFY) + fi + + # Call real unzip + eval unzip $new_args >&2 + + len=${#TMPDIR_FOR_VERIFY} + let len=len+2 + + verify_and_move_recurse $TMPDIR_FOR_VERIFY $len $dir $restore_paths +} \ No newline at end of file