如何防止 Rooted Android 手机安装我的应用程序?
Posted
技术标签:
【中文标题】如何防止 Rooted Android 手机安装我的应用程序?【英文标题】:How to prevent Rooted Android Phones from Installing my app? 【发布时间】: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:我的游戏并不总是需要互联网连接,因此当它发生在另一台服务器上时报告分数是不可行的。只有当互联网连接可用时,高分才会报告到排行榜。
【问题讨论】:
【参考方案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 services 有 Safety Net Attestation API,我们可以通过该 API 评估设备并确定它是否被植根/篡改。 想要处理root设备的朋友,请看我的回答:https://***.com/a/58304556/3908895
【讨论】:
以上是关于如何防止 Rooted Android 手机安装我的应用程序?的主要内容,如果未能解决你的问题,请参考以下文章