Merge branch 'master' of https://github.com/ElderDrivers/EdXposed
This commit is contained in:
commit
d1132927b1
|
|
@ -7,6 +7,7 @@ import android.text.TextUtils;
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
import com.elderdrivers.riru.xposed.config.ConfigManager;
|
||||||
|
|
||||||
|
import java.security.MessageDigest;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
@ -226,4 +227,20 @@ public class DexMakerUtils {
|
||||||
TypeId<?> boxTypeId;
|
TypeId<?> boxTypeId;
|
||||||
code.returnValue(resultLocals.get(returnType));
|
code.returnValue(resultLocals.get(returnType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getSha1Hex(String text) {
|
||||||
|
final MessageDigest digest;
|
||||||
|
try {
|
||||||
|
digest = MessageDigest.getInstance("SHA-1");
|
||||||
|
byte[] result = digest.digest(text.getBytes("UTF-8"));
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : result) {
|
||||||
|
sb.append(String.format("%02x", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
} catch (Exception e) {
|
||||||
|
DexLog.e("error hashing target method: " + text, e);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package com.elderdrivers.riru.xposed.dexmaker;
|
package com.elderdrivers.riru.xposed.dexmaker;
|
||||||
|
|
||||||
import com.elderdrivers.riru.xposed.Main;
|
import com.elderdrivers.riru.xposed.Main;
|
||||||
import com.elderdrivers.riru.xposed.util.FileUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
|
@ -72,8 +71,6 @@ public final class DynamicBridge {
|
||||||
if (!dexPathInited.compareAndSet(false, true)) {
|
if (!dexPathInited.compareAndSet(false, true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// delete previous compiled dex to prevent potential crashing
|
|
||||||
// TODO find a way to reuse them in consideration of performance
|
|
||||||
try {
|
try {
|
||||||
// we always choose to use device encrypted storage data on android N and later
|
// we always choose to use device encrypted storage data on android N and later
|
||||||
// in case some app is installing hooks before phone is unlocked
|
// in case some app is installing hooks before phone is unlocked
|
||||||
|
|
@ -83,10 +80,6 @@ public final class DynamicBridge {
|
||||||
dexOptDir = new File(dexDir, "oat");
|
dexOptDir = new File(dexDir, "oat");
|
||||||
dexDir.mkdirs();
|
dexDir.mkdirs();
|
||||||
DexLog.d(Main.appProcessName + " deleting dir: " + dexOptDir.getAbsolutePath());
|
DexLog.d(Main.appProcessName + " deleting dir: " + dexOptDir.getAbsolutePath());
|
||||||
try {
|
|
||||||
FileUtils.delete(dexOptDir);
|
|
||||||
} catch (Throwable throwable) {
|
|
||||||
}
|
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
DexLog.e("error when init dex path", throwable);
|
DexLog.e("error when init dex path", throwable);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,10 @@ public class HookerDexMaker {
|
||||||
public static final String METHOD_NAME_SETUP = "setup";
|
public static final String METHOD_NAME_SETUP = "setup";
|
||||||
public static final TypeId<Object[]> objArrayTypeId = TypeId.get(Object[].class);
|
public static final TypeId<Object[]> objArrayTypeId = TypeId.get(Object[].class);
|
||||||
private static final String CLASS_DESC_PREFIX = "L";
|
private static final String CLASS_DESC_PREFIX = "L";
|
||||||
private static final String CLASS_NAME_PREFIX = "EdHooker";
|
/**
|
||||||
|
* Note: this identifier is used in native codes to pass class access verification.
|
||||||
|
*/
|
||||||
|
private static final String CLASS_NAME_PREFIX = "EdHooker_";
|
||||||
private static final String FIELD_NAME_HOOK_INFO = "additionalHookInfo";
|
private static final String FIELD_NAME_HOOK_INFO = "additionalHookInfo";
|
||||||
private static final String FIELD_NAME_METHOD = "method";
|
private static final String FIELD_NAME_METHOD = "method";
|
||||||
private static final String PARAMS_FIELD_NAME_METHOD = "method";
|
private static final String PARAMS_FIELD_NAME_METHOD = "method";
|
||||||
|
|
@ -183,26 +186,30 @@ public class HookerDexMaker {
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.O)
|
@TargetApi(Build.VERSION_CODES.O)
|
||||||
private void doMake() throws Exception {
|
private void doMake() throws Exception {
|
||||||
|
final boolean useInMemoryCl = TextUtils.isEmpty(mDexDirPath);
|
||||||
mDexMaker = new DexMaker();
|
mDexMaker = new DexMaker();
|
||||||
// Generate a Hooker class.
|
|
||||||
String className = CLASS_NAME_PREFIX + sClassNameSuffix.getAndIncrement();
|
|
||||||
String classDesc = CLASS_DESC_PREFIX + className + ";";
|
|
||||||
mHookerTypeId = TypeId.get(classDesc);
|
|
||||||
mDexMaker.declare(mHookerTypeId, className + ".generated", Modifier.PUBLIC, TypeId.OBJECT);
|
|
||||||
generateFields();
|
|
||||||
generateSetupMethod();
|
|
||||||
generateBackupMethod();
|
|
||||||
generateHookMethod();
|
|
||||||
generateCallBackupMethod();
|
|
||||||
|
|
||||||
ClassLoader loader;
|
ClassLoader loader;
|
||||||
if (TextUtils.isEmpty(mDexDirPath)) {
|
// Generate a Hooker class.
|
||||||
// in memory dex classloader
|
String className = CLASS_NAME_PREFIX;
|
||||||
|
if (!useInMemoryCl) {
|
||||||
|
// if not using InMemoryDexClassLoader, className is also used as dex file name
|
||||||
|
// so it should be different from each other
|
||||||
|
String suffix = DexMakerUtils.getSha1Hex(mMember.toString());
|
||||||
|
if (TextUtils.isEmpty(suffix)) { // just in case
|
||||||
|
suffix = String.valueOf(sClassNameSuffix.getAndIncrement());
|
||||||
|
}
|
||||||
|
className = className + suffix;
|
||||||
|
if (!new File(mDexDirPath, className).exists()) {
|
||||||
|
// if file exists, reuse it and skip generating
|
||||||
|
doGenerate(className);
|
||||||
|
}
|
||||||
|
// load dex file from disk
|
||||||
|
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), className);
|
||||||
|
} else {
|
||||||
|
// do everything in memory
|
||||||
|
doGenerate(className);
|
||||||
byte[] dexBytes = mDexMaker.generate();
|
byte[] dexBytes = mDexMaker.generate();
|
||||||
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
|
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
|
||||||
} else {
|
|
||||||
// Create the dex file and load it.
|
|
||||||
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mHookClass = loader.loadClass(className);
|
mHookClass = loader.loadClass(className);
|
||||||
|
|
@ -216,6 +223,17 @@ public class HookerDexMaker {
|
||||||
HookMain.backupAndHook(mMember, mHookMethod, mBackupMethod);
|
HookMain.backupAndHook(mMember, mHookMethod, mBackupMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doGenerate(String className) {
|
||||||
|
String classDesc = CLASS_DESC_PREFIX + className + ";";
|
||||||
|
mHookerTypeId = TypeId.get(classDesc);
|
||||||
|
mDexMaker.declare(mHookerTypeId, className + ".generated", Modifier.PUBLIC, TypeId.OBJECT);
|
||||||
|
generateFields();
|
||||||
|
generateSetupMethod();
|
||||||
|
generateBackupMethod();
|
||||||
|
generateHookMethod();
|
||||||
|
generateCallBackupMethod();
|
||||||
|
}
|
||||||
|
|
||||||
public Method getHookMethod() {
|
public Method getHookMethod() {
|
||||||
return mHookMethod;
|
return mHookMethod;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
|
import org.gradle.internal.os.OperatingSystem;
|
||||||
|
|
||||||
apply plugin: 'com.android.library'
|
apply plugin: 'com.android.library'
|
||||||
version "v0.3.1.2_beta"
|
version "v0.3.1.5_beta-SNAPSHOT"
|
||||||
extensions["module_name"] = "EdXposed"
|
extensions["module_name"] = "EdXposed"
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 28
|
||||||
|
|
@ -28,30 +30,24 @@ afterEvaluate {
|
||||||
|
|
||||||
def zipTask = task("zip${nameCapped}", type: Exec, dependsOn: ":Bridge:makeAndCopy${nameCapped}") {
|
def zipTask = task("zip${nameCapped}", type: Exec, dependsOn: ":Bridge:makeAndCopy${nameCapped}") {
|
||||||
workingDir '..'
|
workingDir '..'
|
||||||
commandLine 'sh', 'build.sh',\
|
commandLine 'sh', 'build.sh', \
|
||||||
project.name,\
|
project.name, \
|
||||||
"${project.version}-${nameLowered}",\
|
"${project.version}-${nameLowered}", \
|
||||||
"${project.extensions['module_name']}"
|
"${project.extensions['module_name']}"
|
||||||
}
|
}
|
||||||
|
|
||||||
// def renameTask = task("build${nameCapped}", type: Copy) {
|
|
||||||
// from "release/magisk-${project.name}-${project.version}.zip"
|
|
||||||
// into "release"
|
|
||||||
// rename("${project.name}", "${project.extensions['module_name']}")
|
|
||||||
// rename("${project.version}", "${project.version}-${nameLowered}")
|
|
||||||
// }
|
|
||||||
|
|
||||||
def pushTask = task("push${nameCapped}", type: Exec) {
|
def pushTask = task("push${nameCapped}", type: Exec) {
|
||||||
workingDir 'release'
|
workingDir 'release'
|
||||||
commandLine 'cmd', '/c',
|
def commands = ["adb", "push", "magisk-${project.extensions['module_name']}" +
|
||||||
"adb push magisk-${project.extensions['module_name']}" +
|
"-${project.version}-${nameLowered}.zip", "/sdcard/"]
|
||||||
"-${project.version}-${nameLowered}.zip /sdcard/"
|
if (OperatingSystem.current().isWindows()) {
|
||||||
|
commandLine 'cmd', '/c', commands.join(" ")
|
||||||
|
} else {
|
||||||
|
commandLine commands
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// renameTask.dependsOn(zipTask)
|
|
||||||
pushTask.dependsOn(zipTask)
|
pushTask.dependsOn(zipTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
dependencies {
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ LOCAL_LDFLAGS := -Wl
|
||||||
LOCAL_SRC_FILES:= \
|
LOCAL_SRC_FILES:= \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
native_hook/native_hook.cpp \
|
native_hook/native_hook.cpp \
|
||||||
|
native_hook/riru_hook.cpp \
|
||||||
include/misc.cpp \
|
include/misc.cpp \
|
||||||
include/riru.c \
|
include/riru.c \
|
||||||
yahfa/HookMain.c \
|
yahfa/HookMain.c \
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
#include "include/logging.h"
|
#include "include/logging.h"
|
||||||
#include "native_hook.h"
|
#include "native_hook.h"
|
||||||
|
#include "riru_hook.h"
|
||||||
|
|
||||||
static bool inlineHooksInstalled = false;
|
static bool inlineHooksInstalled = false;
|
||||||
|
|
||||||
|
|
@ -51,8 +52,9 @@ static bool onIsInSamePackageCalled(void *thiz, void *that) {
|
||||||
std::string storage1, storage2;
|
std::string storage1, storage2;
|
||||||
const char *thisDesc = (*getDesc)(thiz, &storage1);
|
const char *thisDesc = (*getDesc)(thiz, &storage1);
|
||||||
const char *thatDesc = (*getDesc)(that, &storage2);
|
const char *thatDesc = (*getDesc)(that, &storage2);
|
||||||
if (strstr(thisDesc, "EdHooker") != nullptr
|
// Note: these identifiers should be consistent with those in Java layer
|
||||||
|| strstr(thatDesc, "EdHooker") != nullptr
|
if (strstr(thisDesc, "EdHooker_") != nullptr
|
||||||
|
|| strstr(thatDesc, "EdHooker_") != nullptr
|
||||||
|| strstr(thisDesc, "com/elderdrivers/riru/") != nullptr
|
|| strstr(thisDesc, "com/elderdrivers/riru/") != nullptr
|
||||||
|| strstr(thatDesc, "com/elderdrivers/riru/") != nullptr) {
|
|| strstr(thatDesc, "com/elderdrivers/riru/") != nullptr) {
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -272,6 +274,7 @@ void install_inline_hooks() {
|
||||||
LOGE("api level not supported: %d, skip", api_level);
|
LOGE("api level not supported: %d, skip", api_level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
install_riru_hooks();
|
||||||
LOGI("using api level %d", api_level);
|
LOGI("using api level %d", api_level);
|
||||||
void *whaleHandle = dlopen(kLibWhalePath, RTLD_LAZY | RTLD_GLOBAL);
|
void *whaleHandle = dlopen(kLibWhalePath, RTLD_LAZY | RTLD_GLOBAL);
|
||||||
if (!whaleHandle) {
|
if (!whaleHandle) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,82 @@
|
||||||
|
//
|
||||||
|
// Created by solo on 2019/3/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <include/riru.h>
|
||||||
|
#include <xhook/xhook.h>
|
||||||
|
#include <sys/system_properties.h>
|
||||||
|
#include <include/logging.h>
|
||||||
|
#include <include/android_build.h>
|
||||||
|
#include "riru_hook.h"
|
||||||
|
|
||||||
|
#define PROP_KEY_COMPILER_FILTER "dalvik.vm.dex2oat-filter"
|
||||||
|
#define PROP_KEY_COMPILER_FLAGS "dalvik.vm.dex2oat-flags"
|
||||||
|
#define PROP_VALUE_COMPILER_FILTER "quicken"
|
||||||
|
#define PROP_VALUE_COMPILER_FLAGS "--inline-max-code-units=0"
|
||||||
|
|
||||||
|
#define XHOOK_REGISTER(NAME) \
|
||||||
|
if (xhook_register(".*", #NAME, (void*) new_##NAME, (void **) &old_##NAME) == 0) { \
|
||||||
|
if (riru_get_version() >= 8) { \
|
||||||
|
void *f = riru_get_func(#NAME); \
|
||||||
|
if (f != nullptr) { \
|
||||||
|
memcpy(&old_##NAME, &f, sizeof(void *)); \
|
||||||
|
} \
|
||||||
|
riru_set_func(#NAME, (void *) new_##NAME); \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
LOGE("failed to register riru hook " #NAME "."); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NEW_FUNC_DEF(ret, func, ...) \
|
||||||
|
static ret (*old_##func)(__VA_ARGS__); \
|
||||||
|
static ret new_##func(__VA_ARGS__)
|
||||||
|
|
||||||
|
NEW_FUNC_DEF(int, __system_property_get, const char *key, char *value) {
|
||||||
|
int res = old___system_property_get(key, value);
|
||||||
|
if (key) {
|
||||||
|
if (strcmp(PROP_KEY_COMPILER_FILTER, key) == 0) {
|
||||||
|
strcpy(value, PROP_VALUE_COMPILER_FILTER);
|
||||||
|
LOGI("system_property_get: %s -> %s", key, value);
|
||||||
|
} else if (strcmp(PROP_KEY_COMPILER_FLAGS, key) == 0) {
|
||||||
|
strcpy(value, PROP_VALUE_COMPILER_FLAGS);
|
||||||
|
LOGI("system_property_get: %s -> %s", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
NEW_FUNC_DEF(std::string,
|
||||||
|
_ZN7android4base11GetPropertyERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_,
|
||||||
|
const std::string &key, const std::string &default_value) {
|
||||||
|
std::string res = old__ZN7android4base11GetPropertyERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_(
|
||||||
|
key, default_value);
|
||||||
|
if (strcmp(PROP_KEY_COMPILER_FILTER, key.c_str()) == 0) {
|
||||||
|
res = PROP_VALUE_COMPILER_FILTER;
|
||||||
|
LOGI("android::base::GetProperty: %s -> %s", key.c_str(), res.c_str());
|
||||||
|
} else if (strcmp(PROP_KEY_COMPILER_FLAGS, key.c_str()) == 0) {
|
||||||
|
res = PROP_VALUE_COMPILER_FLAGS;
|
||||||
|
LOGI("android::base::GetProperty: %s -> %s", key.c_str(), res.c_str());
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void install_riru_hooks() {
|
||||||
|
|
||||||
|
LOGI("install riru hook");
|
||||||
|
|
||||||
|
XHOOK_REGISTER(__system_property_get);
|
||||||
|
|
||||||
|
if (GetAndroidApiLevel() >= ANDROID_P) {
|
||||||
|
XHOOK_REGISTER(
|
||||||
|
_ZN7android4base11GetPropertyERKNSt3__112basic_stringIcNS1_11char_traitsIcEENS1_9allocatorIcEEEES9_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xhook_refresh(0) == 0) {
|
||||||
|
xhook_clear();
|
||||||
|
LOGI("riru hooks installed");
|
||||||
|
} else {
|
||||||
|
LOGE("failed to install riru hooks");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
//
|
||||||
|
// Created by solo on 2019/3/16.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef EDXPOSED_RIRU_HOOK_H
|
||||||
|
#define EDXPOSED_RIRU_HOOK_H
|
||||||
|
|
||||||
|
void install_riru_hooks();
|
||||||
|
|
||||||
|
#endif //EDXPOSED_RIRU_HOOK_H
|
||||||
|
|
@ -22,4 +22,4 @@ supolicy --live "allow zygote apk_data_file * *"
|
||||||
|
|
||||||
. ${MODDIR}/util_functions.sh
|
. ${MODDIR}/util_functions.sh
|
||||||
|
|
||||||
start_verbose_log_catcher
|
start_log_catchers
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#!/system/bin/sh
|
#!/system/bin/sh
|
||||||
|
|
||||||
EDXP_VERSION="0.3.1.2_beta (3120)"
|
EDXP_VERSION="0.3.1.5_beta-SNAPSHOT (3150)"
|
||||||
ANDROID_SDK=`getprop ro.build.version.sdk`
|
ANDROID_SDK=`getprop ro.build.version.sdk`
|
||||||
BUILD_DESC=`getprop ro.build.description`
|
BUILD_DESC=`getprop ro.build.description`
|
||||||
PRODUCT=`getprop ro.build.product`
|
PRODUCT=`getprop ro.build.product`
|
||||||
|
|
@ -23,32 +23,40 @@ setup_log_path () {
|
||||||
else
|
else
|
||||||
PATH_PREFIX=${PATH_PREFIX_LEGACY}
|
PATH_PREFIX=${PATH_PREFIX_LEGACY}
|
||||||
fi
|
fi
|
||||||
BASE_PATH=${PATH_PREFIX}${EDXP_INSTALLER}
|
DEFAULT_BASE_PATH=${PATH_PREFIX}${EDXP_INSTALLER}
|
||||||
if [[ -d ${BASE_PATH} ]]
|
BASE_PATH=${DEFAULT_BASE_PATH}
|
||||||
|
if [[ ! -d ${BASE_PATH} ]]
|
||||||
then
|
then
|
||||||
LOG_PATH=${BASE_PATH}/log
|
|
||||||
else
|
|
||||||
BASE_PATH=${PATH_PREFIX}${EDXP_MANAGER}
|
BASE_PATH=${PATH_PREFIX}${EDXP_MANAGER}
|
||||||
if [[ -d ${BASE_PATH} ]]
|
if [[ ! -d ${BASE_PATH} ]]
|
||||||
then
|
then
|
||||||
LOG_PATH=${BASE_PATH}/log
|
|
||||||
else
|
|
||||||
BASE_PATH=${PATH_PREFIX}${XP_INSTALLER}
|
BASE_PATH=${PATH_PREFIX}${XP_INSTALLER}
|
||||||
if [[ -d ${BASE_PATH} ]]
|
if [[ ! -d ${BASE_PATH} ]]
|
||||||
then
|
then
|
||||||
LOG_PATH=${BASE_PATH}/log
|
BASE_PATH=${DEFAULT_BASE_PATH}
|
||||||
else
|
|
||||||
LOG_PATH=${BASE_PATH}/log
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
LOG_PATH=${BASE_PATH}/log
|
||||||
|
CONF_PATH=${BASE_PATH}/conf
|
||||||
|
DISABLE_VERBOSE_LOG_FILE=${CONF_PATH}/disable_verbose_log
|
||||||
|
LOG_VERBOSE=true
|
||||||
|
if [[ -f ${DISABLE_VERBOSE_LOG_FILE} ]]; then LOG_VERBOSE=false; fi
|
||||||
}
|
}
|
||||||
|
|
||||||
start_log_cather () {
|
start_log_cather () {
|
||||||
LOG_FILE_NAME=$1
|
LOG_FILE_NAME=$1
|
||||||
|
LOG_TAG_FILTERS=$2
|
||||||
|
CLEAN_OLD=$3
|
||||||
|
START_NEW=$4
|
||||||
LOG_FILE=${LOG_PATH}/${LOG_FILE_NAME}
|
LOG_FILE=${LOG_PATH}/${LOG_FILE_NAME}
|
||||||
mkdir -p ${LOG_PATH}
|
mkdir -p ${LOG_PATH}
|
||||||
rm -rf ${LOG_FILE}
|
if [[ ${CLEAN_OLD} = true ]]; then
|
||||||
|
rm -rf ${LOG_FILE}
|
||||||
|
fi
|
||||||
|
if [[ ${START_NEW} = false ]]; then
|
||||||
|
return
|
||||||
|
fi
|
||||||
touch ${LOG_FILE}
|
touch ${LOG_FILE}
|
||||||
chmod 777 ${LOG_FILE}
|
chmod 777 ${LOG_FILE}
|
||||||
echo "--------- beginning of head">>${LOG_FILE}
|
echo "--------- beginning of head">>${LOG_FILE}
|
||||||
|
|
@ -67,11 +75,20 @@ start_log_cather () {
|
||||||
echo "Manufacture: ${MANUFACTURE}">>${LOG_FILE}
|
echo "Manufacture: ${MANUFACTURE}">>${LOG_FILE}
|
||||||
echo "Brand: ${BRAND}">>${LOG_FILE}
|
echo "Brand: ${BRAND}">>${LOG_FILE}
|
||||||
echo "Product: ${PRODUCT}">>${LOG_FILE}
|
echo "Product: ${PRODUCT}">>${LOG_FILE}
|
||||||
logcat -f ${LOG_FILE} *:S logcatcher-xposed-mlgmxyysd:S EdXposed-Fwk:V EdXposed-dexmaker:V XSharedPreferences:V EdXposed-Bridge:V EdXposed-YAHFA:V EdXposed-Core-Native:V xhook:V Riru:V RiruManager:V EdXposed-Manager:V XposedInstaller:V &
|
logcat -f ${LOG_FILE} *:S ${LOG_TAG_FILTERS} &
|
||||||
}
|
}
|
||||||
|
|
||||||
start_verbose_log_catcher () {
|
start_verbose_log_catcher () {
|
||||||
start_log_cather error.log
|
start_log_cather all.log "EdXposed-Fwk:V EdXposed-dexmaker:V XSharedPreferences:V EdXposed-Bridge:V EdXposed-YAHFA:V EdXposed-Core-Native:V EdXposed-Manager:V XposedInstaller:V" true ${LOG_VERBOSE}
|
||||||
|
}
|
||||||
|
|
||||||
|
start_bridge_log_catcher () {
|
||||||
|
start_log_cather error.log "XSharedPreferences:V EdXposed-Bridge:V" true true
|
||||||
|
}
|
||||||
|
|
||||||
|
start_log_catchers () {
|
||||||
|
start_bridge_log_catcher
|
||||||
|
start_verbose_log_catcher
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_log_path
|
setup_log_path
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ LATESTARTSERVICE=false
|
||||||
|
|
||||||
print_modname() {
|
print_modname() {
|
||||||
ui_print "************************************"
|
ui_print "************************************"
|
||||||
ui_print " Riru - Ed Xposed v0.3.1.2 "
|
ui_print " Riru - Ed Xposed v0.3.1.5 "
|
||||||
ui_print "************************************"
|
ui_print "************************************"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
id=riru_edxposed
|
id=riru_edxposed
|
||||||
name=Riru - Ed Xposed
|
name=Riru - Ed Xposed
|
||||||
version=v0.3.1.2_beta
|
version=v0.3.1.5_beta-SNAPSHOT
|
||||||
versionCode=3120
|
versionCode=3150
|
||||||
author=solohsu & MlgmXyysd
|
author=solohsu & MlgmXyysd
|
||||||
description=Magisk version of Xposed. Require Riru - Core installed.
|
description=Magisk version of Xposed. Require Riru - Core installed.
|
||||||
minMagisk=17000
|
minMagisk=17000
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
name=Ed Xposed
|
name=Ed Xposed
|
||||||
version=v0.3.1.2_beta
|
version=v0.3.1.5_beta-SNAPSHOT
|
||||||
versionCode=3120
|
versionCode=3150
|
||||||
author=solohsu & MlgmXyysd
|
author=solohsu & MlgmXyysd
|
||||||
description=Magisk version of Xposed. Require Riru - Core installed.
|
description=Magisk version of Xposed. Require Riru - Core installed.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
version=90.0-0.3.1.2-beta
|
version=90.0-0.3.1.5-beta-SNAPSHOT
|
||||||
arch=arm64
|
arch=arm64
|
||||||
minsdk=23
|
minsdk=23
|
||||||
maxsdk=28
|
maxsdk=28
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
||||||
# EdXposed
|
# EdXposed
|
||||||
|
|
||||||
A Riru module trying to provide a ART hooking framework (mainly for Android Pie) which delivers consistent APIs with the OG Xposed, leveraging YAHFA hooking framework.
|
A Riru module trying to provide a ART hooking framework (initially for Android Pie) which delivers consistent APIs with the OG Xposed, leveraging YAHFA hooking framework.
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
|
||||||
|
|
@ -11,6 +11,13 @@ A Riru module trying to provide a ART hooking framework (mainly for Android Pie)
|
||||||
- [dexmaker](https://github.com/linkedin/dexmaker) and [dalvikdx](https://github.com/JakeWharton/dalvik-dx): dynamiclly generate YAHFA hooker classes
|
- [dexmaker](https://github.com/linkedin/dexmaker) and [dalvikdx](https://github.com/JakeWharton/dalvik-dx): dynamiclly generate YAHFA hooker classes
|
||||||
- [Whale](https://github.com/asLody/whale): used for inline hooking
|
- [Whale](https://github.com/asLody/whale): used for inline hooking
|
||||||
|
|
||||||
|
## Supported versions
|
||||||
|
|
||||||
|
- Android Oreo (8.0, 8.1)
|
||||||
|
- Android Pie (9.0)
|
||||||
|
|
||||||
|
For devices with Android 7.x and lower, original Xposed is strongly recommended.
|
||||||
|
|
||||||
## Known issues
|
## Known issues
|
||||||
|
|
||||||
- resources hooking is not supported yet
|
- resources hooking is not supported yet
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,10 @@ public final class DexMaker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException {
|
||||||
|
return generateAndLoad(parent, dexCache, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a dex file and loads its types into the current process.
|
* Generates a dex file and loads its types into the current process.
|
||||||
*
|
*
|
||||||
|
|
@ -496,8 +500,9 @@ public final class DexMaker {
|
||||||
* @param dexCache the destination directory where generated and optimized
|
* @param dexCache the destination directory where generated and optimized
|
||||||
* dex files will be written. If null, this class will try to guess the
|
* dex files will be written. If null, this class will try to guess the
|
||||||
* application's private data dir.
|
* application's private data dir.
|
||||||
|
* @param fileName the name of dex file
|
||||||
*/
|
*/
|
||||||
public ClassLoader generateAndLoad(ClassLoader parent, File dexCache) throws IOException {
|
public ClassLoader generateAndLoad(ClassLoader parent, File dexCache, String fileName) throws IOException {
|
||||||
if (dexCache == null) {
|
if (dexCache == null) {
|
||||||
String property = System.getProperty("dexmaker.dexcache");
|
String property = System.getProperty("dexmaker.dexcache");
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
|
|
@ -511,7 +516,9 @@ public final class DexMaker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File result = new File(dexCache, generateFileName());
|
if (fileName == null || fileName.isEmpty())
|
||||||
|
fileName = generateFileName();
|
||||||
|
File result = new File(dexCache, fileName);
|
||||||
// Check that the file exists. If it does, return a DexClassLoader and skip all
|
// Check that the file exists. If it does, return a DexClassLoader and skip all
|
||||||
// the dex bytecode generation.
|
// the dex bytecode generation.
|
||||||
if (result.exists()) {
|
if (result.exists()) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue