Determining if an iPhone is Jail broken Programmatically - iphone

How do you determine (programmatically) if an iPhone/iPod is:
Jail broken
Running a cracked copy of your software
Pinch Media can detect if a phone is jail broken or the software running is cracked, does anyone know how they do this? Are there any libraries?

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):
Don't expect it to work forever
Don't use this information to break/hinder your app in any way (otherwise they'll have cause to hexedit it, so your app won't know it is jailbroken)
Probably wise to obfuscate this bit of the code. For example, you could put the base64 encoded reversed string in your code, and then decode it in the app by reversing the process.
Validate your validation later in your code (e.g. when I said SignerIdentity, did it actually say SignerIdentity or siNGeridentity?)
Don't tell people on a public website like stackoverflow how you do it
Keep in mind it is only a guide and is not fool-proof (nor cracker-proof!) - with great power comes great responsibility.

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.

Related

Do I have to use onPause/onStart/onDestroy

I'm developing a mobile puzzle game in Unity, when I exit my game to the home screen and return back- the game continues from the same spot and it seems to be fine (without overriding onPause/onStart), am I missing something? Do I need to store variables when exit? What do people usually save? I'm afraid to have bugs in the future.
I missing something?
Yes
Do I need to store variables when exit?
Yes
I'm afraid to have bugs in the future.
Yes, you will. You will run into lost variables issues. It is your responsibly to implement this. Just because everything looks and works fine now doesn't mean anything. The behavior is different on different platforms and devices and also depends on how many apps are already running on the background + current available ram. Usually, you use a class to store all important variables in your class then serialize and save them.
See this post that explains how to do this and provides a wrapper to easily save and load any class. You have to save your game state when Unity is about to be interrupted. These are the functions that can be used to detect this and you must know about:
OnApplicationQuit()
OnApplicationPause(bool)
OnApplicationFocus(bool)
You have to decide which ones to use to save the data. Sometimes, you must use multiple of them due to the behavior of each one in each platform. It's worth reading the Doc on each one to understand what they do on each platform.

Is the asynchronous part of Apple's new verification controller necessary?

