Replace whale with dobby

This commit is contained in:
LoveSy 2020-11-25 18:54:41 +08:00 committed by 双草酸酯
parent 103c7aa867
commit d34c76e119
38 changed files with 21 additions and 536 deletions

View File

@ -101,6 +101,5 @@ Notice: These community group don't accept any bug report, please use [Get help]
- [Riru](https://github.com/RikkaApps/Riru): provides a way to inject codes into zygote process
- [XposedBridge](https://github.com/rovo89/XposedBridge): the OG xposed framework APIs
- [dexmaker](https://github.com/linkedin/dexmaker) and [dalvikdx](https://github.com/JakeWharton/dalvik-dx): to dynamiclly generate YAHFA hooker classes
- [Whale](https://github.com/asLody/whale): used for inline hooking
- [SandHook](https://github.com/ganyao114/SandHook/): ART hooking framework for SandHook variant
- [Dobby](https://github.com/jmpews/Dobby): used for inline hooking

View File

@ -91,6 +91,6 @@ Edxposed 拥有三个不同的版本
- [Riru](https://github.com/RikkaApps/Riru): 提供一种将代码注入 zygote 进程的方法
- [XposedBridge](https://github.com/rovo89/XposedBridge): 原版 xposed 框架的 API
- [dexmaker](https://github.com/linkedin/dexmaker) 和 [dalvikdx](https://github.com/JakeWharton/dalvik-dx): 动态生成 YAHFA hook 类
- [Whale](https://github.com/asLody/whale): 用于 hook 内联方法
- [SandHook](https://github.com/ganyao114/SandHook/): SandHook 分支的 ART hooking 框架
- [Dobby](https://github.com/jmpews/Dobby): 用于 hook 内联方法

View File

@ -36,7 +36,6 @@ only_commits:
- edxp-common/
- edxp-core/
- edxp-sandhook/
- edxp-whale/
- edxp-yahfa/
- hiddenapi-stubs/
- xposed-bridge/

View File

@ -27,10 +27,6 @@ public class BaseEdxpConfig implements EdxpConfig {
public String getLibSandHookName() {
return ConfigManager.getLibSandHookName();
}
@Override
public String getLibWhaleName() {
return ConfigManager.getLibWhaleName();
}
@Override
public boolean isDynamicModulesMode() {

View File

@ -43,8 +43,6 @@ public class ConfigManager {
public static native String getLibSandHookName();
public static native String getLibWhaleName();
public static native String getInstallerConfigPath(String suffix);
public static native String getDataPathPrefix();

View File

@ -15,7 +15,6 @@ public interface EdxpImpl extends KeepAll {
int NONE = 0;
int YAHFA = 1;
int SANDHOOK = 2;
int WHALE = 3;
@NonNull
Proxy getNormalProxy();
@ -31,7 +30,7 @@ public interface EdxpImpl extends KeepAll {
boolean isInitialized();
@Retention(SOURCE)
@IntDef({NONE, YAHFA, SANDHOOK, WHALE})
@IntDef({NONE, YAHFA, SANDHOOK})
@interface Variant {
}
}

View File

@ -84,10 +84,5 @@ public class Main implements KeepAll {
}catch(Throwable ignored) {
Utils.logD("not using yahfa");
}
try {
Class.forName("com.elderdrivers.riru.edxp.whale.core.WhaleEdxpImpl");
}catch(Throwable ignored) {
Utils.logD("not found whale");
}
}
}

View File

@ -6,5 +6,6 @@
/template_override/module.prop
/template_override/system
/template_override/system_x86
/template_override/riru/module.prop.new
*.iml
/.cxx
/.cxx

View File

@ -24,13 +24,11 @@ ext {
module_name = "EdXposed"
jar_dest_dir = "${projectDir}/template_override/system/framework/"
is_windows = OperatingSystem.current().isWindows()
backends = ["YAHFA", "SandHook", "Whale"]
backends = ["YAHFA", "SandHook"]
yahfa_module_id = "riru_edxposed"
sandhook_module_id = yahfa_module_id + "_sandhook"
whale_module_id = yahfa_module_id + "_whale"
yahfa_authors = "solohsu, MlgmXyysd & rk700"
sandhook_authors = "solohsu, MlgmXyysd & ganyao114"
whale_authors = "solohsu, MlgmXyysd & asLody"
riruModuleId = "edxp"
zipPathMagiskRelease = "$buildDir/tmp/release/magisk"

View File

@ -103,7 +103,6 @@ remove_edxposed() {
ui_print "- Deleting EdXposed..."
rm -r -f /data/adb/modules/riru_edxposed/
rm -r -f /data/adb/modules/riru_edxposed_sandhook/
rm -r -f /data/adb/modules/riru_edxposed_whale/
rm -r -f /data/misc/riru/modules/edxposed/
rm -r -f /data/misc/riru/modules/edxp/
ui_print "- Done"

View File

@ -1,14 +0,0 @@
#ifndef WHALE_ANDROID_ANDROID_BUILD_H_
#define WHALE_ANDROID_ANDROID_BUILD_H_
#include <cstdint>
#include <cstdlib>
#include <sys/system_properties.h>
static inline int32_t GetAndroidApiLevel() {
char prop_value[PROP_VALUE_MAX];
__system_property_get("ro.build.version.sdk", prop_value);
return atoi(prop_value);
}
#endif // WHALE_ANDROID_ANDROID_BUILD_H_

View File

@ -66,7 +66,7 @@ namespace art {
static void Setup(void *handle, HookFunType hook_func) {
LOGD("Classlinker hook setup, handle=%p", handle);
// TODO: Maybe not compatible with Android 10-
int api_level = GetAndroidApiLevel();
int api_level = edxp::GetAndroidApiLevel();
size_t OFFSET_classlinker; // Get offset from art::Runtime::RunRootClinits() call in IDA
switch(api_level) {
case __ANDROID_API_O__:

View File

@ -32,7 +32,7 @@ namespace art {
// @ApiSensitive(Level.HIGH)
static void DisableHiddenApi(void *handle, HookFunType hook_func) {
const int api_level = GetAndroidApiLevel();
const int api_level = edxp::GetAndroidApiLevel();
if (api_level < __ANDROID_API_P__) {
return;
}

View File

@ -14,7 +14,7 @@ namespace art {
// @ApiSensitive(Level.LOW)
// http://androidxref.com/9.0.0_r3/xref/art/runtime/oat_file_manager.cc#637
static void DisableOnlyUseSystemOatFiles(void *handle, HookFunType hook_func) {
const int api_level = GetAndroidApiLevel();
const int api_level = edxp::GetAndroidApiLevel();
if (api_level >= __ANDROID_API_P__) {
HOOK_FUNC(SetOnlyUseSystemOatFiles,
"_ZN3art14OatFileManager24SetOnlyUseSystemOatFilesEv", // 9 & 11

View File

@ -5,7 +5,6 @@
#include <sys/types.h>
#include <string>
#include "art/base/macros.h"
#include "android_build.h"
#include "utils.h"
namespace edxp {
@ -30,7 +29,6 @@ namespace edxp {
static const auto kLibArtName = "libart.so"_str;
static const auto kLibFwName = "libandroidfw.so"_str;
static const auto kLibWhaleName = "libwhale.edxp.so"_str;
static const auto kLibSandHookName = "libsandhook.edxp.so"_str;
static const auto kLibDlName = "libdl.so"_str;
static const auto kLibSandHookNativeName = "libsandhook-native.so"_str;

View File

@ -6,8 +6,16 @@
#include <string>
#include <filesystem>
#include "logging.h"
#include <sys/system_properties.h>
namespace edxp {
static inline int32_t GetAndroidApiLevel() {
char prop_value[PROP_VALUE_MAX];
__system_property_get("ro.build.version.sdk", prop_value);
return atoi(prop_value);
}
inline const std::string operator ""_str(const char *str, std::size_t size) {
return {str, size};
}

View File

@ -12,13 +12,13 @@
#include <vector>
#include <string>
#include <android_build.h>
#include <logging.h>
#include <climits>
#include <fstream>
#include <sstream>
#include "art/runtime/native/native_util.h"
#include "config_manager.h"
#include "utils.h"
namespace edxp {
namespace fs = std::filesystem;

View File

@ -48,8 +48,6 @@ namespace edxp {
inline auto GetLibSandHookName() const { return kLibSandHookName; }
inline auto GetLibWhaleName() const { return kLibWhaleName; }
inline auto GetDataPathPrefix() const { return data_path_prefix_; }
inline auto GetConfigPath(const std::string &suffix) const {

View File

@ -15,7 +15,6 @@ namespace edxp {
NONE = 0,
YAHFA = 1,
SANDHOOK = 2,
WHALE = 3
};
class Context {

View File

@ -35,10 +35,6 @@ namespace edxp {
return env->NewStringUTF(ConfigManager::GetInstance()->GetXposedPropPath().c_str());
}
static jstring ConfigManager_getLibWhaleName(JNI_START) {
return env->NewStringUTF(ConfigManager::GetInstance()->GetLibWhaleName().c_str());
}
static jstring ConfigManager_getLibSandHookName(JNI_START) {
return env->NewStringUTF(ConfigManager::GetInstance()->GetLibSandHookName().c_str());
}
@ -73,7 +69,6 @@ namespace edxp {
NATIVE_METHOD(ConfigManager, getInstallerPackageName, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getXposedPropPath, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getLibSandHookName, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getLibWhaleName, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getDataPathPrefix, "()Ljava/lang/String;"),
NATIVE_METHOD(ConfigManager, getInstallerConfigPath,
"(Ljava/lang/String;)Ljava/lang/String;"),

View File

@ -1,6 +1,5 @@
#include <dlfcn.h>
#include <android_build.h>
#include <string>
#include <vector>
#include <config_manager.h>
@ -9,7 +8,7 @@
#include <art/runtime/jni_env_ext.h>
#include <dobby.h>
#include "android_restriction.h" // from Dobby
#include "utils.h"
#include "logging.h"
#include "native_hook.h"
#include "riru_hook.h"

View File

@ -8,7 +8,7 @@
#include <xhook.h>
#include <sys/system_properties.h>
#include <logging.h>
#include <android_build.h>
#include "utils.h"
#include "riru_hook.h"
namespace edxp {

View File

@ -49,10 +49,6 @@ JAR_EDDEXMAKER="$(getRandomNameExist 8 "" ".dex" "
#/system/framework
#").jar"
LIB_RIRU_EDXP="libriru_${RIRU_EDXP}.so"
LIB_WHALE_EDXP="lib$(getRandomNameExist 10 "lib" ".so" "
/system/lib
/system/lib64
").so"
LIB_SANDHOOK_EDXP="lib$(getRandomNameExist 13 "lib" ".so" "
/system/lib
/system/lib64
@ -272,12 +268,10 @@ mv "${MODPATH}/system/framework/edxp.dex" "${MODPATH}/system/framework/${JAR_EDX
mv "${MODPATH}/system/framework/eddexmaker.dex" "${MODPATH}/system/framework/${JAR_EDDEXMAKER}"
#mv "${MODPATH}/system/framework/edconfig.jar" "${MODPATH}/system/framework/${JAR_EDCONFIG}"
mv "${MODPATH}/system/lib/libriru_edxp.so" "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
#mv "${MODPATH}/system/lib/libwhale.edxp.so" "${MODPATH}/system/lib/${LIB_WHALE_EDXP}"
mv "${MODPATH}/system/lib/libsandhook-native.so" "${MODPATH}/system/lib/libsandhook-native.so"
if [[ "${IS64BIT}" == true ]]; then
mv "${MODPATH}/system/lib64/libriru_edxp.so" "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
#mv "${MODPATH}/system/lib64/libwhale.edxp.so" "${MODPATH}/system/lib64/${LIB_WHALE_EDXP}"
mv "${MODPATH}/system/lib64/libsandhook-native.so" "${MODPATH}/system/lib64/libsandhook-native.so"
fi
@ -293,14 +287,12 @@ ui_print "- Resetting libraries path"
sed -i 's:/system/framework/edxp.dex\:/system/framework/eddalvikdx.dex\:/system/framework/eddexmaker.dex:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
#sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
sed -i 's:libriru_edxp.so:'"${LIB_RIRU_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
#sed -i 's:libwhale.edxp.so:'"${LIB_WHALE_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
sed -i 's:libsandhook.edxp.so:'"${LIB_SANDHOOK_EDXP}"':g' "${MODPATH}/system/lib/${LIB_RIRU_EDXP}"
if [[ "${IS64BIT}" == true ]]; then
sed -i 's:/system/framework/edxp.dex\:/system/framework/eddalvikdx.dex\:/system/framework/eddexmaker.dex:/system/framework/'"${JAR_EDXP}"'\:/system/framework/'"${JAR_EDDALVIKDX}"'\:/system/framework/'"${JAR_EDDEXMAKER}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
# sed -i 's:/system/framework/edconfig.jar:/system/framework/'"${JAR_EDCONFIG}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
sed -i 's:libriru_edxp.so:'"${LIB_RIRU_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
#sed -i 's:libwhale.edxp.so:'"${LIB_WHALE_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
sed -i 's:libsandhook.edxp.so:'"${LIB_SANDHOOK_EDXP}"':g' "${MODPATH}/system/lib64/${LIB_RIRU_EDXP}"
fi

View File

@ -1,6 +0,0 @@
name=Riru - EdXposed
version=v0.5.0.8 (YAHFA)
versionCode=233
author=solohsu, MlgmXyysd & rk700
description=Another enhanced implementation of Xposed Framework. Supports Android 8.0, 8.1, 9, 10 or above. Requires Riru - Core v19 or above installed. Telegram: @EdXposed
minApi=9

View File

@ -1,2 +0,0 @@
/build
/template_override/system/framework

View File

@ -1,71 +0,0 @@
apply plugin: 'com.android.application'
sourceCompatibility = "7"
targetCompatibility = "7"
android {
compileSdkVersion androidCompileSdkVersion.toInteger()
defaultConfig {
applicationId "com.elderdrivers.riru.edxp.whale"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
multiDexEnabled false
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
ndkVersion androidCompileNdkVersion
}
dependencies {
compileOnly project(':hiddenapi-stubs')
implementation project(':edxp-common')
compileOnly files(project(":dexmaker").tasks.getByName("makeJarRelease").outputs)
}
preBuild.doLast {
def imlFile = file(project.name + ".iml")
try {
def parsedXml = (new groovy.util.XmlParser()).parse(imlFile)
def jdkNode = parsedXml.component[1].orderEntry.find { it.'@type' == 'jdk' }
parsedXml.component[1].remove(jdkNode)
def sdkString = "Android API " + android.compileSdkVersion.substring("android-".length()) + " Platform"
new groovy.util.Node(parsedXml.component[1], 'orderEntry', ['type': 'jdk', 'jdkName': sdkString, 'jdkType': 'Android SDK'])
groovy.xml.XmlUtil.serialize(parsedXml, new FileOutputStream(imlFile))
} catch (FileNotFoundException e) {
// nop, iml not found
}
}
afterEvaluate {
tasks.withType(JavaCompile) {
options.compilerArgs.add("-Xbootclasspath/p:${hiddenApiStubJarFilePath}")
}
android.applicationVariants.all { variant ->
def variantNameCapped = variant.name.capitalize()
def variantNameLowered = variant.name.toLowerCase()
task("copyDex${variantNameCapped}", type: Copy) {
dependsOn "assemble${variantNameCapped}"
dependsOn tasks.getByPath(":edxp-common:copyCommonProperties")
def dexOutPath = "${buildDir}/intermediates/dex/${variantNameLowered}/minify${variantNameCapped}WithR8"
from (dexOutPath){
rename("classes.dex", "edxp.dex")
}
destinationDir file(templateRootPath + "system/framework/")
outputs.upToDateWhen { false }
}
}
}

View File

@ -1,38 +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
-dontoptimize
-dontobfuscate
-keep class de.robv.android.xposed.** {*;}
-keep class android.** { *; }
-keep interface com.elderdrivers.riru.common.KeepAll
-keep interface com.elderdrivers.riru.common.KeepMembers
-keep class * implements com.elderdrivers.riru.common.KeepAll { *; }
-keepclassmembers class * implements com.elderdrivers.riru.common.KeepMembers { *; }
-keep class com.lody.** {*;}
-keepclasseswithmembers class * {
native <methods>;
}

View File

@ -1 +0,0 @@
<manifest package="com.elderdrivers.riru.edxp.whale" />

View File

@ -1,7 +0,0 @@
package com.elderdrivers.riru.edxp.whale.config;
import com.elderdrivers.riru.edxp.config.BaseEdxpConfig;
public class WhaleEdxpConfig extends BaseEdxpConfig {
}

View File

@ -1,100 +0,0 @@
package com.elderdrivers.riru.edxp.whale.config;
import com.elderdrivers.riru.edxp.art.ClassLinker;
import com.elderdrivers.riru.edxp.art.Heap;
import com.elderdrivers.riru.edxp.config.BaseHookProvider;
import com.elderdrivers.riru.edxp.core.ResourcesHook;
import com.elderdrivers.riru.edxp.core.Yahfa;
import com.elderdrivers.riru.edxp.util.Utils;
import com.lody.whale.WhaleRuntime;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import static com.elderdrivers.riru.edxp.util.ClassUtils.shouldDelayHook;
public class WhaleHookProvider extends BaseHookProvider {
private static final Map<Member, Long> sHookedMethodSlotMap = new HashMap<>();
@Override
public void unhookMethod(Member method) {
synchronized (sHookedMethodSlotMap) {
sHookedMethodSlotMap.remove(method);
}
}
@Override
public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) {
// resolveStaticMethod(method);
long slot = WhaleRuntime.hookMethodNative(method.getDeclaringClass(), method, additionalInfo);
synchronized (sHookedMethodSlotMap) {
sHookedMethodSlotMap.put(method, slot);
}
}
@Override
public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable {
long slot = sHookedMethodSlotMap.get(method);
return WhaleRuntime.invokeOriginalMethodNative(slot, thisObject, args);
}
@Override
public Member findMethodNative(Member hookMethod) {
return shouldDelayHook(hookMethod) ? null : hookMethod;
}
@Override
public Object findMethodNative(Class clazz, String methodName, String methodSig) {
return Yahfa.findMethodNative(clazz, methodName, methodSig);
}
@Override
public void deoptMethodNative(Object method) {
ClassLinker.setEntryPointsToInterpreter((Member) method);
}
@Override
public long getMethodId(Member member) {
return WhaleRuntime.getMethodSlot(member);
}
@Override
public boolean initXResourcesNative() {
return ResourcesHook.initXResourcesNative();
}
@Override
public boolean removeFinalFlagNative(Class clazz) {
return ResourcesHook.removeFinalFlagNative(clazz);
}
/**
* the static method is lazy resolved, when not resolved, the entry point is a trampoline of
* a bridge, we can not hook these entry. this method force the static method to be resolved.
*/
public static void resolveStaticMethod(Member method) {
//ignore result, just call to trigger resolve
if (method == null)
return;
try {
if (method instanceof Method && Modifier.isStatic(method.getModifiers())) {
((Method) method).setAccessible(true);
((Method) method).invoke(new Object(), getFakeArgs((Method) method));
}
} catch (Exception ignored) {
// we should never make a successful call.
}
}
private static Object[] getFakeArgs(Method method) {
return method.getParameterTypes().length == 0 ? new Object[]{new Object()} : null;
}
}

View File

@ -1,39 +0,0 @@
package com.elderdrivers.riru.edxp.whale.core;
import android.os.Build;
import com.elderdrivers.riru.edxp.core.BaseEdxpImpl;
import com.elderdrivers.riru.edxp.core.EdxpImpl;
import com.elderdrivers.riru.edxp.core.Main;
import com.elderdrivers.riru.edxp.core.Yahfa;
import com.elderdrivers.riru.edxp.core.yahfa.HookMethodResolver;
import com.elderdrivers.riru.edxp.proxy.Router;
public class WhaleEdxpImpl extends BaseEdxpImpl {
static {
final EdxpImpl edxpImpl = new WhaleEdxpImpl();
if (Main.setEdxpImpl(edxpImpl)) {
edxpImpl.init();
}
}
@Override
protected Router createRouter() {
return new WhaleRouter();
}
@Override
public int getVariant() {
return WHALE;
}
@Override
public void init() {
Yahfa.init(Build.VERSION.SDK_INT);
HookMethodResolver.init();
getRouter().injectConfig();
setInitialized();
}
}

View File

@ -1,28 +0,0 @@
package com.elderdrivers.riru.edxp.whale.core;
import com.elderdrivers.riru.edxp.config.ConfigManager;
import com.elderdrivers.riru.edxp.config.EdXpConfigGlobal;
import com.elderdrivers.riru.edxp.framework.Zygote;
import com.elderdrivers.riru.edxp.proxy.BaseRouter;
import com.elderdrivers.riru.edxp.whale.config.WhaleEdxpConfig;
import com.elderdrivers.riru.edxp.whale.config.WhaleHookProvider;
public class WhaleRouter extends BaseRouter {
public void onEnterChildProcess() {
}
public void injectConfig() {
BaseRouter.useXposedApi = true;
EdXpConfigGlobal.sConfig = new WhaleEdxpConfig();
EdXpConfigGlobal.sHookProvider = new WhaleHookProvider();
// Zygote.allowFileAcrossFork("/system/lib/libwhale.edxp.so");
// Zygote.allowFileAcrossFork("/system/lib64/libwhale.edxp.so");
Zygote.allowFileAcrossFork("/system/lib/" + ConfigManager.getLibWhaleName());
Zygote.allowFileAcrossFork("/system/lib64/" + ConfigManager.getLibWhaleName());
Zygote.allowFileAcrossFork("/system/lib/libart.so");
Zygote.allowFileAcrossFork("/system/lib64/libart.so");
}
}

View File

@ -1,105 +0,0 @@
package com.lody.whale;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.HashMap;
/**
* @author Lody
*/
class VMHelper {
// Holds a mapping from Java type names to native type codes.
private static final HashMap<Class<?>, String> PRIMITIVE_TO_SIGNATURE;
static {
PRIMITIVE_TO_SIGNATURE = new HashMap<>(9);
PRIMITIVE_TO_SIGNATURE.put(byte.class, "B");
PRIMITIVE_TO_SIGNATURE.put(char.class, "C");
PRIMITIVE_TO_SIGNATURE.put(short.class, "S");
PRIMITIVE_TO_SIGNATURE.put(int.class, "I");
PRIMITIVE_TO_SIGNATURE.put(long.class, "J");
PRIMITIVE_TO_SIGNATURE.put(float.class, "F");
PRIMITIVE_TO_SIGNATURE.put(double.class, "D");
PRIMITIVE_TO_SIGNATURE.put(void.class, "V");
PRIMITIVE_TO_SIGNATURE.put(boolean.class, "Z");
}
/**
* Returns the internal name of {@code clazz} (also known as the
* descriptor).
*/
private static String getSignature(final Class<?> clazz) {
final String primitiveSignature = PRIMITIVE_TO_SIGNATURE.get(clazz);
if (primitiveSignature != null) {
return primitiveSignature;
} else if (clazz.isArray()) {
return "[" + getSignature(clazz.getComponentType());
} else {
return "L" + clazz.getName().replace('.', '/') + ";";
}
}
/**
* Returns the native type codes of {@code clazz}.
*/
private static String getShortyType(final Class<?> clazz) {
final String primitiveSignature = PRIMITIVE_TO_SIGNATURE.get(clazz);
if (primitiveSignature != null) {
return primitiveSignature;
}
return "L";
}
// @SuppressWarnings("ConstantConditions")
private static String getSignature(final Class<?> retType,
final Class<?>[] parameterTypes) {
final StringBuilder result = new StringBuilder();
result.append('(');
for (final Class<?> parameterType : parameterTypes) {
result.append(getSignature(parameterType));
}
result.append(")");
result.append(getSignature(retType));
return result.toString();
}
private static String getShorty(final Class<?> retType,
final Class<?>[] parameterTypes) {
final StringBuilder result = new StringBuilder();
result.append(getShortyType(retType));
for (final Class<?> parameterType : parameterTypes) {
result.append(getShortyType(parameterType));
}
return result.toString();
}
static String getSignature(final Member m) {
if (m instanceof Method) {
final Method md = (Method) m;
return getSignature(md.getReturnType(), md.getParameterTypes());
}
if (m instanceof Constructor) {
final Constructor<?> c = (Constructor<?>) m;
return getSignature(void.class, c.getParameterTypes());
}
return null;
}
static String getShorty(final Member m) {
if (m instanceof Method) {
final Method md = (Method) m;
return getShorty(md.getReturnType(), md.getParameterTypes());
}
if (m instanceof Constructor) {
final Constructor<?> c = (Constructor<?>) m;
return getShorty(void.class, c.getParameterTypes());
}
return null;
}
}

View File

@ -1,74 +0,0 @@
package com.lody.whale;
import android.os.Build;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import de.robv.android.xposed.XposedBridge;
/**
* @author Lody
* <p>
* NOTICE: Do not move or rename any methods in this class.
*/
public class WhaleRuntime {
static {
System.loadLibrary("whale.edxp");
}
private static String getShorty(Member member) {
return VMHelper.getShorty(member);
}
public static long[] countInstancesOfClasses(Class[] classes, boolean assignable) {
if (Build.VERSION.SDK_INT < 27) {
throw new UnsupportedOperationException("Not support countInstancesOfClasses on your device yet.");
}
try {
Class<?> clazz = Class.forName("dalvik.system.VMDebug");
Method method = clazz.getDeclaredMethod("countInstancesOfClasses", Class[].class, boolean.class);
return (long[]) method.invoke(null, classes, assignable);
} catch (Throwable e) {
throw new IllegalStateException(e);
}
}
public static Object[][] getInstancesOfClasses(Class[] classes, boolean assignable) {
if (Build.VERSION.SDK_INT < 28) {
throw new UnsupportedOperationException("Not support getInstancesOfClasses on your device yet.");
}
try {
Class<?> clazz = Class.forName("dalvik.system.VMDebug");
Method method = clazz.getDeclaredMethod("getInstancesOfClasses", Class[].class, boolean.class);
return (Object[][]) method.invoke(null, classes, assignable);
} catch (Throwable e) {
throw new IllegalStateException(e);
}
}
public static Object handleHookedMethod(Member member, long slot, Object additionInfo, Object thisObject, Object[] args) throws Throwable {
return XposedBridge.handleHookedMethod(member, slot, additionInfo, thisObject, args);
}
public static native Object invokeOriginalMethodNative(long slot, Object thisObject, Object[] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;
public static native long getMethodSlot(Member member) throws IllegalArgumentException;
public static native long hookMethodNative(Class<?> declClass, Member method, Object additionInfo);
public static native void setObjectClassNative(Object object, Class<?> parent);
public static native Object cloneToSubclassNative(Object object, Class<?> subClass);
public static native void removeFinalFlagNative(Class<?> cl);
public static native void enforceDisableHiddenAPIPolicy();
private static native void reserved0();
private static native void reserved1();
}

View File

@ -1 +0,0 @@
libwhale.edxp.so

Binary file not shown.

View File

@ -1 +1 @@
include ':edxp-core', ':xposed-bridge', ':hiddenapi-stubs', ':dexmaker', ':dalvikdx', ':edxp-common', ':edxp-yahfa', ':edxp-sandhook', ':edxp-whale'
include ':edxp-core', ':xposed-bridge', ':hiddenapi-stubs', ':dexmaker', ':dalvikdx', ':edxp-common', ':edxp-yahfa', ':edxp-sandhook'

View File

@ -12,8 +12,6 @@ public interface EdxpConfig {
String getLibSandHookName();
String getLibWhaleName();
boolean isDynamicModulesMode();
boolean isNoModuleLogEnabled();