安卓应用程序不能在已经root的设备上运行

10

我正在编写一个应用程序,必须不能在已root的设备上运行。我希望存储一些安全数据,这只有在未root的设备上才可能,因为没有人可以访问 /data/data/package-name 中的文件。

有人知道吗:

1) 是否可能阻止在已root的设备上安装应用程序?我读到了关于Android Market的“副本保护机制”的一些内容。但是这个特性似乎已经过时,并被许可证功能取代。然而,许可证仅适用于付费应用程序,而我的应用程序是免费的...

2) 是否可能通过编程方式检查设备是否已root?如果可以这样做,我可以简单地停止应用程序,如果设备已root。

任何关于此主题的帮助都将不胜感激!


市场表示它很快会被弃用,但现在还没有,如果你没有其他解决方案,暂时可以使用它。 - Ray Britton
1
这是许多不可能的阴影。 - rook
7个回答

9

执行

Runtime.getRuntime().exec("su");

并且检查结果代码。

换句话说,如果您可以执行su,则具有root访问权限。无论用户是否允许或拒绝,您都有答案。


Runtime.exec()已经定义,我已经使用过了。请参见:http://developer.android.com/reference/java/lang/Runtime.html - Jeffrey Blattman
这可能行不通。当你请求root权限时,用户可以简单地拒绝授予你的应用程序,而你将一无所知。如果他们授予了它,并告诉你“呵呵,你不能在已经root的设备上使用我的应用程序”,他们只会说“好吧,那就不给你root权限”,而你还是一无所知。 - John
这就是为什么编写“无根设备”应用程序有点愚蠢的原因。根访问权限由用户本身控制,几乎与由服务提供商控制一样安全。安全性在于聪明地做出逻辑选择,而不在于软件或硬件。 - SineSwiper
在已经root的设备上,没有办法保护敏感数据免受其他应用程序的侵害,而且另一个应用程序轻易地就可以访问本来是私有和安全的其他应用程序的数据。换句话说,整个沙盒模型都被破坏了。有很多情况下这是不能容忍的。 - Jeffrey Blattman
@John 简单地跟进请求一个受保护的操作...比如读取一个受保护的文件,如果失败了,你就知道被拒绝了。 - Jeffrey Blattman
显示剩余4条评论

6
我认为你的方法有些缺陷。首先,用户可以先安装您的应用程序和数据,然后“root”设备(即使root会清除数据,也可以先备份)。其次,一般规则是,无论用户手中拥有什么,都不再属于你。黑客迟早会找到获取您的数据的方法。
如果您关心安全数据,请勿将其放在设备上。由于Android是面向网络的设备(是的,我知道这是主观的,但它最初是这样开发和定位的),在线访问数据并不罕见。

更不用说拥有root权限,你很可能能够绕过大多数安全措施。 - Kevin Coppock
这就是为什么我正在寻找一种方法,使应用程序无法安装在已经获取了 root 权限的设备上的原因... - Peter
@Peter:这里有一种循环论证的情况。我的意思是,你为了避免在已经root的设备上安装它而采取的任何安全措施,都可能被拥有root权限的人绕过。 - Kevin Coppock
@kcoppock:好的,现在我明白你的意思了 :-) 我认为使用runtime.exec("su")会很有帮助。每次启动应用程序时检查设备是否已经root听起来很合理。即使设备已经被root,根仍然无法更改应用程序的源代码以禁用检查...或者我漏掉了什么? - Peter
@Peter:我不是黑客,但实际上,任何可以锁定的东西都可以被解锁。我想Runtime.exec()函数可以被修改,以始终返回一个值,使您的应用程序认为设备没有被root。您在原始问题中列出的复制保护很容易通过root手机来绕过。当我将我的Droid升级到Froyo的自定义ROM时,许多我之前购买的应用程序在市场上不会显示,因为某些ID没有正确匹配。只需修改单个文件(我相信是build.prop?)即可欺骗它认为我正在运行Eclair。 - Kevin Coppock
显示剩余2条评论

4
使用那些能帮助您检查root的方法。
public static boolean findBinary(String binaryName) {
        boolean found = false;
        if (!found) {
            String[] places = { "/sbin/", "/system/bin/", "/system/xbin/",
                    "/data/local/xbin/", "/data/local/bin/",
                    "/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/" };
            for (String where : places) {
                if (new File(where + binaryName).exists()) {
                    found = true;

                    break;
                }
            }
        }
        return found;
    }

    private static boolean isRooted() {
        return findBinary("su");
    }

