views:

3609

answers:

4

What are accepted methods to reduce iPhone application piracy, which do not violate Apple's evaluation process?

If my application "phones home" to provide the unique device ID on which it runs, what other information would I need to collect (e.g., the Apple ID used to purchase the application) to create a valid registration token that authorizes use of the application? Likewise, what code would I use to access that extra data?

What seem to be the best available technical approaches to this problem, at the present time?

(Please refrain from non-programming answers about how piracy is inevitable, etc.)

+30  A: 

For now there's an easier way to detect if your iPhone application has been cracked for piracy use. This does not involve you to check the iPhone unique IDs against a list of accepted IDs.

Currently there are three things crackers do:

  1. Edit the Info.plist file
  2. Decode the Info.plist from binary to UTF-8 or ASCII
  3. Add a key-pair to Info.plist{SignerIdentity, Apple iPhone OS Application Signing}

The last one is easiest to check with this code:

NSBundle *bundle = [NSBundle mainBundle]; 
NSDictionary *info = [bundle infoDictionary]; 
if ([info objectForKey: @"SignerIdentity"] != nil) 
{ /* do something */  }

Generally we don't have SignerIdentity in any of the App Store applications we build so checking for nil then performing set instructions should make it more difficult for crackers and pirates.

I can't take credit for this so please visit How to Thwart iPhone IPA Crackers. There's loads of information there about piracy on iPhone and how to curb it.

David Wong
Thank you for answering the question that I asked.
Alex Reynolds
@David Quick question that no one may have the answer to: If this is such an easy (potentially 5 line) fix, why has it not been implemented more often? Is there a downside you are aware of? The VAST majority of the apps on the app store have been cracked, and are available for download.
mmc
It is very easy for the cracker to check for SignerIdentity literal string, or for infoDictionary selector call. You must likely want to obscure them. The “do something” part is also tricky: you cannot fail right away, as this would alarm the cracker. So you need to fail with a big delay (maybe give them a 30 day trial, and then ask to buy a legitimate copy). See, making this useful is not that simple any more.
Andrey Tarantsov
P.S. And *do* visit the link in the answer, it's awesome.
Andrey Tarantsov
Yes, this is a very simple solution for a massive problem, it does have its flaws. SignerIdentity is used to allow iTunes to install the illegitimate copy onto a jailbroken + things I'm not obliged to say iPod/iPhone. For pirates there is a way around this by replacing the info.plist file again when the application is in the device with one that doesn't have a SignerIdentity KV. If you want your checks to be more stringent you may iterate through all infoDictionary's values and check their strings. Remember, as long as people want free things, your application will always be crackable.
David Wong
I've found cracked versions of my app with the Info.plist file identical to the one I submitted to the store. This check doesn't work anymore.
Rhythmic Fistman
THIS IS WRONG! THIS IS NO LONGER NEEDED TO PIRATE AN APP! Please instead check the "Crypt ID" of the binary. That key is not needed and no longer included, and is a horrid way of checking.
chpwn
Uhh, did you check the date of when that was submitted? It worked then. No need to get your nickers in a knot. ;)
David Wong
+3  A: 

As pointed out by Andrey Tarantsov in the comments, looking for the "SignerIdentity" string in the binary (using an app like HexEdit) and replacing it is pretty easy.

You could encode that string, but then again all you have to do is change one char of it and the app is not going to look for the "SignerIdentity" key anymore but for some other key that probably doesn't exist (therefore is null). That key being null, the app thinks it isn't cracked (since SignerIdentity should be null if the app isn't cracked).

Instead, I'd rather check the size of the info.plist and compare it to a reference value. I noticed Simulator and Devices builds don't have the same info.plist file size. Same goes for Debug, Release and Distribution builds. Therefore, make sure you set the reference value using the info.plist file size for the Device Distribution Build.

How to look for the filesize at launch:

http://stackoverflow.com/questions/903157/get-filesize-of-info-plist-to-prevent-piracy

Sam V
A: 

Isn't there a way to validate the signed assembly against your code signing certificate? If you signed it with a cert, then there should be a way to verify the signature is still yours by using your public key against that signature.

Jason Short
There's no API for this yet, so you'll have to do it by hand. Amit Singh give's a some good pointers.
Rhythmic Fistman
A: 

I'm pretty new at creating iPhone apps; I just released my first game. I'm impressed because I see cracked apps released on the same day the app itself is launched, but mine hasn't been cracked yet; I wrote some anti-cracking code and maybe it worked well