【VirtualAPP 双开系列08】如何实现多开 - UID

目录:

  • 1. Android UID 介绍
  • 2. 多开基本原理
  • 3. 常用的多开方案
  • 4. VirtualAPP 如何实现多开

 

1. Android UID 介绍

Android 系统中修改了 Linux 的 UID 的含义。由于 Android 是单用户系统,不需要支持多用户登陆,因此传统的 UID 系统就失去了原来的意义。Android 的开发者巧妙地修改了 UID 的含义:每个 APP 对应一个 UID—用 UID 对应用程序进行管理。

Android 中查看 UID 的方法:

adb shell ps | grep 包名

 

2. 多开基本原理

通过在宿主容器上面新建一个进程供插件 APK 寄宿,然后通过 hook 一些系统接口欺骗应用—让虚拟化后应用以为自己是正常运行的独立 APP,欺骗系统—让系统认为此虚拟化应用是一个已正常安装在系统的应用。


UID 是一个虚拟化无法绕过的东西,不同于传统 linux 上的含义,因为 Android 是单用户系统,因此传统的 UID 失去了原来的意义,但是 Android 巧妙的修改了 UID 的含义:UID 是系统分配的一个应用的标志,每一个 APP 对应一个 UID。因为虚拟化并没有真正的安装应用,因此 UID 必定是和宿主一致的。

虚拟化将文件访问也做了虚拟化,因此虚拟化后的应用必定是有自己的 ”/data/data/pkg” 私有目录的。那么这样就有一个冲突的地方了,”/data/data” 目录下会为已安装的应用创建一个私有目录,并且只创建一个。那么如果一个 UID 下面有两个进程,进程名对应包名,而包名对应的 ”/data/data” 私有目录有两个可以访问,那是不是就和只为一个应用创建唯一一个私有目录相冲突了。 

 

 

3. 常用的多开方案

(1) 修改 APK

反编译 APK,修改 APK 包名、签名,将 APK 伪装成另外一个不同的 APK,但对于一些有加密的 APK,可能没办法实现。

产品:克隆大师

(2)  修改 Framework

对于有系统修改权限的厂商,可以修改 Framework 来实现双开的目的。本质是基于原生 Android 系统的多账户体系实现在不同的账户下登录不同的微信。

缺点在于成本较高,需要一个支持多账户的手机才可以,而国内 ROM 一般都把这个功能从表面上“阉割”了。此外,双开时还需要频繁切换系统账户,且不能同时收消息,极为不便。更加遗憾的是除分身外,基本没有其他功能。各个分身账户之间相互隔离,互不影响。

产品:小米应用分身、360奇酷手机

(3) 通过虚拟化技术实现

虚拟 Framework 层、虚拟文件系统、模拟 Android 对组件的管理、虚拟应用进程管理等一整套虚拟技术,将 APK 复制一份到虚拟空间中运行

产品:360 分身大师、LBE 空间、VirtualAPP

(4) 以插件机制运行

可以在无需安装、修改的情况下运行 APK 文件,利用反射替换,动态代理,hook 了系统的大部分与 system—server 进程通讯的函数,以此作为“欺上瞒下”的目的,欺骗系统“以为”只有一个 apk 在运行,瞒过插件让其“认为”自己已经安装。

产品:DroidPlugin、VirtualAPP

 

 

4. VirtualAPP 如何实现多开

我们先用 VirtualAPP 安装两个 58App:

然后我们可以看到 VirtualAPP 的 data 目录下:

VirtualAPP 通过 native hook 技术对文件系统也做了 hook (下章重点),  可以看到,它给两个 58App 分配了两个 user.

com.docker/virtual/data/system/users/0.xml:

<?xml version=\'1.0\' encoding=\'utf-8\' standalone=\'yes\' ?>
<user id="0" serialNumber="0" flags="19" created="0" lastLoggedIn="0">
    <name>Admin</name>
</user>

com.docker/virtual/data/system/users/1.xml:

<?xml version=\'1.0\' encoding=\'utf-8\' standalone=\'yes\' ?>
<user id="1" serialNumber="1" flags="2" created="1619678812614" lastLoggedIn="0">
    <name>Space 2</name>
</user>

com.docker/virtual/data/system/users/userlist.xml:

<?xml version=\'1.0\' encoding=\'utf-8\' standalone=\'yes\' ?>
<users nextSerialNumber="2" version="0">
    <user id="0" />
    <user id="1" />
</users>
我们通过 VirtualAPP 打开 两个 58App,查看对应的 uid:
kuangzhongwen@MacBook-Pro-5 ~ % adb shell; top

u0_a1865      6183   672 1497260 167416 0                   0 S com.wuba
u0_a1865      6183   672 1497260 167416 0                   0 S com.wuba
u0_a1865      3549   672 1501000 185600 0                   0 S com.docker
u0_a1865      3798   672 1423680 106348 0                   0 S com.docker:x

uid 是一样的,说明系统认为只打开了一个 App(VirtualAPP). VirtualApp 通过虚拟化技术和插件运行结合的方式,hook 了系统的大部分与 system—server 进程通讯的函数,以此作为“欺上瞒下”的目的,欺骗系统“以为”只有一个 apk 在运行,瞒过插件让其“认为”自己已经安装。

hook 点:

