吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7926|回复: 22
收起左侧

[Android 原创] 使用xposed跳过oppo USB安装应用确认(需root+xposed)

  [复制链接]
LeadroyaL 发表于 2020-8-24 16:12
本帖最后由 LeadroyaL 于 2020-8-24 16:15 编辑

背景

众所周知,oppo对安卓开发者非常不友好,每次 adb install 安装APP都要登录账户输入密码,费时费力,如图所示。

昨天刚 root 了一台 reno3,在拥有 root 权限、安装好 xpsoed 后,我们就可以把这个框给干掉了。

如图所示:

Screenshot_2020-08-24-15-34-55-86.jpg

第一步,观察现象

  • AndroidStudio 安装 app,弹框输密码;
  • AndroidStudio 更新 app,可以正常更新;
  • shell 用户安装 app,弹框输密码;
  • shell 用户更新 app,可以正常更新;
  • root 用户安装 app,直接成功;
dumpsys activity top | grep ACTIVITY 
  ACTIVITY com.android.packageinstaller/.OppoPackageInstallerActivity c949e21 pid=6958

弹框的Activity 是:

com.android.packageinstaller/.OppoPackageInstallerActivity

,我们从这里追。

第二步,分析 com.android.packageinstaller

com.android.packageinstaller 拖下来,阅读manifest,发现一个和 adb 相关的receiver。

看起来这三个和我们有关

<activity android:configChanges="0x4a0" android:excludeFromRecents="true" android:name="com.android.packageinstaller.PackageInstallerActivity" android:theme="@style/Theme.PackageInstaller.Translucent">
 <intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <action android:name="android.intent.action.INSTALL_PACKAGE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:scheme="file" />
  <data android:scheme="content" />
  <data android:mimeType="application/vnd.android.package-archive" />
 </intent-filter>
 <intent-filter android:priority="1">
  <action android:name="android.intent.action.INSTALL_PACKAGE" />
  <category android:name="android.intent.category.DEFAULT" />
  <data android:scheme="file" />
  <data android:scheme="package" />
  <data android:scheme="content" />
 </intent-filter>
 <intent-filter android:priority="1">
  <action android:name="android.content.pm.action.CONFIRM_INSTALL" />
  <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>
</activity>

<activity android:configChanges="0x4a0" android:excludeFromRecents="true" android:name="com.android.packageinstaller.OppoPackageInstallerActivity" android:permission="oppo.permission.OPPO_COMPONENT_SAFE" android:screenOrientation="1" android:theme="@style/Theme.NoAnimation" />

<receiver android:name="com.android.packageinstaller.OppoPackageInstallerReceiver" android:permission="oppo.permission.OPPO_COMPONENT_SAFE">
 <intent-filter>
  <action android:name="oppo.intent.action.OPPO_INSTALL_FROM_ADB" />
 </intent-filter>

使用 frida 把日志开关打开,

Java.perform(function(){
    var cls = Java.use("com.android.packageinstaller.common.k");
    cls._a.value = true;
    cls._b.value = true;
    cls._c.value = true;
    cls._d.value = true;
});

有如下日志:

