How do you determine (programmatically) if an iPhone/iPod is:
Pinch Media can det
To expand on yonel's and Benjie's comments above:
1) Landon Fuller's method relying on encryption check, linked above by yonel, seem to be the only one still not defeated by automated cracking tools. I would not be overly worried about Apple changing the state of the LC_ENCRYPTION_INFO header any time soon. It does seem to have some unpredictable effects on jailbroken iphones (even when the user has purchased a copy...)
At any rate, I would not take any rash action against a user based on that code...
2) To complement Benjie's comment re. obfuscation (an absolute necessity when dealing with any string values in your anti-piracy code): a similar but perhaps even easier way is to always check a salted hashed version of the value you are looking for. For example (even though that check is no longer efficient), you would check each MainBundle's key name as md5(keyName + "some secret salt") against the appropriate constant... Rather basic, but sure to defeat any attempt at locating the string.
Of course, this requires you to be able to indirectly query the value you want to compare (for example by going through an array containing it). But this is most often the case.
Here is one of the ways to detect if your app was cracked.
In short: the cracking usually requires changing the Info.plist. Since it's regular file you have access to, it's pretty easy to determine such changes.
Detecting a jailbroken phone is as easy as checking for the presence of /private/var/lib/apt/
folder. Although this doesn't detect Installer-only users, by now most have have installed Cydia, Icy or RockYourPhone (all of which use apt)
To detect pirated users, the easiest way is to check for the presence of a SignerIdentity
key in your app's Info.plist
. Since advanced crackers can easily find the standard [[[NSBundle mainBundle] infoDictionary] objectForKey: @"SignerIdentity"]
checks, it is best to obscure these calls using the Objective C runtime available via #import <objc/runtime.h>
or use alternative equivalents.
Just to expand on zakovyrya's reply, you could use the following code:
if ([[[NSBundle mainBundle] infoDictionary] objectForKey: @"SignerIdentity"] != nil) {
// Jailbroken
}
HOWEVER, the person jailbreaking your app can hexedit your program and as such, they could edit the string @"SignerIdentity" to read @"siNGeridentity" or something else which would return nil, and thus pass.
So if you use this (or any of the other suggestions from http://thwart-ipa-cracks.blogspot.com/2008/11/detection.html):