VAppManagerService#installPackage():

        PackageSetting ps;
        if (existSetting != null) {
            ps = existSetting;
        } else {
            ps = new PackageSetting();
        }
        ps.dependSystem = dependSystem;
        ps.apkPath = packageFile.getPath();
        ps.libPath = libDir.getPath();
        ps.packageName = pkg.packageName;
        ps.appId = VUserHandle.getAppId(mUidSystem.getOrCreateUid(pkg));
        if (res.isUpdate) {
            ps.lastUpdateTime = installTime;
        } else {
            ps.firstInstallTime = installTime;
            ps.lastUpdateTime = installTime;
            for (int userId : VUserManagerService.get().getUserIds()) {
                boolean installed = userId == 0;
                ps.setUserState(userId, false/*launched*/, false/*hidden*/, installed);
            }
        }
PackageParserEx#initApplicationInfoBase():
        ai.enabled = true;
        ai.nativeLibraryDir = ps.libPath;
        ai.uid = ps.appId;
        ai.name = ComponentFixer.fixComponentClassName(ps.packageName, ai.name);
        ai.publicSourceDir = ps.apkPath;
        ai.sourceDir = ps.apkPath;
VPackageManagerService#getActivityInfo():
    @Override
    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
        checkUserId(userId);
        flags = updateFlagsNought(flags);
        synchronized (mPackages) {
            VPackage p = mPackages.get(component.getPackageName());
            if (p != null) {
                PackageSetting ps = (PackageSetting) p.mExtras;
                VPackage.ActivityComponent a = mActivities.mActivities.get(component);
                if (a != null) {
                    ActivityInfo activityInfo = PackageParserEx.generateActivityInfo(a, flags, ps.readUserState(userId), userId);
                    ComponentFixer.fixComponentInfo(ps, activityInfo, userId);
                    return activityInfo;
                }
            }
        }
        return null;
    }

...

 

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
简介VirtualApp是一个App虚拟化引擎(简称VA)。VirtualApp已兼容Android 0(8.0 Preview)。VirtualApp在你的App内创建一个虚拟空间,你可以在虚拟空间内任意的安装、启动和卸载APK,这一切都与外部隔离,如同一个沙盒。运行在VA中的APK无需在外部安装,即VA支持免安装运行APK。VA目前被广泛应用于双开/多开、应用市场、模拟定位、一键改机、隐私保护、游戏修改、自动化测试、无感知热更新等技术领域,但它决不仅限于此,Android本身就是一个极其开放的平台,免安装运行APK这一Feature打开了无限可能--------这都取决于您的想象力。申明当您需要将VirtualApp用于商业用途时,请务必联系QQ:10890 购买商业授权。您如果未经授权将VirtualAppApp模块作为您自己的App用于牟利或上传软件市场,我们取证后将直接报警(侵犯著作权罪)。购买商业授权是对我们最大的支持和认可,我们将投入更多精力和时间来不断完善优化VirtualApp,作为购买商业授权的回报,您可以获得未开放的商业版本和1vs1的支持(技术、运营、预警)!同时我们也支持基于VirtualAppAPP订制开发,请联系:QQ:10890 洽谈。请注意VirtualApp代码的更新频率非常快(以小时为单位),每一次代码的更新都有可能修复重大BUG,所以请 watch 本项目,并注意随时更新代码,以免给您带来损失!已支持的加固(不断更新)360加固腾讯加固梆梆加固梆梆企业版(12306客户端 Pass)爱加密百度加固娜迦加固乐变加固网易易盾通付盾(已支持的加固均可通过VA来脱壳,本技术不公开)在VA使用Google服务VA支持运行官方的Google服务套件,同时我们也提供了对MicroG的支持。您可以通过在VA中安装MicroG来支持Google服务,这样,即使外部没有Google服务,用户也可以在VA中享受Google服务。MicroG套件可在此下载:Download MicroGMicroG的必要模块:Services CoreServices Framework ProxyStore如果您需要在VA中使用官方的Google服务套件(外部已安装的前提下),则可以通过 GmsSupport.installGms(userId) 来安装。注意,您不能同时安装MicroGms和官方的Gms。使用说明前往你的Application并添加如下代码:@Override     protected void attachBaseContext(Context base) {         super.attachBaseContext(base);         try {             VirtualCore.getCore().startup(base);         } catch (Throwable e) {             e.printStackTrace();         }     }安装App:VirtualCore.getCore().installApp({APK PATH}, flags);启动App:VirtualCore.getCore().uninstallApp({PackageName});该App的基本信息:VirtualCore.getCore().findApp({PackageName});
要同时使用vue-virtual-scroller和vue-seamless-scroll,你需要在你的Vue项目中安装和导入这两个库,并进行相应的配置。 首先,你需要在项目中安装vue-virtual-scroller和vue-seamless-scroll。你可以使用npm或yarn来安装它们。在终端中运行以下命令: ``` npm install vue-virtual-scroller vue-seamless-scroll ``` 或 ``` yarn add vue-virtual-scroller vue-seamless-scroll ``` 安装完成后,你需要在主文件(通常是main.js)中导入vue-virtual-scroller和vue-seamless-scroll的相关代码。根据引用和引用,可以看出vue-virtual-scroller的引入方式如下: ```javascript import "vue-virtual-scroller/dist/vue-virtual-scroller.css" import VueVirtualScroller from "vue-virtual-scroller" Vue.use(VueVirtualScroller) ``` 对于vue-seamless-scroll的引入,根据引用,可以找到以下引入方式: ```javascript import VueSeamlessScroll from 'vue-seamless-scroll' Vue.use(VueSeamlessScroll) ``` 一旦你在项目中导入了这两个库并进行了相应的配置,你就可以在Vue组件中使用它们了。可能需要根据库的文档进行具体的配置和使用。 希望这能帮到你!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [vue-virtual-scroller的使用,展示巨量数据,长列表优化,虚拟列表](https://blog.csdn.net/muzidigbig/article/details/132135898)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值