2020-08-24 13:53:41.652 28501-28501/? D/PackageInstaller.AdbInstallerReceiver: OppoPackageInstallerReceiver onReceive, action=oppo.intent.action.OPPO_INSTALL_FROM_ADB
2020-08-24 13:53:41.659 1487-14947/? I/ActivityTaskManager: START u0 {act=android.intent.action.VIEW dat=content://com.oppo.packageinstaller.fileprovider/root-dir/vmdl1662471080.tmp/base.apk typ=application/vnd.android.package-archive flg=0x10000000 cmp=com.android.packageinstaller/.PackageInstallerActivity (has extras)} from uid 10065 and from pid 28501
2020-08-24 13:53:41.675 28501-28501/? W/ActivityThread: handleWindowVisibility: no activity for token android.os.BinderProxy@e1a2e36
2020-08-24 13:53:41.693 28501-28501/? D/PackageInstaller.PackageInstaller: mOriginatingPackage: com.android.packageinstaller
2020-08-24 13:53:41.694 28501-29214/? I/PackageInstaller: read new cloud config after app updated by sau
2020-08-24 13:53:41.696 28501-28501/? D/PackageInstaller.PackageInstaller: mCallingPkgName: com.android.packageinstaller
2020-08-24 13:53:41.696 28501-28501/? D/PackageInstaller.PackageInstaller: Convert to SCHEME_FILE
2020-08-24 13:53:41.699 1487-13598/? I/ActivityTaskManager: START u0 {act=android.intent.action.VIEW dat=file:///data/app/vmdl1662471080.tmp/base.apk flg=0x12800000 cmp=com.android.packageinstaller/.OppoPackageInstallerActivity (has extras)} from uid 10065 and from pid 28501
2020-08-24 13:53:41.714 28501-29794/? D/PackageInstaller.OppoRomUpdateHelper: local rus xml is the latest version
2020-08-24 13:53:41.719 28501-29794/? D/PackageInstaller: local rus xml is the latest version
2020-08-24 13:53:41.725 28501-28501/? V/PackageInstaller.PerfServiceManager: start perfserviceinit
2020-08-24 13:53:41.726 28501-28501/? V/PackageInstaller.PerfServiceManager: mPerfServiceInited + -1
2020-08-24 13:53:41.727 28501-28501/? D/PackageInstaller: onCreate dataCollection debug info  pid 28501 uid 10065 callingPackage com.android.packageinstaller
2020-08-24 13:53:41.727 28501-28501/? D/PackageInstaller.PackageInstaller: mApkSource: 电脑端未知来源

可以得到信息:

adb install 后并没有直接开启 OppoPackageInstallerActivity,而是

  1. 先收到广播;
  2. 再启动 PackageInstallerActivity,
  3. 再启动 OppoPackageInstallerActivity。

这时候有思路,就是收到广播后别开 Activity 了,直接安装不好吗。。。考虑到两个问题,一是回调问题,我不知道这样做 adb install 是否能感知到安装完毕;二是实现问题,我懒得写代码。

观察 root 用户 pm install 的现象,发现一句日志都没有,也没有发广播,说明根本没有走到这里,这正是我需要的功能。

既然root 能做到,我们应该也可以做到,继续追吧。

第三步,分析 framework

根据目前表现来看,oppo 肯定是修改了 framework 的,所以要从 pm install 出发追代码,先把 /system/framework 都拖回来。

先找找 pm 在哪实现的,网上说它代码是在 jar 里的,

adb shell pm --help
...
  get-moduleinfo [--all | --installed] [module-name]
...

搜字符串,

➜  framework grep "get-moduleinfo" * -R
Binary file services.jar matches

找到 services.jar,阅读代码,大致如下:

  1. 解析命令
  2. runInstall 简单处理
  3. 子函数里访问远程的 IPackageManager,追不到了

代码都在 com.android.server.pm.PackageManagerShellCommand

    case 1957569947: {
            if(!cmd.equals("install")) {
            v2_1 = -1;
            break;
            }

            v2_1 = 7;
            break;
        }

        case 7: {
            return this.runInstall();
        }

  private int runInstall() throws RemoteException {
    PrintWriter pw = this.getOutPrintWriter();
    InstallParams params = this.makeInstallParams();
    String inPath = this.getNextArg();
    this.setParamsSize(params, inPath);
    int sessionId = this.doCreateSession(params.sessionParams, params.installerPackageName, params.userId);
........
    try {
      int v2_6 = this.doCommitSession(sessionId, false);
    }
    catch(Throwable v2) {
      goto label_70;
    }
........
  }
  private int doCreateSession(PackageInstaller.SessionParams arg3, String arg4, int arg5) throws RemoteException {
    int v5 = this.translateUserId(arg5, true, "runInstallCreate");
    if(v5 == -1) {
      v5 = 0;
      arg3.installFlags |= 0x40;
    }

    return this.mInterface.getPackageInstaller().createSession(arg3, arg4, v5);
  }

既然涉及到 IPackageManager,一眼没找到,懒得继续看了,搜别的吧。

我们注意到那个 adb 的广播叫 oppo.intent.action.OPPO_INSTALL_FROM_ADB,肯定很少见,搜:

➜  framework grep "oppo.intent.action.OPPO_INSTALL_FROM_ADB" * -R
Binary file coloros-services.jar matches

找到 coloros-services.jar 阅读代码,com.android.server.pm.ColorPackageInstallInterceptManager

  private boolean allowSendBroadcastForAdbInstall(Context arg6, String arg7, String arg8, String arg9, IPackageInstallObserver2 arg10, int arg11) {
    if(!new File(arg9).exists() && !arg9.startsWith("/storage") && !arg9.startsWith("/sdcard")) {
      return 0;
    }

    Intent intent = new Intent("oppo.intent.action.OPPO_INSTALL_FROM_ADB");
    intent.addFlags(0x1000000);
    intent.putExtra("apkPath", arg9);
    if(arg7 != null) {
      intent.putExtra("callerpkg", arg7);
    }

    intent.putExtra("installFlags", arg11);
    arg6.sendBroadcastAsUser(intent, new UserHandle(ActivityManager.getCurrentUser()));
    OppoAdbInstallerEntry oaie = OppoAdbInstallerEntry.Builder(arg9, arg10, arg8);
    ArrayList v3 = this.mOppoPackageInstallerList;
    synchronized(v3) {
      this.mOppoPackageInstallerList.add(oaie);
      return 1;
    }
  }

  public boolean handleForAdbSessionInstaller(String arg11, String arg12, IPackageInstallObserver2 arg13, int arg14) {
    if(ColorPackageInstallInterceptManager.EXP_VERSION) {

  public boolean allowInterceptAdbInstallInInstallStage(int arg7, PackageInstaller.SessionParams arg8, File arg9, String arg10, IPackageInstallObserver2 arg11) {
    if((arg8.installFlags & 0x20) != 0 && (arg7 != 0 || arg7 == 0 && !SystemProperties.getBoolean("oppo.root.silent.install", true)) && arg9 != null && arg10 != null) {
      String path = arg9.getAbsolutePath() + "/base.apk";
      Slog.d("ColorPackageInstallInterceptManager", "installStage send adb install pkg:" + arg10 + "  path: " + path + " installFlags:" + arg8.installFlags);
      ArrayMap v4 = this.mPms.mPackages;
      synchronized(v4) {
        if((arg8.installFlags & 2) != 0 && (this.mPms.mPackages.containsKey(arg10))) {
          Slog.d("ColorPackageInstallInterceptManager", "installStage send adb replace install, silent");
          return 0;
        }
      }

      if(this.handleForAdbSessionInstaller(arg10, path, arg11, arg8.installFlags)) {
        return 1;
      }
    }

    if((arg8.installFlags & 0x10000000) != 0) {
      Slog.d("ColorPackageInstallInterceptManager", "installStage from oppo adb installer, set INSTALL_FROM_ADB flag");
      arg8.installFlags |= 0x20;
      arg8.installFlags &= 0xEFFFFFFF;
    }

    return 0;
  }

注意那几句日志,Slog.d,它们是可以在 logcat 里被看到的,因此去日志看看。

shell 安装,弹框,点击取消按钮

2020-08-24 14:27:16.330 1487-1585/? D/ColorPackageInstallInterceptManager: installStage send adb install pkg:com.leadroyal.hellonative   path: /data/app/vmdl1622572147.tmp/base.apk installFlags:5242994
2020-08-24 14:27:34.488 1487-1487/? E/ColorPackageInstallInterceptManager: handForAdbSessionInstallerCancel packageName = null !

root 安装
无日志

shell 替换安装

2020-08-24 14:39:19.433 1487-1585/? D/ColorPackageInstallInterceptManager: installStage send adb install pkg:com.leadroyal.hellonative   path: /data/app/vmdl659442885.tmp/base.apk installFlags:5242994
2020-08-24 14:39:19.433 1487-1585/? D/ColorPackageInstallInterceptManager: installStage send adb replace install, silent

显然,hook 掉 allowInterceptAdbInstallInInstallStage 返回false就可以了,写个 xposed 插件,测试,收工!

第四步:编写 xposed 插件

这里主要考虑如何过滤包名,system_server的包名(可能)是 android,过滤一下就行了。

public class Entry implements IXposedHookLoadPackage {
    @Override
    public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {
        if (lpparam.packageName.equals("android")) {
            ClassLoader classLoader = lpparam.classLoader;
            XposedBridge.log("Patch oppo usb alert START");
            XposedHelpers.findAndHookMethod("com.android.server.pm.ColorPackageInstallInterceptManager", classLoader, "allowInterceptAdbInstallInInstallStage", int.class, "android.content.pm.PackageInstaller$SessionParams", "java.io.File", "java.lang.String", "android.content.pm.IPackageInstallObserver2", new XC_MethodHook() {
                @Override
                protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                    super.beforeHookedMethod(param);
                    param.setResult(false);
                }
            });
            XposedBridge.log("Patch oppo usb alert END");
        }
    }
}

舒服,再也不用看到这个傻逼的框了。

免费评分

参与人数 10威望 +1 吾爱币 +28 热心值 +10 收起 理由
FLY-one + 1 热心回复!
qtfreet00 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
dreamlivemeng + 1 + 1 用心讨论,共获提升!
穿透骨頭撫摸妳 + 1 + 1 用心讨论,共获提升!
打你个大窝瓜 + 1 + 1 满满的干货
19183311119 + 1 + 1 热心回复!
jiayang + 1 + 1 oppor17,有没有解BL锁的方法
tanghengvip + 1 + 1 ColorOS这些限制超级恶心开发者
zxc123Qwe789 + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Mr丶Yang 发表于 2020-8-26 15:35
MRTLSM 发表于 2020-8-26 14:44
哈哈哈哈哈我就是用的1+7p,这种手机就是为搞机人设计的

我前一阵子入手的小米10pro,12+256,更新的MIUI12稳定版,然后面具+edxposed一套下来,香的很,就是安卓10好像面具刷字体会卡米。。。回头我得再研究研究
MRTLSM 发表于 2020-8-26 18:47
Mr丶Yang 发表于 2020-8-26 15:35
我前一阵子入手的小米10pro,12+256,更新的MIUI12稳定版,然后面具+edxposed一套下来,香的很,就是安卓 ...

面具+edxposed基本上是搞机人标配了
HelloWorld68 发表于 2020-8-24 16:32
私心作怪 发表于 2020-8-24 17:15
等我买了oppo 一定root
蔚蓝枫叶95 发表于 2020-8-24 18:02
好巧不巧我看完你的帖子去搜oppo支持解锁bl了么正好搜到了你的博客的reno3的root步骤
china08 发表于 2020-8-24 20:22
谢谢分享,辛苦了
zxc123Qwe789 发表于 2020-8-24 22:27
OPPO是真的烦,终于能摆脱了!
滑稽pro 发表于 2020-8-25 02:13
vivo有没有思路…
QingYi. 发表于 2020-8-25 08:11
会编程是真的牛逼 我选择买小米
没想到吧 发表于 2020-8-25 09:18
我选择了华为
Like· 发表于 2020-8-25 11:44
好东西分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-16 10:34

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表