2626
2727import org .lsposed .hiddenapibypass .library .BuildConfig ;
2828
29+ import java .io .File ;
2930import java .lang .invoke .MethodHandle ;
3031import java .lang .invoke .MethodHandles ;
3132import java .lang .reflect .Constructor ;
4142import java .util .Set ;
4243import java .util .stream .Collectors ;
4344
45+ import dalvik .system .PathClassLoader ;
4446import dalvik .system .VMRuntime ;
4547import sun .misc .Unsafe ;
4648
49+ class ChildFirstClassLoader extends PathClassLoader {
50+ public ChildFirstClassLoader (String dexPath , ClassLoader parent ) {
51+ super (dexPath , parent );
52+ }
53+
54+ @ Override
55+ public Class <?> loadClass (String name ) throws ClassNotFoundException {
56+ if ("java.lang.Object" .equals (name )) {
57+ return Object .class ;
58+ }
59+ return findClass (name );
60+ }
61+ }
62+
4763@ RequiresApi (Build .VERSION_CODES .P )
4864public final class HiddenApiBypass {
4965 private static final String TAG = "HiddenApiBypass" ;
@@ -65,12 +81,21 @@ public final class HiddenApiBypass {
6581 //noinspection JavaReflectionMemberAccess DiscouragedPrivateApi
6682 unsafe = (Unsafe ) Unsafe .class .getDeclaredMethod ("getUnsafe" ).invoke (null );
6783 assert unsafe != null ;
68- methodOffset = unsafe .objectFieldOffset (Helper .Executable .class .getDeclaredField ("artMethod" ));
69- classOffset = unsafe .objectFieldOffset (Helper .Executable .class .getDeclaredField ("declaringClass" ));
70- artOffset = unsafe .objectFieldOffset (Helper .MethodHandle .class .getDeclaredField ("artFieldOrMethod" ));
71- methodsOffset = unsafe .objectFieldOffset (Helper .Class .class .getDeclaredField ("methods" ));
72- iFieldOffset = unsafe .objectFieldOffset (Helper .Class .class .getDeclaredField ("iFields" ));
73- sFieldOffset = unsafe .objectFieldOffset (Helper .Class .class .getDeclaredField ("sFields" ));
84+ ClassLoader bootClassloader = null ;
85+ try {
86+ if (new File ("/apex/com.android.art/javalib/core-oj.jar" ).exists ()) {
87+ bootClassloader = new ChildFirstClassLoader ("/apex/com.android.art/javalib/core-oj.jar" , null );
88+ } else if (new File ("/apex/com.android.runtime/javalib/core-oj.jar" ).exists ()) {
89+ bootClassloader = new ChildFirstClassLoader ("/apex/com.android.runtime/javalib/core-oj.jar" , null );
90+ }
91+ } catch (Throwable ignored ) {
92+ }
93+ methodOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (Executable .class .getName ()) : Helper .Executable .class ).getDeclaredField ("artMethod" ));
94+ classOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (Executable .class .getName ()) : Helper .Executable .class ).getDeclaredField ("declaringClass" ));
95+ artOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (MethodHandle .class .getName ()) : Helper .MethodHandle .class ).getDeclaredField ("artFieldOrMethod" ));
96+ methodsOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (Class .class .getName ()) : Helper .Class .class ).getDeclaredField ("methods" ));
97+ iFieldOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (Class .class .getName ()) : Helper .Class .class ).getDeclaredField ("iFields" ));
98+ sFieldOffset = unsafe .objectFieldOffset ((bootClassloader != null ? bootClassloader .loadClass (Class .class .getName ()) : Helper .Class .class ).getDeclaredField ("sFields" ));
7499 Method mA = Helper .NeverCall .class .getDeclaredMethod ("a" );
75100 Method mB = Helper .NeverCall .class .getDeclaredMethod ("b" );
76101 mA .setAccessible (true );
@@ -233,7 +258,7 @@ public static List<Executable> getDeclaredMethods(@NonNull Class<?> clazz) {
233258 * @param parameterTypes argument types of the expected method with name {@code methodName}
234259 * @return the found method
235260 * @throws NoSuchMethodException when no method matches the given parameters
236- * @see Class#getDeclaredMethod(String, Class[])
261+ * @see Class#getDeclaredMethod(String, Class[])
237262 */
238263 @ NonNull
239264 public static Method getDeclaredMethod (@ NonNull Class <?> clazz , @ NonNull String methodName , @ NonNull Class <?>... parameterTypes ) throws NoSuchMethodException {
0 commit comments