From d5e61973e1964a878e32ee73a269bc544f066a7d Mon Sep 17 00:00:00 2001 From: BlackBox <> Date: Tue, 22 Feb 2022 23:21:48 +0800 Subject: [PATCH] Supported Android S (Android 12) --- .../blackbox/app/BActivityThread.java | 4 + .../core/system/am/ActivityStack.java | 3 +- .../fake/delegate/AppInstrumentation.java | 41 ++++++--- .../fake/hook/ClassInvocationStub.java | 11 ++- .../blackbox/fake/hook/HookManager.java | 4 + .../blackbox/fake/service/HCallbackProxy.java | 33 ++++++- .../fake/service/IActivityClientProxy.java | 89 +++++++++++++++++++ .../providers/SettingsProviderStub.java | 13 ++- .../blackbox/utils/compat/ContextCompat.java | 3 +- .../black/android/app/ActivityClient.java | 31 +++++++ .../black/android/app/ActivityThread.java | 17 ++++ .../java/black/android/app/LoadedApk.java | 6 ++ 12 files changed, 231 insertions(+), 24 deletions(-) create mode 100644 Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityClientProxy.java create mode 100644 android-mirror/src/main/java/black/android/app/ActivityClient.java diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java index ea4d28dc..f7ac8ae9 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java @@ -365,6 +365,10 @@ private void installProviders(Context context, String processName, List mMethodHookMap = new HashMap<>(); private Object mBase; private Object mProxyInvocation; + private boolean onlyProxy; protected abstract Object getWho(); @@ -43,11 +42,17 @@ protected Object getBase() { return mBase; } + protected void onlyProxy(boolean o) { + onlyProxy = o; + } + @Override public void injectHook() { mBase = getWho(); mProxyInvocation = Proxy.newProxyInstance(mBase.getClass().getClassLoader(), MethodParameterUtils.getAllInterface(mBase.getClass()), this); - inject(mBase, mProxyInvocation); + if (!onlyProxy) { + inject(mBase, mProxyInvocation); + } onBindMethod(); Class[] declaredClasses = this.getClass().getDeclaredClasses(); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java index b8b8b6dd..763d6457 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/hook/HookManager.java @@ -7,6 +7,7 @@ import top.niunaijun.blackbox.fake.service.IAccessibilityManagerProxy; import top.niunaijun.blackbox.fake.service.IAccountManagerProxy; +import top.niunaijun.blackbox.fake.service.IActivityClientProxy; import top.niunaijun.blackbox.fake.service.IActivityManagerProxy; import top.niunaijun.blackbox.fake.service.IActivityTaskManagerProxy; import top.niunaijun.blackbox.fake.service.HCallbackProxy; @@ -114,6 +115,9 @@ public void init() { if (BuildCompat.isL()) { addInjector(new IJobServiceProxy()); } + if (BuildCompat.isS()) { + addInjector(new IActivityClientProxy(null)); + } } injectAll(); } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/HCallbackProxy.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/HCallbackProxy.java index b603da4a..a311179e 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/HCallbackProxy.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/HCallbackProxy.java @@ -4,26 +4,29 @@ import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ServiceInfo; -import android.os.Debug; import android.os.Handler; import android.os.IBinder; import android.os.Message; -import android.util.Log; import androidx.annotation.NonNull; +import java.lang.reflect.Proxy; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import black.android.app.ActivityThreadActivityClientRecordContext; +import black.android.app.BRActivityClient; +import black.android.app.BRActivityClientActivityClientControllerSingleton; import black.android.app.BRActivityManagerNative; import black.android.app.BRActivityThread; import black.android.app.BRActivityThreadActivityClientRecord; import black.android.app.BRActivityThreadCreateServiceData; import black.android.app.BRActivityThreadH; import black.android.app.BRIActivityManager; +import black.android.app.BRLoadedApk; import black.android.app.servertransaction.BRClientTransaction; import black.android.app.servertransaction.BRLaunchActivityItem; +import black.android.app.servertransaction.LaunchActivityItem; import black.android.app.servertransaction.LaunchActivityItemContext; import black.android.os.BRHandler; import top.niunaijun.blackbox.BlackBoxCore; @@ -172,7 +175,15 @@ private boolean handleLaunchActivity(Object client) { int taskId = BRIActivityManager.get(BRActivityManagerNative.get().getDefault()).getTaskForActivity(token, false); BlackBoxCore.getBActivityManager().onActivityCreated(taskId, token, stubRecord.mActivityRecord); - if (BuildCompat.isPie()) { + if (BuildCompat.isS()) { + Object record = BRActivityThread.get(BlackBoxCore.mainThread()).getLaunchingActivity(token); + ActivityThreadActivityClientRecordContext clientRecordContext = BRActivityThreadActivityClientRecord.get(record); + clientRecordContext._set_intent(stubRecord.mTarget); + clientRecordContext._set_activityInfo(activityInfo); + clientRecordContext._set_packageInfo(BActivityThread.currentActivityThread().getPackageInfo()); + + checkActivityClient(); + } else if (BuildCompat.isPie()) { LaunchActivityItemContext launchActivityItemContext = BRLaunchActivityItem.get(r); launchActivityItemContext._set_mIntent(stubRecord.mTarget); launchActivityItemContext._set_mInfo(activityInfo); @@ -202,4 +213,20 @@ private boolean handleCreateService(Object data) { } return false; } + + private void checkActivityClient() { + try { + Object activityClientController = BRActivityClient.get().getActivityClientController(); + if (!(activityClientController instanceof Proxy)) { + IActivityClientProxy iActivityClientProxy = new IActivityClientProxy(activityClientController); + iActivityClientProxy.onlyProxy(true); + iActivityClientProxy.injectHook(); + Object instance = BRActivityClient.get().getInstance(); + Object o = BRActivityClient.get(instance).INTERFACE_SINGLETON(); + BRActivityClientActivityClientControllerSingleton.get(o)._set_mKnownInstance(iActivityClientProxy.getProxyInvocation()); + } + } catch (Throwable t) { + t.printStackTrace(); + } + } } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityClientProxy.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityClientProxy.java new file mode 100644 index 00000000..f8d2bf91 --- /dev/null +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/IActivityClientProxy.java @@ -0,0 +1,89 @@ +package top.niunaijun.blackbox.fake.service; + +import android.os.IBinder; +import android.os.IInterface; +import android.util.Log; + +import java.lang.reflect.Method; + +import black.android.app.BRActivityClient; +import black.android.util.BRSingleton; +import black.android.util.SingletonContext; +import top.niunaijun.blackbox.fake.frameworks.BActivityManager; +import top.niunaijun.blackbox.fake.hook.ClassInvocationStub; +import top.niunaijun.blackbox.fake.hook.MethodHook; +import top.niunaijun.blackbox.fake.hook.ProxyMethod; + +/** + * Created by BlackBox on 2022/2/22. + */ +public class IActivityClientProxy extends ClassInvocationStub { + public static final String TAG = "IActivityClientProxy"; + private final Object who; + + public IActivityClientProxy(Object who) { + this.who = who; + } + + @Override + protected Object getWho() { + if (who != null) { + return who; + } + Object instance = BRActivityClient.get().getInstance(); + Object singleton = BRActivityClient.get(instance).INTERFACE_SINGLETON(); + return BRSingleton.get(singleton).get(); + } + + @Override + protected void inject(Object baseInvocation, Object proxyInvocation) { + Object instance = BRActivityClient.get().getInstance(); + Object singleton = BRActivityClient.get(instance).INTERFACE_SINGLETON(); + BRSingleton.get(singleton)._set_mInstance(proxyInvocation); + } + + @Override + public boolean isBadEnv() { + return false; + } + + @Override + public Object getProxyInvocation() { + return super.getProxyInvocation(); + } + + @Override + public void onlyProxy(boolean o) { + super.onlyProxy(o); + } + + @ProxyMethod(name = "finishActivity") + public static class FinishActivity extends MethodHook { + @Override + protected Object hook(Object who, Method method, Object[] args) throws Throwable { + IBinder token = (IBinder) args[0]; + BActivityManager.get().onFinishActivity(token); + return method.invoke(who, args); + } + } + + @ProxyMethod(name = "activityResumed") + public static class ActivityResumed extends MethodHook { + @Override + protected Object hook(Object who, Method method, Object[] args) throws Throwable { + IBinder token = (IBinder) args[0]; + BActivityManager.get().onActivityResumed(token); + return method.invoke(who, args); + } + } + + @ProxyMethod(name = "activityDestroyed") + public static class ActivityDestroyed extends MethodHook { + @Override + protected Object hook(Object who, Method method, Object[] args) throws Throwable { + IBinder token = (IBinder) args[0]; + BActivityManager.get().onActivityDestroyed(token); + return method.invoke(who, args); + } + } +} diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/context/providers/SettingsProviderStub.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/context/providers/SettingsProviderStub.java index 05617684..87533af3 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/context/providers/SettingsProviderStub.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/service/context/providers/SettingsProviderStub.java @@ -1,11 +1,14 @@ package top.niunaijun.blackbox.fake.service.context.providers; import android.os.IInterface; +import android.util.Log; import java.lang.reflect.Method; +import black.android.content.BRAttributionSource; import top.niunaijun.blackbox.BlackBoxCore; import top.niunaijun.blackbox.fake.hook.ClassInvocationStub; +import top.niunaijun.blackbox.utils.compat.ContextCompat; /** * Created by Milk on 4/8/21. @@ -50,9 +53,13 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl if ("asBinder".equals(method.getName())) { return method.invoke(mBase, args); } - if (args != null && args.length > 0 && args[0] instanceof String) { - String pkg = (String) args[0]; - args[0] = BlackBoxCore.getHostPkg(); + if (args != null && args.length > 0) { + Object arg = args[0]; + if (arg instanceof String) { + args[0] = BlackBoxCore.getHostPkg(); + } else if (arg.getClass().getName().equals(BRAttributionSource.getRealClass().getName())) { + ContextCompat.fixAttributionSourceState(arg); + } } return method.invoke(mBase, args); } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/ContextCompat.java b/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/ContextCompat.java index b18e543c..2ab2286a 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/ContextCompat.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/utils/compat/ContextCompat.java @@ -11,6 +11,7 @@ import black.android.content.BRAttributionSourceState; import black.android.content.BRContentResolver; import top.niunaijun.blackbox.BlackBoxCore; +import top.niunaijun.blackbox.app.BActivityThread; /** * Created by Milk on 3/31/21. @@ -21,7 +22,7 @@ * 此处无Bug */ public class ContextCompat { - public static final String TAG = "ContextFixer"; + public static final String TAG = "ContextCompat"; public static void fixAttributionSourceState(Object obj) { Object mAttributionSourceState; diff --git a/android-mirror/src/main/java/black/android/app/ActivityClient.java b/android-mirror/src/main/java/black/android/app/ActivityClient.java new file mode 100644 index 00000000..8de3b4d4 --- /dev/null +++ b/android-mirror/src/main/java/black/android/app/ActivityClient.java @@ -0,0 +1,31 @@ +package black.android.app; + +import android.os.IInterface; + +import top.niunaijun.blackreflection.annotation.BClassName; +import top.niunaijun.blackreflection.annotation.BField; +import top.niunaijun.blackreflection.annotation.BStaticMethod; + +/** + * Created by BlackBox on 2022/2/22. + */ +@BClassName("android.app.ActivityClient") +public interface ActivityClient { + @BField + Object INTERFACE_SINGLETON(); + + @BStaticMethod + Object getInstance(); + + @BStaticMethod + Object getActivityClientController(); + + @BStaticMethod + Object setActivityClientController(Object iInterface); + + @BClassName("android.app.ActivityClient$ActivityClientControllerSingleton") + interface ActivityClientControllerSingleton { + @BField + IInterface mKnownInstance(); + } +} diff --git a/android-mirror/src/main/java/black/android/app/ActivityThread.java b/android-mirror/src/main/java/black/android/app/ActivityThread.java index 4db26155..19fe9d3e 100644 --- a/android-mirror/src/main/java/black/android/app/ActivityThread.java +++ b/android-mirror/src/main/java/black/android/app/ActivityThread.java @@ -23,11 +23,15 @@ import top.niunaijun.blackreflection.annotation.BField; import top.niunaijun.blackreflection.annotation.BMethod; import top.niunaijun.blackreflection.annotation.BParamClass; +import top.niunaijun.blackreflection.annotation.BParamClassName; import top.niunaijun.blackreflection.annotation.BStaticField; import top.niunaijun.blackreflection.annotation.BStaticMethod; @BClassName("android.app.ActivityThread") public interface ActivityThread { + @BField + Object mAppThread(); + @BStaticField IInterface sPackageManager(); @@ -73,6 +77,16 @@ public interface ActivityThread { @BMethod Object getSystemContext(); + @BMethod + Object getActivityClient(IBinder token); + + @BMethod + Object getLaunchingActivity(IBinder token); + + @BMethod + Object getPackageInfo(ApplicationInfo ai, @BParamClassName("android.content.res.CompatibilityInfo") Object compatInfo, + int flags); + @BMethod Object installProvider(Context context, @BParamClass(ContentProviderHolder.class) Object holder, ProviderInfo info, @@ -187,5 +201,8 @@ interface ActivityClientRecord { @BField IBinder token(); + + @BField + Object packageInfo(); } } diff --git a/android-mirror/src/main/java/black/android/app/LoadedApk.java b/android-mirror/src/main/java/black/android/app/LoadedApk.java index aec07181..e636a9f0 100644 --- a/android-mirror/src/main/java/black/android/app/LoadedApk.java +++ b/android-mirror/src/main/java/black/android/app/LoadedApk.java @@ -44,6 +44,12 @@ public interface LoadedApk { @BField boolean mSecurityViolation(); + @BField + boolean mPackageName(); + + @BMethod + Object getResources(); + @BMethod IServiceConnection forgetServiceDispatcher(Context Context0, ServiceConnection ServiceConnection1);