【问题标题】:How to prevent Rooted Android Phones from Installing my app?如何防止 Rooted Android 手机安装我的应用程序?
【发布时间】:2015-02-16 21:13:07
【问题描述】:

在此上下文中的目的是防止在排行榜中报告虚假的高分(我的应用是游戏)。 Flappy Birds 发生了这种情况 - 请参阅此链接 - http://www.androidpit.com/forum/589832/flappy-bird-high-score-cheat-set-your-own-high-score

由于 root 用户可以用他的手机做任何他想做的事情,我想其他解决方法都不起作用,唯一的解决方案是阻止 root 用户安装应用程序。我对吗?有没有办法做到这一点?

PS:我的游戏并不总是需要互联网连接,因此当它发生在另一台服务器上时报告分数是不可行的。只有当互联网连接可用时,高分才会报告到排行榜。

【问题讨论】:

    标签: android mobile anti-cheat


    【解决方案1】:

    我也有类似的要求。我无法实现应用程序不应安装在有根设备上,但我使用了一种解决方法:

    • 检查您的设备是否植根于您的活动的onResume
    • 如果它已root,只需向他显示警报“此设备已root。您无法使用此应用程序。”,然后退出应用程序。

    示例:

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        if(new DeviceUtils().isDeviceRooted(getApplicationContext())){
            showAlertDialogAndExitApp("This device is rooted. You can't use this app.");
        }
    }
    
    
    public void showAlertDialogAndExitApp(String message) {
    
        AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
        alertDialog.setTitle("Alert");
        alertDialog.setMessage(message);
        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        Intent intent = new Intent(Intent.ACTION_MAIN);
                        intent.addCategory(Intent.CATEGORY_HOME);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        startActivity(intent);
                        finish();
                    }
                });
    
        alertDialog.show();
    }
    

    DeviceUtis.java 是一个实用程序类,它在设备是否被 root 时返回。

    public class DeviceUtils {
    
        public Boolean isDeviceRooted(Context context){
            boolean isRooted = isrooted1() || isrooted2();
            return isRooted;
        }
    
        private boolean isrooted1() {
    
            File file = new File("/system/app/Superuser.apk");
            if (file.exists()) {
                return true;
            }
            return false;
        }
    
        // try executing commands
        private boolean isrooted2() {
            return canExecuteCommand("/system/xbin/which su")
                    || canExecuteCommand("/system/bin/which su")
                    || canExecuteCommand("which su");
        }
    }
    

    我们使用了 5 种方法进行测试,我这里只展示了 2 种。您可以使用任何您认为不错的方法。

    希望这会有所帮助。

    P.S:我已将此调用放在所有活动的onResume 中,因为用户(有意进行黑客攻击)可以安装应用程序、导航到其他活动,然后是 root 设备。

    【讨论】:

    • 你能说,在安装应用程序之前,就像在安卓设备上安装应用程序一样,我们可以检查设备是否已root吗?
    • 但是为什么在 onResume() 中,为什么不在 onCreate() 方法中,我认为如果它在所有活动中 onCreate() 会很好。
    • 用户可以通过按返回按钮绕过警报。
    【解决方案2】:
    private static boolean canExecuteCommand(String command) {
            boolean executedSuccesfully;
            try {
                Runtime.getRuntime().exec(command);
                executedSuccesfully = true;
            } catch (Exception e) {
                executedSuccesfully = false;
            }
    
            return executedSuccesfully;
        }
    

    【讨论】:

    • 这里的命令是什么?如果你能解释它是如何工作的,那将会被应用。
    【解决方案3】:

    没有必要阻止具有根电话的用户,因为这是正常的用户行为。那么,如果您在游戏中没有在线连接以获取高分、应用内购买等,您会担心什么样的危险或损害?

    玩家想通过作弊方式到达最后一关或本地(!)排行榜的顶部?伤害在哪里?

    通过阻止您的游戏在有根设备上运行,您只会排斥应用的合法用户。

    编辑:

    使用云保存服务来保存玩家的高分。如果离线,它将被加密并存储在设备上。下次在线时,您会读取高分并将其发送到播放服务。播放服务提供了您可能还需要的反盗版功能。

    【讨论】:

    • 很抱歉让您感到困惑。我已经改写了PS。我的游戏需要互联网连接(向排行榜报告分数)但并非总是如此(因此在游戏结束时检查分数是否“有效与否”总是失败)。
    • @DroidHeaven 好吧,那我理解错了。您是否使用 Google Play 服务或推出自己的排行榜系统?
    • 我使用 Google Play 服务
    • @DroidHeaven 那就更简单了。使用云保存服务保存玩家的高分。如果离线,它将被加密并存储在设备上。下次在线时,您会读取高分并将其发送到播放服务。播放服务提供了您可能还需要的反盗版功能。
    • aah 现在我很困惑我应该接受哪个答案。你的和下面的都是有效的:)
    【解决方案4】:

    使用 Kotlin 扩展,您可以轻松检查设备是否已植根。下面是可以帮助你的代码

    DeviceUtils.kt

    object DeviceUtils {
        fun isDeviceRooted(context: Context?): Boolean {
            return isRooted1 || isRooted2
        }
    
        private val isRooted1: Boolean
            get() {
                val file = File("/system/app/Superuser.apk")
                return file.exists()
            }
    
        // try executing commands
        private val isRooted2: Boolean
            get() = (canExecuteCommand("/system/xbin/which su")
                    || canExecuteCommand("/system/bin/which su")
                    || canExecuteCommand("which su"))
    
        private fun canExecuteCommand(command: String): Boolean {
            return try {
                Runtime.getRuntime().exec(command)
                true
            } catch (e: Exception) {
                false
            }
        }
    }
    

    Extention.kt

    fun Activity.checkDeviceRoot(): Boolean {
        return if (DeviceUtils.isDeviceRooted(this)) {
            AlertDialog.Builder(this)
                    .setMessage("Your device is rooted. you can not use this app into rooted device.")
                    .setCancelable(false)
                    .setPositiveButton(R.string.alert_ok) { _, _ ->
                        exitProcess(0)
                    }.show()
            true
        } else {
            false
        }
    }
    

    如何使用这个扩展:

    class MyActivity : Activity{
        ...
        override 
        fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_splash)
    
            if(checkDeviceRoot())
                return
            ....
            ....
        }
    }
    

    希望这个答案能帮到你。

    【讨论】:

      【解决方案5】:

      我们在 Playstore 控制台中有一个 SafetyNet 排除 选项,我们可以使用它来防止应用出现在 Playstore 中以便在有根设备上下载。

      Google play servicesSafety Net Attestation API,我们可以通过该 API 评估设备并确定它是否被植根/篡改。

      想要处理root设备的朋友,请看我的回答:https://stackoverflow.com/a/58304556/3908895

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多