现在尝试检查设备是否已经取得了root权限。
if (isRooted() == true){
//Do something to prevent run this app on the device

}
else{
//Do nothing and run app normally
}

例如,如果设备已经获取了root权限,您可以强制停止应用程序。

4
我建议运行su并检查输出。如果用户允许您的应用程序获取root权限,则可以使用root卸载自己的应用程序(一种方法是将脚本放入init.d,然后强制重新启动)。
如果用户不允许您的应用程序以root身份运行,则有两种情况:
1. 他们拒绝了您的应用权限。 2. 他们没有root权限。
现在,拒绝权限(和rooted)意味着他们拥有某种SUPERUSER管理应用程序,这就是下一个步骤的关键。
我会使用PackageManager来检索所有包的列表,然后将它们与少数可用的超级用户管理应用程序进行比较,即Koush、ChainsDD和Chainfire提供的应用程序。
相关的包名称包括:
1. com.noshufou.android.su 2. eu.chainfire.supersu 3. com.koushikdutta.superuser

3
如果你试图为用户保护数据,那么其他应用程序就是他们需要关心的事情。如果你试图保护数据免受用户侵害,那么你将其放在他们的设备上有什么理由呢?
回答你的问题,他们控制着机器,所以你应该期望他们能够捕捉到任何调用API检查“这个是否已经rooted”的请求并且欺骗你。相反地,在客户端使用一个客户端已知密钥加密数据,但是要使它不明显,不让人轻易发现你正在进行加密操作。总体来说,让任何人都感到烦恼。
享受接下来的打地鼠游戏吧。每当有人破解它时,你会做出更好的修复,他们会做出更好的破解方式,一路上你会提高破解难度。
不要反对自由 - 为什么你要拒绝使用免费设备的客户呢? - 相反地,如果你想要特定的结果,那么让获取数据的麻烦程度大于获取数据的价值。这样就不会发生了。如果你确实必须要有完全安全的保障,那么请将数据保存在服务器端。

实际上,我正在设备上创建一对密钥(公钥和私钥),并希望将其存储在自己的密钥库中。访问此密钥库的密码应尽可能安全地存储,以便即使在已获取 root 权限的手机上,持有手机的任何人也无法获取私钥... - Peter
1
你把访问密钥的密码和密钥一起存储?这样非常不安全,你不觉得吗?为什么不用口令加密密钥对,只有输入正确的口令才能正确解密呢?这就是SSH和其他工具所做的。 - James
如果您正在尝试保护用户数据,那么其他应用程序的问题就是他们自己的事情。无意冒犯,这是一种天真的安全方法。按照这个逻辑,我的浏览器应该只将所有密码存储在c:/passwords.txt的明文文件中,对吗?毕竟,如果他们安装了恶意应用程序,那么这就是用户的问题。 - Jeffrey Blattman

0

我认为传统的拷贝保护机制之一的“缺点”是它不允许应用程序安装在已经root的设备上,但它也有自己的问题,并且很快就会被弃用。

至于客户端检查,你根本不能依靠编程方法来检测你是否在root设备上运行--任何客户端代码中的东西都可以被黑客攻击和删除。你会惊讶于即使是Proguard混淆过的代码也很容易被修改。最好的情况是,你迫使黑客花费几个小时或几天来编辑代码并重新编译。这是通过模糊性来实现安全性,而不是可行的保护机制。


0

1) 不行。你怎么能拒绝安装呢?为什么一个已经root的设备会拒绝用户想要在文件系统上安装的东西呢?root的整个意义就是让设备基本上可以做任何事情。

2) 不行。对于你的目的来说不行。你可以通过通常的方法检查是否可以为你的应用程序获取root权限。所以你可以进行正面检查,但你无法从你的应用程序内部以编程方式证明它没有被root化。

另外,你所问的是是否可以制作完美的副本保护DRM系统 - 你可能也忽略了一个重点,那就是用户可以更改你的应用程序,删除你的root检查。如果你有某种校验和/ CRC检查,用户也可以伪造其结果。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接