I'm writing an application that must not run on rooted devices. I want to store some secure data and which is possible only on non-rooted devices as nobody can access files in /data/data/package-name.
Does anyone know:
1) Is it possible to prevent the installation of an application on rooted devices? I read something about the "copy-protection mechanis开发者_Python百科m" of Android Market. This feature seems to be outdated and replaced by the licensing feature. However, licensing is only possible for paid application and mine is free...
2) Is it possible to check programmatically whether a device is rooted or not? If it would be possible to do so I could simply stop the application if the device is rooted.
Any help regarding this topic is appreciated!
Execute
Runtime.getRuntime().exec("su");
and check the result code.
In other words, if you can exec su
, then you have root access. it doesn't matter if the user allows or denies it, you have your answer.
I think your approach is a bit flawed. First of all, the user can first install your application and data, then "root" the device (even if rooting wipes the data, one can make the backup first). Next, the general rule is that whatever is in user's hands is not yours anymore. The hacker will find a way to get to your data sooner or later.
If you care about secure data, don't put it to device. As Android is net-centric device (yes, I know, that's subjective, but it was initially developed and positioned as such), accessing the data online is not uncommon.
What I would say is to run su
and then check the output. If the user allows your app to have root, then use root to uninstall your own application (one way might be to place a script into init.d
and then force a reboot).
If the user DOES NOT allow your app to run as root, then:
- They DENIED your app permissions.
- They are not rooted.
Now, denying permissions (and rooted) means that they have some sort of SUPERUSER management app, and that's where this next part comes in.
I would then proceed to use PackageManager
to retrieve a list of all packages and then check them against the handful SuperUser management apps available, namely the ones by Koush, ChainsDD, and Chainfire
The relevant package names are:
com.noshufou.android.su
eu.chainfire.supersu
com.koushikdutta.superuser
Use those methods which will help you check for 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");
}
Now try to check whether the device is rooted.
if (isRooted() == true){
//Do something to prevent run this app on the device
}
else{
//Do nothing and run app normally
}
For example you can force stop the app if the device is rooted
If you are trying to protect data for the user, it's their business to worry about other apps. If you are trying to protect data from the user, what business do you have putting it on their device?
To answer your question, they are in control of the machine so expect them to be able to trap any call to an API checking 'Is this rooted?' and lie to you. Instead, encrypt the data on the client with a key known to the client, but make it non-obvious where and how you are doing it. Generally make things annoying for whoever is looking.
Enjoy the ensuing game of whack-a-mole. Every time someone cracks into it, you'll make a better fix, they'll make a better crack, and all along the way you will be raising the barrier for cracking it.
Don't fight against freedom - why should you turn away customers with free devices anyway? - instead, if you want a particular outcome, make it so Bother To Get Data > Value Of Getting Data. Then it won't happen. If you truly must have fool-proof security, keep the data server-side.
I believe that one of the 'drawbacks' of the traditional copy protection was that it did not allow the application to be installed on rooted devices, but it also has its own share of problems and will be deprecated soon.
As for client-side checks, you simply cannot rely on a programmatic approach to detect if you're running on a rooted device or not -- anything that is in client-side code can and will be hacked and removed. You'd be surprised at how easy it is to modify even Proguard-obfuscated code. At best, you force the hacker to spend a few hours or days to edit the code and recompile. This is security through obscurity, and not a viable protection mechanism.
1) no. how would you deny installation? why would a rooted device deny installation of something the user wants to install on the fs? being the whole point of rooting that you can make the device do basically whatever.
2) no. not for your purposes. you can check if you can gain root for your application through the usual methods. so you can make a check for a positive but you cannot prove programmatically that it is not rooted, from within your app.
also, what you are asking if you can make perfect copy protection drm system - you might also be missing the point that the user can alter your application, removing your root check. if you have a checksum/crc check of some kind, the user can fake the result of that as well.
精彩评论