Add an annotation to remind compatibility checking

This commit is contained in:
solohsu 2020-08-02 15:26:34 +08:00
parent b1838bf602
commit e12c40b408
50 changed files with 123 additions and 19 deletions

View File

@ -21,7 +21,7 @@ android {
dependencies {
compileOnly project(':hiddenapi-stubs')
implementation project(':xposed-bridge')
api project(':xposed-bridge')
compileOnly project(':dexmaker')
api "androidx.annotation:annotation:1.1.0-rc01"
}

View File

@ -4,7 +4,10 @@ import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.impl.HandleBindApp;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class HandleBindAppHooker implements KeepMembers {
public static String className = "android.app.ActivityThread";

View File

@ -8,7 +8,10 @@ import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.impl.LoadedApkCstr;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class LoadedApkConstructorHooker implements KeepMembers {
public static String className = "android.app.LoadedApk";
public static String methodName = "<init>";

View File

@ -5,7 +5,10 @@ import com.elderdrivers.riru.edxp._hooker.impl.OneplusWorkaround;
import com.elderdrivers.riru.edxp.core.yahfa.HookMain;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.MIDDLE)
public class OnePlusWorkAroundHooker implements KeepMembers {
static {

View File

@ -4,7 +4,10 @@ import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.impl.StartBootstrapServices;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class StartBootstrapServicesHooker11 implements KeepMembers {
public static String className = "com.android.server.SystemServer";
public static String methodName = "startBootstrapServices";

View File

@ -6,7 +6,10 @@ import com.elderdrivers.riru.common.KeepMembers;
import com.elderdrivers.riru.edxp._hooker.impl.SystemMain;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class SystemMainHooker implements KeepMembers {
public static String className = "android.app.ActivityThread";

View File

@ -1,10 +1,8 @@
package com.elderdrivers.riru.edxp.art;
import com.elderdrivers.riru.common.KeepAll;
import com.elderdrivers.riru.edxp.core.Yahfa;
import java.lang.reflect.Member;
import java.util.function.Consumer;
import de.robv.android.xposed.PendingHooks;

View File

@ -1,7 +1,5 @@
package com.elderdrivers.riru.edxp.art;
import java.lang.reflect.Member;
public class Heap {
public static native int waitForGcToComplete(long thread);

View File

@ -160,6 +160,7 @@ public class Main implements KeepAll {
});
}
// TODO do this earlier?
private static boolean isBlackListedProcess(int uid) {
return ProcessHelper.isIsolated(uid)
|| ProcessHelper.isRELROUpdater(uid)

View File

@ -2,6 +2,9 @@ package com.elderdrivers.riru.edxp.deopt;
import java.util.HashMap;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
/**
* Providing a whitelist of methods which are the callers of the target methods we want to hook.
* Because the target methods are inlined into the callers, we deoptimize the callers to
@ -10,6 +13,7 @@ import java.util.HashMap;
* Only for methods which are included in pre-compiled framework codes.
* TODO recompile system apps and priv-apps since their original dex files are available
*/
@ApiSensitive(Level.MIDDLE)
public class InlinedMethodCallers {
public static final String KEY_BOOT_IMAGE = "boot_image";

View File

@ -1,4 +0,0 @@
package com.elderdrivers.riru.edxp.entry;
public interface Hook {
}

View File

@ -1,5 +0,0 @@
package com.elderdrivers.riru.edxp.entry;
public class HookImpl<T> implements Hook {
}

View File

@ -1,7 +1,10 @@
package com.elderdrivers.riru.edxp.framework;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.MIDDLE)
public class ProcessHelper {
static {

View File

@ -3,7 +3,10 @@ package com.elderdrivers.riru.edxp.framework;
import com.elderdrivers.riru.edxp.util.Utils;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class Zygote {
// prevent from fatal error caused by holding not whitelisted file descriptors when forking zygote

View File

@ -4,7 +4,10 @@ import android.os.StrictMode;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class SliceProviderFix {
public static final String SYSTEMUI_PACKAGE_NAME = "com.android.systemui";

View File

@ -28,6 +28,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.XposedInit;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
public abstract class BaseRouter implements Router {
@ -94,6 +96,7 @@ public abstract class BaseRouter implements Router {
}
@ApiSensitive(Level.LOW)
public void startBootstrapHook(boolean isSystem) {
Utils.logD("startBootstrapHook starts: isSystem = " + isSystem);
ClassLoader classLoader = BaseRouter.class.getClassLoader();
@ -143,6 +146,7 @@ public abstract class BaseRouter implements Router {
}
}
@ApiSensitive(Level.LOW)
public void startWorkAroundHook() {
ClassLoader classLoader = BaseRouter.class.getClassLoader();
if (useXposedApi) {

View File

@ -15,7 +15,10 @@ import dalvik.system.PathClassLoader;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class ClassLoaderUtils {
public static final String DEXPATH = "/system/framework/edxp.jar:/system/framework/eddalvikdx.jar:/system/framework/eddexmaker.jar";

View File

@ -7,9 +7,12 @@ import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
public class ClassUtils {
@ApiSensitive(Level.MIDDLE)
public static int getClassStatus(Class clazz, boolean isUnsigned) {
if (clazz == null) {
return 0;
@ -25,8 +28,9 @@ public class ClassUtils {
/**
* 5.0-8.0: kInitialized = 10 int
* 8.1: kInitialized = 11 int
* 9.0: kInitialized = 14 uint8_t
* 9.0+: kInitialized = 14 uint8_t
*/
@ApiSensitive(Level.MIDDLE)
public static boolean isInitialized(Class clazz) {
if (Build.VERSION.SDK_INT >= 28) {
return getClassStatus(clazz, true) == 14;

View File

@ -8,10 +8,13 @@ import java.lang.reflect.Field;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexClassLoader;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
/**
* For 6.0 only.
*/
@ApiSensitive(Level.LOW)
@TargetApi(Build.VERSION_CODES.M)
public class DexUtils {

View File

@ -8,6 +8,10 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public class ProcessUtils {
// Copied from UserHandle, indicates range of uids allocated for a user.

View File

@ -21,6 +21,10 @@ import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
public final class Unsafe {
private static final String TAG = "Unsafe";

View File

@ -5,6 +5,8 @@ import android.util.Log;
import com.elderdrivers.riru.edxp.common.BuildConfig;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
public class Utils {
@ -45,6 +47,7 @@ public class Utils {
Log.e(LOG_TAG, msg, throwable);
}
@ApiSensitive(Level.LOW)
public static String getSysProp(String key) {
try {
Class sysProps = XposedHelpers.findClassIfExists("android.os.SystemProperties", null);

View File

@ -60,6 +60,7 @@ namespace art {
return instance_;
}
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
HOOK_FUNC(Constructor, "_ZN3art11ClassLinkerC2EPNS_11InternTableE",
"_ZN3art11ClassLinkerC2EPNS_11InternTableEb"); // 10.0

View File

@ -37,6 +37,7 @@ namespace art {
return instance_;
}
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
HOOK_FUNC(PreZygoteFork, "_ZN3art2gc4Heap13PreZygoteForkEv");
RETRIEVE_FUNC_SYMBOL(WaitForGcToComplete,

View File

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

View File

@ -20,6 +20,7 @@ namespace art {
public:
JNIEnvExt(void *thiz) : HookedObject(thiz) {}
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(NewLocalRef, "_ZN3art9JNIEnvExt11NewLocalRefEPNS_6mirror6ObjectE");
RETRIEVE_FUNC_SYMBOL(DeleteLocalRef, "_ZN3art9JNIEnvExt14DeleteLocalRefEP8_jobject");

View File

@ -46,6 +46,7 @@ namespace art {
public:
Class(void *thiz) : HookedObject(thiz) {}
// @ApiSensitive(Level.MIDDLE)
static void Setup(void *handle, HookFunType hook_func) {
RETRIEVE_FUNC_SYMBOL(GetDescriptor, "_ZN3art6mirror5Class13GetDescriptorEPNSt3__112"
"basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE");

View File

@ -11,6 +11,7 @@ namespace art {
return;
}
// @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();

View File

@ -36,6 +36,7 @@ namespace art {
return instance_;
}
// @ApiSensitive(Level.LOW)
static void Setup(void *handle, HookFunType hook_func) {
HOOK_FUNC(Init, "_ZN3art7Runtime4InitEONS_18RuntimeArgumentMapE");
RETRIEVE_FUNC_SYMBOL(DeoptimizeBootImage,

View File

@ -3,6 +3,7 @@
#include <cstdint>
// @ApiSensitive(Level.MIDDLE)
namespace android {
typedef int32_t status_t;

View File

@ -40,7 +40,8 @@ static const char *kPathPrefixWhitelist[] = {
static const char *kFdPath = "/proc/self/fd";
// todo stay up to date
// TODO stay up-to-date
// @ApiSensitive(Level.MIDDLE)
// Keeps track of all relevant information (flags, offset etc.) of an
// open zygote file descriptor.
class FileDescriptorInfo {

View File

@ -4,6 +4,7 @@
#include <android-base/strings.h>
#include "base/object.h"
// NOT USED
namespace android {
// Static whitelist of open paths that the zygote is allowed to keep open.

View File

@ -105,6 +105,7 @@ namespace edxp {
}
}
// TODO ignore unrelated processes
bool ConfigManager::IsAppNeedHook(const std::string &app_data_dir) {
// zygote always starts with `uid == 0` and then fork into different user.
// so we have to check if we are the correct user or not.

View File

@ -11,6 +11,7 @@ namespace edxp {
return XposedBridge_initXResourcesNative(env, clazz);
}
// @ApiSensitive(Level.MIDDLE)
static jboolean ResourcesHook_removeFinalFlagNative(JNI_START, jclass target_class) {
if (target_class) {
jclass class_clazz = JNI_FindClass(env, "java/lang/Class");

View File

@ -23,6 +23,7 @@
namespace edxp {
// TODO exclude unrelated processes
EXPORT void onModuleLoaded() {
LOG(INFO) << "onModuleLoaded: welcome to EdXposed!";
InstallInlineHooks();

View File

@ -80,7 +80,9 @@ namespace edxp {
InstallFwkHooks(fwk_handle.Get());
}
// @ApiSensitive(Level.MIDDLE)
bool InstallLinkerHooks(const char *linker_path) {
// TODO flags
void *handle = dlopen(kLibSandHookNativePath.c_str(), RTLD_NOW);
if (!handle) {

View File

@ -15,6 +15,7 @@
#include "resource_hook.h"
#include "dl_util.h"
// @ApiSensitive(Level.HIGH)
namespace edxp {
static constexpr const char *kXResourcesClassName = "android/content/res/XResources";

View File

@ -20,6 +20,7 @@
namespace edxp {
// @ApiSensitive(Level.HIGH)
static constexpr const char *kPropKeyCompilerFilter = "dalvik.vm.dex2oat-filter";
static constexpr const char *kPropKeyCompilerFlags = "dalvik.vm.dex2oat-flags";
static constexpr const char *kPropKeyUseJitProfiles = "dalvik.vm.usejitprofiles";

View File

@ -27,7 +27,6 @@ android {
dependencies {
compileOnly files("${hiddenApiStubJarFilePath}")
implementation project(':edxp-common')
implementation project(':xposed-bridge')
implementation 'com.swift.sandhook:hooklib:4.2.1'
compileOnly project(':dexmaker')
}

View File

@ -15,7 +15,10 @@ import com.swift.sandhook.annotation.ThisObject;
import java.lang.reflect.Method;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
@HookClass(ActivityThread.class)
public class HandleBindAppHooker implements KeepMembers {

View File

@ -17,7 +17,10 @@ import com.swift.sandhook.annotation.ThisObject;
import java.lang.reflect.Method;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
@HookClass(LoadedApk.class)
public class LoadedApkConstructorHooker implements KeepMembers {
public static String className = "android.app.LoadedApk";

View File

@ -13,7 +13,11 @@ import java.lang.reflect.Method;
import dalvik.system.BaseDexClassLoader;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
// TODO check HOS / OOS ver.11 when available
@ApiSensitive(Level.MIDDLE)
@HookClass(BaseDexClassLoader.class)
public class OnePlusWorkAroundHooker implements KeepMembers {

View File

@ -13,7 +13,10 @@ import com.swift.sandhook.annotation.ThisObject;
import java.lang.reflect.Method;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
@HookReflectClass("com.android.server.SystemServer")
public class StartBootstrapServicesHooker11 implements KeepMembers {
public static String className = "com.android.server.SystemServer";

View File

@ -12,8 +12,11 @@ import com.swift.sandhook.annotation.HookMethodBackup;
import java.lang.reflect.Method;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
@ApiSensitive(Level.LOW)
// system_server initialization
// ed: only support sdk >= 21 for now
@HookClass(ActivityThread.class)

View File

@ -27,7 +27,6 @@ android {
dependencies {
compileOnly files("${hiddenApiStubJarFilePath}")
implementation project(':edxp-common')
implementation project(':xposed-bridge')
compileOnly project(':dexmaker')
}

View File

@ -27,7 +27,6 @@ android {
dependencies {
compileOnly files("${hiddenApiStubJarFilePath}")
implementation project(':edxp-common')
implementation project(':xposed-bridge')
compileOnly project(':dexmaker')
}

View File

@ -21,6 +21,8 @@ import java.util.Set;
import dalvik.system.InMemoryDexClassLoader;
import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
import de.robv.android.xposed.callbacks.XC_InitZygote;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@ -92,6 +94,7 @@ public final class XposedBridge {
public static volatile ClassLoader dummyClassLoader = null;
@ApiSensitive(Level.MIDDLE)
public static void initXResources() {
if (dummyClassLoader != null) {
return;

View File

@ -34,6 +34,8 @@ import java.util.zip.ZipFile;
import dalvik.system.DexFile;
import dalvik.system.PathClassLoader;
import de.robv.android.xposed.annotation.ApiSensitive;
import de.robv.android.xposed.annotation.Level;
import de.robv.android.xposed.callbacks.XC_InitPackageResources;
import de.robv.android.xposed.callbacks.XC_InitZygote;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
@ -91,6 +93,7 @@ public final class XposedInit {
hookResources();
}
@ApiSensitive(Level.MIDDLE)
private static void hookResources() throws Throwable {
if (!EdXpConfigGlobal.getConfig().isResourcesHookEnabled() || disableResources) {
return;
@ -265,6 +268,7 @@ public final class XposedInit {
XResources.init(latestResKey);
}
@ApiSensitive(Level.MIDDLE)
private static XResources cloneToXResources(XC_MethodHook.MethodHookParam param, String resDir) {
Object result = param.getResult();
if (result == null || result instanceof XResources ||

View File

@ -0,0 +1,17 @@
package de.robv.android.xposed.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Annotation that indicates a element is sensitive to Android API level.
* <p>
* Annotated elements' compatibility should be checked when adapting to new Android versions.
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
public @interface ApiSensitive {
Level value() default Level.HIGH;
}

View File

@ -0,0 +1,9 @@
package de.robv.android.xposed.annotation;
public enum Level {
LOW, MIDDLE, HIGH;
private Level() {
}
}