Skip to content

Commit

Permalink
Supported Android S (Android 12)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlackBox committed Feb 22, 2022
1 parent e20be37 commit d5e6197
Show file tree
Hide file tree
Showing 12 changed files with 231 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,10 @@ private void installProviders(Context context, String processName, List<Provider
}
}

public Object getPackageInfo() {
return mBoundApplication.info;
}

public static Object installProvider(Object mainThread, Context context, ProviderInfo providerInfo, Object holder) throws Throwable {
return BRActivityThread.getWithException(mainThread).installProvider(context, holder, providerInfo, false, true, true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,7 @@ private int startActivityInSourceTask(Intent intent, String resolvedType,
return realStartActivityLocked(sourceRecord.processRecord.appThread, shadow, resolvedType, resultTo, resultWho, requestCode, flags, options);
}

private int realStartActivityLocked(IInterface appThread, Intent intent, String
resolvedType,
private int realStartActivityLocked(IInterface appThread, Intent intent, String resolvedType,
IBinder resultTo, String resultWho, int requestCode, int flags,
Bundle options) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

import black.android.app.BRActivity;
import black.android.app.BRActivityClient;
import black.android.app.BRActivityClientActivityClientControllerSingleton;
import black.android.app.BRActivityThread;
import top.niunaijun.blackbox.BlackBoxCore;
import top.niunaijun.blackbox.app.BActivityThread;
import top.niunaijun.blackbox.fake.hook.HookManager;
import top.niunaijun.blackbox.fake.hook.IInjectHook;
import top.niunaijun.blackbox.utils.compat.ActivityCompat;
import top.niunaijun.blackbox.utils.compat.ContextCompat;
import top.niunaijun.blackbox.fake.service.HCallbackProxy;
import top.niunaijun.blackbox.fake.service.IActivityClientProxy;
import top.niunaijun.blackbox.utils.HackAppUtils;
import top.niunaijun.blackbox.utils.compat.ActivityCompat;
import top.niunaijun.blackbox.utils.compat.BuildCompat;
import top.niunaijun.blackbox.utils.compat.ContextCompat;

public final class AppInstrumentation extends BaseInstrumentationDelegate implements IInjectHook {

Expand Down Expand Up @@ -98,25 +104,36 @@ private void checkHCallback() {
HookManager.get().checkEnv(HCallbackProxy.class);
}

@Override
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ContextCompat.fix(context);
BActivityThread.currentActivityThread().loadXposed(context);
return super.newApplication(cl, className, context);
}

@Override
public void callActivityOnCreate(Activity activity, Bundle icicle) {
private void checkActivity(Activity activity) {
Log.d(TAG, "callActivityOnCreate: " + activity.getClass().getName());
HackAppUtils.enableQQLogOutput(activity.getPackageName(), activity.getClassLoader());
checkHCallback();
Log.d(TAG, "callActivityOnCreate: " + activity.getClass().getName());
HookManager.get().checkEnv(IActivityClientProxy.class);
ActivityInfo info = BRActivity.get(activity).mActivityInfo();
ContextCompat.fix(activity);
ActivityCompat.fix(activity);
if (info.theme != 0) {
activity.setTheme(info.theme);
}
activity.setRequestedOrientation(info.screenOrientation);
}

@Override
public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
ContextCompat.fix(context);
BActivityThread.currentActivityThread().loadXposed(context);
return super.newApplication(cl, className, context);
}

@Override
public void callActivityOnCreate(Activity activity, Bundle icicle, PersistableBundle persistentState) {
checkActivity(activity);
super.callActivityOnCreate(activity, icicle, persistentState);
}

@Override
public void callActivityOnCreate(Activity activity, Bundle icicle) {
checkActivity(activity);
super.callActivityOnCreate(activity, icicle);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package top.niunaijun.blackbox.fake.hook;

import android.text.TextUtils;
import android.util.Log;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
Expand All @@ -10,7 +9,6 @@
import java.util.Map;

import top.niunaijun.blackbox.utils.MethodParameterUtils;
import top.niunaijun.blackbox.utils.Slog;

/**
* Created by Milk on 3/30/21.
Expand All @@ -26,6 +24,7 @@ public abstract class ClassInvocationStub implements InvocationHandler, IInjectH
private final Map<String, MethodHook> mMethodHookMap = new HashMap<>();
private Object mBase;
private Object mProxyInvocation;
private boolean onlyProxy;

protected abstract Object getWho();

Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -114,6 +115,9 @@ public void init() {
if (BuildCompat.isL()) {
addInjector(new IJobServiceProxy());
}
if (BuildCompat.isS()) {
addInjector(new IActivityClientProxy(null));
}
}
injectAll();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
Expand Down
31 changes: 31 additions & 0 deletions android-mirror/src/main/java/black/android/app/ActivityClient.java
Original file line number Diff line number Diff line change
@@ -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();
}
}
Loading

0 comments on commit d5e6197

Please sign in to comment.