What are an iOS app's Compiled/Build Files? - ios

I am delivering an iOS app for a client and they are asking for the compiled/build files for the app and not the source code or an exported .ipa. I am wondering what compiled/build files are.
Is it just the .app that is created in /products whenever I build my app or something else that I need to do? I believe they are after these files so they can sign the app with their own production provisioning profile and to create a .ipa themselves.
What is an iOS app's compiled/build files and if it is just the .app how it differs from an exported .ipa?

Although vague, it's also possible they're looking for an Xcode Archive. This includes the compiled .app file as well as symbol information. You can build an archive to seed an application for testing or to validate and submit an application to iTunes Connect. If they want to submit or distribute the app without the source code, this is how you would do it.

"Building" is a fairly general term, and it can refer to anything that is needed to go from editable source material (source code, scripts, raw data files, etc.) to a shippable software product. Building can (and usually does) involve several steps, such as pre-processing, compiling, linking, converting data files, running automated tests, packaging, etc.
"Compiling" is more specific, and almost invariably refers to a process that takes source code as its input, and outputs something runnable, typically machine code for either a physical or virtual machine, or source code in a different language.

I bet they are wanting the .app. Unfortunately, since they are being relatively vague with their request, I think you should confirm this with them. I wouldn't feel uncomfortable asking, because their terminology is not some universally accepted way of refering to some method of building iOS applications. Or, if you can find out what they plan to do with the compiled binary, that might help understand what they need.
FYI, here's a brief description of the difference between a .app or .ipa.

Related

How to decompile iOS apps?

