package com.lody.virtual.client.hook.patchs.am; import android.app.ActivityManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Build; import android.os.IInterface; import com.lody.virtual.client.core.VirtualCore; import com.lody.virtual.client.hook.base.Hook; import com.lody.virtual.client.hook.base.HookBinderDelegate; import com.lody.virtual.client.hook.base.HookDelegate; import com.lody.virtual.client.hook.base.Patch; import com.lody.virtual.client.hook.base.PatchDelegate; import com.lody.virtual.client.hook.base.ReplaceCallingPkgHook; import com.lody.virtual.client.hook.base.ReplaceLastUidHook; import com.lody.virtual.client.hook.base.ResultStaticHook; import com.lody.virtual.client.hook.base.StaticHook; import com.lody.virtual.client.ipc.VActivityManager; import com.lody.virtual.helper.proto.AppTaskInfo; import java.lang.reflect.Method; import java.util.List; import mirror.android.app.ActivityManagerNative; import mirror.android.app.IActivityManager; import mirror.android.content.pm.ParceledListSlice; import mirror.android.os.ServiceManager; import mirror.android.util.Singleton; /** * @author Lody * * @see IActivityManager * @see android.app.ActivityManager */ @Patch({StartActivity.class, StartActivityAsCaller.class, StartActivityAndWait.class, StartActivityWithConfig.class, StartActivityIntentSender.class, StartNextMatchingActivity.class, StartVoiceActivity.class, GetIntentSender.class, RegisterReceiver.class, GetContentProvider.class, GetContentProviderExternal.class, GetActivityClassForToken.class, GetTasks.class, GetRunningAppProcesses.class, StartService.class, StopService.class, StopServiceToken.class, BindService.class, UnbindService.class, PeekService.class, ServiceDoneExecuting.class, UnbindFinished.class, PublishService.class, HandleIncomingUser.class, SetServiceForeground.class, BroadcastIntent.class, GetCallingPackage.class, GrantUriPermissionFromOwner.class, CheckGrantUriPermission.class, GetPersistedUriPermissions.class, KillApplicationProcess.class, ForceStopPackage.class, AddPackageDependency.class, UpdateDeviceOwner.class, CrashApplication.class, GetPackageForToken.class, GetPackageForIntentSender.class, SetPackageAskScreenCompat.class, GetPackageAskScreenCompat.class, CheckPermission.class, PublishContentProviders.class, GetCurrentUser.class, UnstableProviderDied.class, GetCallingActivity.class, FinishActivity.class, GetServices.class, SetTaskDescription.class,}) public class ActivityManagerPatch extends PatchDelegate<HookDelegate<IInterface>> { public ActivityManagerPatch() { super(new HookDelegate<IInterface>(ActivityManagerNative.getDefault.call())); } @Override public void inject() throws Throwable { if (ActivityManagerNative.gDefault.type() == IActivityManager.TYPE) { ActivityManagerNative.gDefault.set(getHookDelegate().getProxyInterface()); } else if (ActivityManagerNative.gDefault.type() == Singleton.TYPE) { Object gDefault = ActivityManagerNative.gDefault.get(); Singleton.mInstance.set(gDefault, getHookDelegate().getProxyInterface()); } HookBinderDelegate hookAMBinder = new HookBinderDelegate(getHookDelegate().getBaseInterface()); hookAMBinder.copyHooks(getHookDelegate()); ServiceManager.sCache.get().put(Context.ACTIVITY_SERVICE, hookAMBinder); } @Override protected void onBindHooks() { super.onBindHooks(); if (VirtualCore.get().isVAppProcess()) { addHook(new ReplaceLastUidHook("checkPermissionWithToken")); addHook(new isUserRunning()); addHook(new ResultStaticHook("updateConfiguration", 0)); addHook(new ReplaceCallingPkgHook("setAppLockedVerifying")); addHook(new StaticHook("checkUriPermission") { @Override public Object afterCall(Object who, Method method, Object[] args, Object result) throws Throwable { return PackageManager.PERMISSION_GRANTED; } }); addHook(new StaticHook("getRecentTasks") { @Override public Object call(Object who, Method method, Object... args) throws Throwable { //noinspection unchecked Object _infos = method.invoke(who, args); List<ActivityManager.RecentTaskInfo> infos = ParceledListSlice.TYPE.isInstance(_infos) ? ParceledListSlice.getList.call(_infos) : (List)_infos; for (ActivityManager.RecentTaskInfo info : infos) { AppTaskInfo taskInfo = VActivityManager.get().getTaskInfo(info.id); if (taskInfo == null) { continue; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { info.baseActivity = taskInfo.baseActivity; info.topActivity = taskInfo.topActivity; } info.origActivity = taskInfo.baseActivity; info.baseIntent = taskInfo.baseIntent; } return _infos; } }); } } @Override public boolean isEnvBad() { return ActivityManagerNative.getDefault.call() != getHookDelegate().getProxyInterface(); } private class isUserRunning extends Hook { @Override public String getName() { return "isUserRunning"; } @Override public Object call(Object who, Method method, Object... args) { int userId = (int) args[0]; return userId == 0; } } }