黑科技-通过IBinder直接与服务端通信获取应用安装列表

1 需要绕过反射限制(推荐 github FreeReflection)

2 从android.app.ApplicationPackageManager中拿mPM

3 从android.content.pm.IPackageManager$Stub$Proxy中拿mRemote

4 模拟调用transact

上代码:

    public String get_install_pkg() {
        try {
            PackageManager packageManager = getBaseContext().getPackageManager();

            // 第一步:Object Obj = getObjectField(packageManager, "mPM");
            String spackageManagerClassName = packageManager.getClass().getName();
            Log.i("testtest", "sPMClassName - " + spackageManagerClassName);
            Class<?> clsApplicationPackageManager = Class.forName(spackageManagerClassName);
            Field fieldmPM = clsApplicationPackageManager.getDeclaredField("mPM");
            fieldmPM.setAccessible(true);
            Object objmPM = fieldmPM.get(packageManager);

            // 第二部:取binder
            //IBinder mRemote = (IBinder) getObjectField(objmPM, "mRemote");
            String smPMClassName = objmPM.getClass().getName();
            Log.i("testtest", "smPMClassName - " + smPMClassName);
            Class<?> clsmPM = Class.forName(smPMClassName);
            Field fieldmRemote = clsmPM.getDeclaredField("mRemote");
            fieldmRemote.setAccessible(true);
            IBinder objmRemote = (IBinder)fieldmRemote.get(objmPM);
            Log.i("testtest", "objmRemote - " + objmRemote.toString());

            Parcel _data = Parcel.obtain();
            Parcel _reply = Parcel.obtain();

            _data.writeInterfaceToken("android.content.pm.IPackageManager");
            _data.writeLong(PackageManager.INSTALL_SCENARIO_DEFAULT); // MATCH_UNINSTALLED_PACKAGES   INSTALL_SCENARIO_DEFAULT
            _data.writeInt(android.os.Process.myUid());

            //拿调用号
            int TRANSACTION_getInstalledPackages = -1;
            try {
                Class<?> pkmIPCClazz = Class.forName("android.content.pm.IPackageManager$Stub");
                Field field = pkmIPCClazz.getDeclaredField("TRANSACTION_getInstalledPackages");
                assert field != null;
                field.setAccessible(true);
                TRANSACTION_getInstalledPackages = field.getInt(null);
            } catch (Throwable e) {
                e.printStackTrace();
                return null;
            }

            //与服务端通信
            boolean _status = objmRemote.transact(TRANSACTION_getInstalledPackages, _data, _reply, 0);
            Log.i("testtest", "_status - " + String.valueOf(_status));
            _reply.readException();


            // 第三步:ParceledListSlice<PackageInfo> parceledList = ParceledListSlice.CREATOR.createFromParcel(_reply);
            // 1 反射获取静态字段ParceledListSlice.CREATOR
            Class<?> clsParceledListSlice = Class.forName("android.content.pm.ParceledListSlice");
            Field fieldCREATOR = clsParceledListSlice.getDeclaredField("CREATOR");
            fieldCREATOR.setAccessible(true);
            Parcelable.Creator objCREATOR = (Parcelable.Creator)fieldCREATOR.get(null);
            Log.i("testtest", "objCREATOR - " + objCREATOR.toString());

            // 2 _reply.readTypedObject(ParceledListSlice.CREATOR);
            Object objParceledListSlice = _reply.readTypedObject(objCREATOR);
            Log.i("testtest", "objParceledListSlice - " + objParceledListSlice.toString());

            // 3 反射调用List<PackageInfo> listPKG = parceledList.getList()
            Method methodgetList = clsParceledListSlice.getDeclaredMethod("getList");
            methodgetList.setAccessible(true);
            List<PackageInfo> retgetList = (List)methodgetList.invoke(objParceledListSlice);
            Log.i("testtest", "retgetList - " + retgetList.size());

            StringBuffer sb = new StringBuffer();
            for (PackageInfo pk:retgetList){
                sb.append(pk.packageName);
                sb.append("\n");
                Log.i("testtest", "smPMClassName - " + pk.packageName);
            }
            _data.recycle();
            _reply.recycle();
            return sb.toString();
        } catch (Throwable e) {
            Log.i("testtest", "get_install_pkg error " + e);
        }
        return null;
    }

 效果:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值