I want to see the code of an iOS app.
The app I downloaded is .deb.
First question: Is it possible to install .deb file on iOS or I downloaded a wrong file?
After unpacking the .deb file, I got some files, including .nib, .storyboard and some other files.
My main question is, How to decompile these .nib files?
I tried to decompile these files using NibToXibConverter, but I didn't succeed.
Answer to your first question:
I think you downloaded the wrong file. .deb files for iOS are common for jailbreak community and not for apps, I think all of the Cydia stuffs are packed into .deb's. If your app is especially made for the jailbreak scene then you may try to install it using Cydia's auto install feature on a jailbroken device.
Answer to your main question:
This is general info about decompiling and modifying iOS apps (not specific for nibs, but you may still find it useful).
iOS apps are distibuted in .ipa archives, which are ordinary zip archives. They contain, usually one executable in the form of Mach-O file, and resources like .plist, sounds, images - every resource you include in your xcode project. Decompiling the executable file is only possible on jailbroken iDevice, because it is encrypted especially for the current device and the magic key to decrypt the binary is burned inside the device CPU and as far as I know there is no software way to read that key. The encryption system here is called FairPlay.
Briefly described, one way to decrypt that binary is to have the app installed on a jailbroken device, and launch it from command line using a debugger (gdb) which you can download from Cydia. You have to set a breakpoint somewhere, and when your code execution pauses at the breakpoint, you are doing a memory dump of the device ram - and that is your decrypted bin.
So when you have the decrypted binary, you can run one tool called "class-dump", and get the information for declared classes and their methods if the app is written in Objective C. Once you know this information you can alter the implementation of given method from some class used in your app using "Cydia Subtstrate" a.k.a "Mobile Substrate". In fact that is the way all of the jailbroken iOS tweaks are made. Basically you are hooking a method call, and when that method get invoked, it uses your implementation. Furthermore your implementation can call the original implementation, and that is really useful if you want to make some small code addition.
I am not sure whether those things possible in Swift, but if you are dealing with a Hybrid app like the ones done with cordova, phonegap, etc., then you can see all of its javascript source because it is persisted as a resource inside the "ipa" file. In addition you can alter that javascript code directly if you have a jailbroken device and find where the app is installed on file system (usually /var/containers/Bundle/Application/uuid_for_your_app/). However, I think there is no way to get that patched version and redistribute it (correct me if I'm wrong).

Opening up an .ipa file - Piracy

How easy is it to open up an app submitted to Apple's store?
I'm going to submit a new app to the store soon, and want to protect the app file from being opened up to the source-code. So for instance, if I were to download my own app, how easy would it be to pull out all the .h and .m files and recreate it in Xcode?
Does Apple encrypt it somehow?
What steps can I take to mitigate the code being viewed?
EDIT: Allow me to rephrase the question a little better - can I take decompiled code and make it human-readable?
An IPA is just a zip. But you don't even need to access the IPA.
Just get iExplorer and access all available assets of your installed apps from your Mac.
The m files however build a compiled binary and can not be read (if you consider de-compiled code as not readable, as I do)
Adding on the answer, it is possible to decompile the binary, but the only thing that would be directly removable from the binary itself would be the headers (or to my knowledge of what I've seen). Then the application would be reverse engineered from there. That would probably be the only thing I'd be worried about when it comes to people stealing my code.

Check if app is ad-hoc|dev|app-store build at run time

I'd like to check this for build information in a debugging screen. Is there a way to check this at runtime?
I realize that I could set compiler flags for the builds or similar, but if there is an existing method that I could leverage I'd like to take advantage of that.
While I would agree with Abhi Beckert that runtime is the wrong time to be doing this (use preprocessor directives and build settings!), I wanted to clarify some of the details and speculations in the previous answer/comments and shine some light on things you could do. Bear with me, this is going to be a longer answer...
There are a bunch of pieces of data that could go under the generic umbrella of 'Build Information'. A non-exhaustive list of such things would include: Build Configuration, Code Signing Identity, Build Time, Build Date, Marketing Version Number, SCM Revision Number, SCM Branch Name, Provisioning Profile Team Identity, Provisioning Profile Expiration, CI Build Number...the list goes on and on.
Assuming for the moment your question was narrowly focused on gaining information as to the type of iOS certificate and Provisioning Profile used for the build, then I will have to go with a very firm 'No' as the answer to the question: Is there a way to check [build information using an existing API method] at runtime? As a brief aside: Collectively these two data points are called the "Code Signing Identity" in Xcode 4.6.x Build Settings or "CODE_SIGN_IDENTITY" for you command-line build setting enthusiasts.
As of the time this question was asked, there is no singular public iOS API that you can call to get information about the code signature type for the currently running app. The likely reasons behind this are numerous, but here are a few examples:
Developers are permitted to construct their own build schemes and build configurations. This means that we can have one scheme and one build configuration, or one scheme and dozens of build configurations, or even thousands of each. Naturally each scheme can be assigned a different build configuration, and those configurations can each be assigned a different code signing identity. As you might guess, it doesn't take much customization by a developer or team for this to quickly get chaotic.
Code signing identities only require that a non-expired Provisioning Profile issued for the current app identifier, contains a copy of the public key for the certificate used to sign the binary. For those working on a team, you might have a single Provisioning Profile containing all the certificates of the developers on the team, or you might make individual Provisioning Profiles for each developer on the team containing only their certificates. This is yet another point of variation in how developers can elect to build their app.
Developers may share a single certificate (tsk tsk) or be issued their own certificates...yep, you guessed it, even more variation.
This hypothetical one-stop API would then need to have access at runtime to all of your build configuration data, certificates, and provisioning profiles to be able to untwist the 'effective' settings applied at compile time and reduce all of that data down to a finite string...simply for a developer diagnostics view...not an impossible feat by any stretch of the imagination, but such a potentially computationally intense operation for negligible developer benefit would definitely rank low on just about anybody's priority list. It would get kicked even further down the priority list given that other options (like compile-time flags!) are more reliable, cheaper to setup, and simpler to maintain in the long run.
Now, as to the semi-lurking question of "Could I do it at runtime?" I would emphatically say 'Yes you can.'
As you know, device builds are the only kinds of builds that require code signing. Part of the process creates a file in the main bundle called 'embedded.mobileprovision'. This is a file owned by your app's sandbox and thus is something you absolutely have the ability to open programmatically:
[[NSBundle mainBundle] pathForResource:#"embedded.mobileprovision" ofType:nil]
.mobileprovision files are PCKS#7 encoded and contain both binary and text data. The info you seek is that of the text-based plist embedded within the PCKS#7 data. First, using OS X let's take a look at this text data out of one of your device builds:
Right click on your build for device .app bundle and select 'Show Package Contents'
Copy the embedded.mobileprovision file someplace easily accessible.
Open that file with your preferred text editor.
You notice right away that there's a lot of binary data but you can make out parts of the text data. Scrolling to the right, you'll see plist-styled xml, only it isn't so easy to read in this view. We can use an OS X command line tool to look at this data in a more organized manner:
Open Terminal and 'cd' to the folder containing your copy of the embedded.mobileprovision.
Run: security cms -D -i embedded.mobileprovision
This will display the plist xml to the terminal window for your perusal in a nicely tabbed format. If you repeat this process for an Ad-Hoc build, Dev build, and an App Store build you'll start to notice the keys in this text that are indicative of the respective types of builds. For builds signed with an 'iPhone Developer: ...' certificate (or 'Dev' builds as you listed in the original post), look for:
<key>get-task-allow</key>
<true/>
The 'get-task-allow' key is what is used to instruct iOS if the app will allow a debugger to attach to it. In the case of an 'iPhone Developer' signed binary this makes sense - You would typically need to be able to debug on the device when pushing code from Xcode to your device for testing purposes.
The difference between 'Ad-Hoc' and 'App Store' require some additional checks. This same 'get-task-allow' key will be set to false for both of these kinds of distributions:
<key>get-task-allow</key>
<false/>
However, 'Ad-Hoc' builds have a defined set of 'ProvisionedDevices'not present in 'App Store' builds:
<key>ProvisionedDevices</key>
<array>
<string>abcdef01234567890abcdef01234567890abacde</string>
<string>1abcdef01234567890abcdef01234567890abacd</string>
<string>2abcdef01234567890abcdef01234567890abacd</string>
</array>
So what does this mean in practical terms for the runtime checking question? Yes you can do it, by opening up the embedded.mobileprovision file out of the main bundle, and parsing data out of it to make an informed decision, but that is something you'd be entirely responsible for implementing yourself. You'll need to add logic to handle cases where that file is missing (ex. Simulator builds) and to either parse the PCKS#7 data or reliably extract the ASCII content of the file upon which your code can run a series of string searches. As is likely evident, this will require non-trivial effort for a somewhat brittle solution that can otherwise be easily accommodated by build settings and pre-processor macros at as Abhi Beckert outlined in the previous answer.
What about the risk of App Store rejection? Is this 'illegal' or 'subversive'?
Presuming that you use all public API when reading and parsing the contents of the embedded.mobileprovision file, this is perfectly allowable by the current terms of the App Store. Anything in your app's sandbox is fair game including embedded.mobileprovision if it happens to be present. I still strongly caution against going down this road, echoing Abhi Beckert's comments. It is a considerable amount of effort for less than 1% of use cases and there are far easier solutions out there! Furthermore, developer diagnostic views shouldn't be in App Store release builds, however the decision to include extraneous code is entirely in your hands.
I hope this clears up any lingering questions, but if not, please toss in a comment and we can see what we can do.
This is probably what you're looking for. Abhi has a good, thorough explanation and this gist has the actual code:
https://github.com/blindsightcorp/BSMobileProvision
Runtime is the wrong time to do this.
Your app may get rejected from the store if you try doing it. Or it might be approved, and then you do an urgent bugfix release and that one might get rejected.
As #rmaddy suggested in a comment, you should do it at compile time.
Edit your project settings to define this constant: CONFIGURATION_$(CONFIGURATION), then do this in your code:
#if defined (CONFIGURATION_Debug) || defined (CONFIGURATION_Adhoc)
NSLog( #"Warning message");
#endif
Source/more details: http://ios-dev.gravitini.com/2009/02/identifying-current-xcode-configuration.html
You can wrap a runtime function around it if you want. Perhaps:
void debugLog(NSString *str)
{
#if defined (CONFIGURATION_Debug)
NSLog(#"%#", str);
#endif
}

Information on iOS app wrapping?

There is a process called app wrapping:
IPA is disassembled (taken apart + sometimes executable part of is is really disassembled)
Some new binary code, resources, segments are added
IPA is assembled again
Quite often this process is used as compile time AOP (to add some aspect like security, audit etc to application).
Have you seen any guide + tools which are used for this?
Here is good overview on app wrapping for iOS: http://pauldotcom.com/wiki/index.php/Episode226#Library_Injection

iOS: How to modify .app file?

I've to de-compile iOS .app file and then insert my code and then re-package back to ipa file.
Can you please suggest some pointers how to do it?
You simply can't do this.
Once the app is compiled down to machine code, the best you can get from reverse engineering it is just assembly and unless you are willing to write your fix in assembly I don't see how you are going to integrate your code.
Also the code signing will be corrupted by doing this as well.
Unless you have valid provisioning set up on your machine you can't repackage the app with the original code signing.
Try to get the source or similar source to write an app with the functionality you need.
Yes you can if the device is jailbroken and the signature check is removed.
Here there is one case:
Is it possible to edit and recompile an iOS Binary?
In the reply they suggest that the modifications have been taken directly on the binary (by replacing some functions with other of the same size). However, I believe that you can do more advanced things.
You could, for instance, include the assembly of the application into your own objective-c code using XCode:
Compiling Assembly (.S) file alongside iPhone project
Or directly compile the modified assembly into the binary (mach-o) and then repackage.
How to create an iPhone mach-o file?
Maybe GNU ARM or LLVM toolchain can assit you on doing this: Compile, Assemble and Disassemble Using the LLVM Tool Chain
There are just some approaches which I'm currently investigating on. It is not straightforward, so any other know-how on the topic will be very appreciated.

Resources