Original address: http://bitcrank.com/blog/2012/02/07/how-to-stop-non-jailbroken-pirates-theory/
Please Note: The following is an approach I has put together to help other developers stop this kind of highly immoral piracy. I have no tested this myself as I am not currently maintaining any paid apps. Your results if you do a try this.
Background
This are rather long-winded, so if you ' re impatient and/or a IOS Ninja/expert, skip down to the ' Rough solution ' s Ection.
Most IOS developers know that jailbroken Iphone/ipad users can quite easily download and install cracked versions of their Apps. This egregious violation of the copyright has understandably angered devs which had poured their hearts and souls tion countless hours and Benjamins) into these apps. Through This anger, methods has been developed to detect and track these illegitimate users.
But what some developers don ' t realise are, there is another method for installing cracked apps on your iPhone without jail Breaking. It is not quite as easy as the jailbroken route, but I found a couple of programs which simplify the process. Google turned up a couple of results, Crappstore (a Xcode project), Iresign (automated tool) and IPA God. Part of the complexity lies in the fact so you need access to a IOS developer account as the method requires a valid Dev Elopment Provisioning profile. This should is a impassable barrier for the most users, but there is services selling provisioning profiles to the users which in Clude their udids.
The programs mentioned above is all based on the same method, which have been around for awhile now, and a dev on Twitter Proposed a simple question which caught my attention. at runtime, can I detect whether an app have been installed illegally using this method?
So first, the lets take a look at how this method works. It takes advantage of the fact that Apple have given developers a fair amount of leniency with regards to what code they CA n execute on their devices. The process is outlined below.
Obtain the App Store IPA or download decrypted IPA (skip to Step 3)
Decrypt using a appropriate tool usually on a jailbroken device
Re-Code sign using one of the tools mentioned above with a valid development provisioning profiles (you can obtain these fo R a fee for a few different sources)
Install Provisioning Profile and freshly codesigned IPA onto your device
Enjoy your cracked app (or more correctly, try to Enjoy your apps while the guilt eats away at your soul)
So what can we tell at runtime whether this app was legitimate or not? Well, the core of this method was resigning the decrypted app using a development provisioning profile. So, we really need to do are determine the code signing identity at runtime.
The Embedded.mobileprovision file holds information related to how the app was signed and the devices it's allowed to be Installed on. My first thought is this would is our silver bullet, but after some, I realised this is not the case.
Stack Overflow offered me this piece of information.
A provisioning profile was der-encoded "Pkcs7-signeddata", consisting of an XML blob (the data), a certificate chain (Apple Root Certificate authority→apple iphone certification authority→apple iphone OS Provisioning profile Signing), and th E signature
So this tells me that the structure of it isn ' t human readable without a ASN.1 parser, but all the pertinent information W E need should is here. Luckily, most of what we need are in the ' XML blob ' which is actually a plist. This was human readable in a text editor so I took a look around and I found these main differences between developmen T and distribution embedded.mobileprovision files.
|
Development |
Distribution |
Contains Udids |
Yes |
No |
Get-task-allow |
True |
False |
Certification Authority |
Apple Certification Authority |
Apple Worldwide Developer Relations Certification Authority |
However, it seems Apple strips the embedded.mobileprovision file out of your IPA at some point in the black box that's th E App Store submission process. Moreover, the Embedded.mobileprovison file doesn ' t even need to being bundled with the app (IPAs created by iresign didn ' t co Ntain any) as long as it exists on the device. codesign
embeds the Code signature (which refers to the appropriate provisioning profiles) into the binary, " c1/> "in Terminal). Seeing as there is no app without a binary, this seems like a decent place to check the signature.
I opened the binary of an app in a text editor and found a similar structure embedded at the end of the file as we saw in The embedded.mobileprovision files. However, Udids is isn't present in both cases and get-task-allow by itself was not enough information to be determine the LE Gitimacy of the app, so we is left with the certification authority.
Rough Solution
The solution I present here is the result of a couple of hours of digging and experimentation. I haven ' t extensively tested it with the various method I mentioned earlier and I haven ' t tested it in the wild as I don ' t Maintain any applicable paid apps. your own risk and only if you understand the underlying logic and possible implications. With + time and motivation, I ' m sure a more elegant method would be discovered, but I believe this method is robust ENO Ugh to at least with collect some data on the use of these techniques. If someone implements this, the get in contact because I ' d is happy to the help test this if you would like.
My proposed technique is brutally simple. Look for the ' Apple Worldwide Developer Relations Certification Authority ' string in the executable.
NSString *executablePath = [[NSBundle mainBundle] executablePath];NSString *executableAsString = [NSString stringWithContentsOfFile:executablePath encoding:NSISOLatin1StringEncoding error:NULL];BOOL isDevelopmentSigned = [executableAsString rangeOfString:@"Apple " @"Worldwide Developer Relations Certification Authority" options:NSCaseInsensitiveSearch].length;
This could was done much more efficiently (using Nsfilehandle), but this version was more readable and explains the Techniqu e well. If anyone is interested in seeing the extended version, I might being persuaded to does a follow-up post on that.
I would recommend you put it between some #ifdef
s and define a preprocessor macro in your distribution Build configuratio N. This would keep this snippet from interfering with your development testing. If This is means nothing, probably shouldn ' t is doing this anyway.
Discussion
There is a couple of possible pitfalls that I can think of off the top of my head.
I tested this method using a project I am working on, which compiles to a 6.3MB binary and it takes roughly 0.9s to Comple Te this check. There is, however, several simple optimisations I can think of which should speed this up and reduce the memory footprint
There is potential for various false positives here that I Haven ' t thought of
This method was vulnerable to changes in the the same as Apple signs apps
There could possibly is issues when Apple reviews the app depending on how they test it
Update: Thanks to Steve Troughton-smith for pointing out a silly mistake I made in the code snippet. By including a exact copy of the certification authority string in my Code, I was (recursively?) validating the test whic H would produce false positives in almost all cases. For the sake of simplicity and readability, I has a fixed this simply by splitting the string and concatenating it. There is definitely more elegant ways of the hiding this string, but I'll save this for a future post.
How-to-stop-non-jailbroken-pirates-theory