I was looking through Apple's Verification Controller patch for In App Purchases here: https://developer.apple.com/library/ios/#releasenotes/StoreKit/IAP_ReceiptValidation/_index.html
I was planning on implementing server validation, but to not necessitate a response immediately.
Is the asynchronous part of their new code absolutely necessary. Does it offer any advantage over a naive server side validation?
If I could just use the immediate parsing and checking and gain a benefit, that would be great.
Thanks!
EDIT: This question feels a little empty without some code:
I'm talking specifically about changing the main verifyPurchase function to contain only:
- (BOOL)verifyPurchase:(SKPaymentTransaction *)transaction;
{
return [self isTransactionAndItsReceiptValid:transaction];
}
...and get rid of the client -> server post. Will I still be vulnerable to the recent hacks?
Your question makes much more sense after looking at the code.
The attack in question is that someone presents someone else's otherwise-valid receipt. There does not appear to be anything in the receipt data that ties it to the device/purchaser. You can mitigate this to some extent by checking the purchase dates (but only if the device has accurate time, which is under the user's control).
(This attack would not work if the client generated a 256-bit random nonce which had to match the receipt. An attacker can obviously hack the binary/PRNG, but in either case you've already lost.)
Incidentally, the code has a bunch of problems:
The only check of the server cert is that it's an EV cert. This should be easy to forge, since the attacker has complete control of the CA.
A transaction ID is permanently added to the list of "already seen" transactions in -isTransactionAndItsReceiptValid: before the network check finishes, but the content is only unlocked after the network returns. The receipt can never be re-verified if the connection fails, so the user's money will have effectively gone into a black hole.
It expects the transaction to have occurred on the same device that is verifying it.
It expects ITC_CONTENT_PROVIDER_SHARED_SECRET to be embedded in the executable (trivial to decrypt with a jailbroken device).
It assumes that -connection:didReceiveData: returns the complete receipt data (this might not be the case due to fragmentation, but it can probably be guaranteed since Apple controls the server implementation).

Is dynamic code insertion possible in iphone?

Each time i make small changes, i need to submit the app for approval and need to wait to review process to complete, so till what extent i can exploit dynamic code insertion or at least can i change the view of a view controller using the nib file which i will be downloading to document directory dynamically?
For the most part, the answer is no, and intentionally so. In particular, you cannot run executable code that you download. If you figured out a workaround to allow it technically (and I have at least one or two thoughts in mind on how I'd attack it), it would definitely run counter to Apple's approval process.
On the other hand, a nib file is data, not code. That you can definitely read from disk and instantiate using [UINib nibWithData:bundle:]. This is a pretty big hassle, though, and I don't particularly recommend it. But it's relatively straightforward (unless you want to correctly handle low memory situations, in which case it's a bit more of a hassle).
Of course you can always have dynamic code by putting it in a webview and writing it in JavaScript.
In the end, though, the review process is the way it is on purpose, and I recommend developers adapt their development cycle to include it. That generally means having fewer releases with heavier testing because "one quick fix" is expensive.

Best way to save values to disk and prevent tampering? (Without over-the-top encryption)

I am programming a game, and I want highscores to be able to be saved locally, but I dont want the user to be able to go into a plist file and change the values. What is the best way to make it difficult for users to edit the highscores easily. Would making the value an NSNumber that I then write as NSData be sufficient?
AES is probably more trouble than it's worth here. Much as I respect Jeff LaMarche, this implementation is not good. It's adequate for this purpose, but it's not something to copy around in my opinion unless you understand what's right and what's wrong with it. I talk about this at length in Properly encrypting with AES with CommonCrypto and include how to do AES correctly; but you probably don't want the hassle of doing AES correctly here, and it wouldn't buy you much if you did.
My recommendation is a simple checksum hash:
- (NSUInteger)checksumForScore:(NSUInteger)score player:(GKPlayer *)player {
NSString *string = [NSString stringWithFormat:#"%d%#%#", score, [player playerID], kLongRandomPassword];
return [string hash];
}
You then store the checksum along with the score. You validate it like:
- (BOOL)isValidChecksum:(NSUInteger)checksum forScore:(NSUInteger)score player:(GKPlayer *)player {
return (checksum == [checksumForScore:score player:player]);
}
I've used GKPlayer playerID here to pick something that's easy for you to use, but not trivial for the device owner to change while playing. Doing it this way makes replay attack hard. I can't just copy my friend's plist entry with it's super-highscore to my plist. It's also nicely persistent when the user changes devices or restores this device. If you're not using GameKit, first, you probably should :D and second, you'll have to figure out if there's some other key you want to use. A "user handle" would be fine too if you have the user enter that at some point. Anything that's unique-enough to the user that he wouldn't just copy his friend's.
Keychain is interesting as an obfuscation technique. It's a royal pain to read even legitimately, so the official SDK provides its own obfuscation :D I doubt it's worth the trouble, but it is a decent place to "hide" small amounts of data.
NSCoding isn't even obfuscation. Anyone who's going to bother to open up the plist can read and write NSCoding in less than a minute. Same for turning this into an NSData. Same for storing it in SQLite or Core Data.
#CocoaFu's suggestion of NSDataWritingFileProtectionComplete is clever, but I doubt it will have any real impact on a jailbroken device. Once the device is unlocked, the OS will will decrypt any file for you, so it's no barrier at all to someone who knows the device's PIN.
Save the data with NSData built-in encryption:
- (BOOL)writeToFile:(NSString *)path options:(NSDataWritingOptions)mask error:(NSError **)errorPtr
with the option:
NSDataWritingFileProtectionComplete
Available in iOS 4.0 and later.
How would a user edit a plist? They would have to jailbreak to get access to the documents folder of your app. Even if I wrote an app to try to access your plist, the sandbox prevents me unless the device is jailbroken. I wouldn't worry about this for a game score and spend my time elsewhere.
If you are really concerned, you code encrypt the data. Here is a tutorial on how to do that.
I think that NSCoding is probably the easiest bet though. It formats the save file in a non-obvious way, and you would have to know what you are doing in order to change it.
Hope that helps!
Look here too:
1) Keychain services http://developer.apple.com/library/ios/documentation/Security/Conceptual/keychainServConcepts/iPhoneTasks/iPhoneTasks.html
2) or save data in sqlite db using CoreData.

Tips for finding things in your program that are broken that you don't know about?

I was working on something for a client today when I found a way to break some functionality in our program.
(The code is really legacy code, it's been in development for about 10 years and I've only been working here for about a year.)
It didn't cause an error, or cause the program to crash, but if a user was using the program and duplicated the behavior I'm pretty sure they'd be holding up their "WTF?" flag.
In our program we have named fields (textboxes) and static text (labels) that can be linked with the textboxes. When the textbox is not filled in the label(s) that were linked to them disappear.
The functionality that I broke was, when you change the name of a textbox that already has one label or more linked to it, and save the file, without re-associating the one or more labels associated with the textbox, the formerly-associated labels appear when the textbox is blank.
Now my thinking on the matter is that a simple observer pattern could have solved this problem in the first place, but then I didn't write the code.
I was thinking that if I could dig up more situations like this with the guys in my shop, that maybe I could talk them into considering unit testing, decoupling, applying patterns where they are called for and the like.
So for this reason I was wondering if anyone had any tips for finding broken (but not error causing) functionality in any sort of app (web-based, desktop, etc...)
For an app to fail usability, it has to have a defined set of expected behaviors.
"Is this textbox SUPPOSED to do nothing when the enter key is pressed?" Maybe it is, maybe it isn't. I've seen apps where a tester/reviewer reports something that they ASSUME should work another way, when in actuality the client specifically asked that they DON'T want the form submitted on a return key press, but only a submit button click.
So basically you have to define proper behaviour before you can determine incorrect behavior.
Hire some testers.
If it has an interface, then one of my favorite unconventional test is putting 5-10 year old children in front of it. You'd be surprised what they can come up with (especially the younger ones). While this may sound like a joke, it isn't -- it really works, because children don't have the mindset of only going through "mindset" paths.
And yeah, children are the experts in "breaking things" xP.
Code inspections, i.e. reading the source code: if you had taken time to read/inspect the source code, looking for "smells" or even just looking for code whose behaviour you don't immediately understand and agree with, you might have been holding up your "WTF?" flag too.
Test, test, test.
Do unexpected things. Start doing one task and switch another to see if anything goes haywire. Use the back button when you're not supposed to. Open it in two windows. Let it time out.
Test in all browsers, especially IE.
You can find database connections/sessions aren't released by:
working out the minimum number of connections you need to do something
setting resource limits to that minimum number
ensuring one "run" of the scenario that should use exactly that number (and release it afterwards)
then run it again a few times... do you run out of connections?
I used to work in a company where programmers regularly used to forget to de-allocate db connections. The standard answer was to reduce the resource to a minimum to see if there's a leak - and to try to work out where it is by restarting the system and running different scenarios repeatedly.
The first hour of code review, with the first reviewer, will do the most to find quality problems. But here's the thing: You don't need to convince people of quality problems. You need to convince them of the value of fixing bugs, and of rewriting only when the present quality absolutely justifies it.
I've dealt with some seriously bad code in my time. But you can't just rewrite. You need a spec before you can even tell if the rewrite is an improvement.
Sometimes, you have to infer the spec from the code and then check it against some human somewhere. But by the time you've done that, you understand the code as written and are now better prepared to repair than to rewrite -- most of the time.
Repair proceeds by a process of small behavior-preserving modifications that render the spec more clear in the code. Then, when you find something that looks wrong, you don't just change it. You ask around until you find the person responsible for that decision, and you get them to show you where in the spec it says that behavior X is correct. (This conversation can take many forms.) If you're lucky, they'll tell you that behavior X is in fact incorrect, and then you've earned your pay.
assert()
Also unit testing with coverage analysis.
This is particular to the Visual Studio IDE, although it probably also applies to others:
During testing, always at some point run in the debugger with "Break when an exception is thrown" turned on.
This can often help expose exceptions which are incorrectly being silently caught and which represent bugs, but otherwise may not be evident.
Code reviews should always also include reviews of the unit test code.
The problem is that with ad-hoc testing it's impossible to know how much or how well a developer has tested their code. So, you're at the mercy of different developers definition of the word "done".
If you include reviews of the unit test code at the same time you review the production code you should have a good idea of whether the code is really complete; in that "complete" includes "tested". Not just "Hey, I'll throw it over the wall to the testers!".