Functions of the iOS signature mechanism

After learning about encryption and decryption, digital signatures, and certificates in the previous chapter, it’s time to learn more about iOS signatures. In fact, the iOS signature mechanism is to ensure that the App installed on the user’s phone is officially approved by Apple. Except, of course, for jailbreaking devices.

In normal development, whether it is debugging the real phone or releasing the App to the App Store, we need to go through the following steps

  • First of all, on the Mac to generate CertificateSigningRequest. CertSigningRequest file
  • Cer or iOS_Distribution. cer, which is a development certificate and a distribution certificate, can be obtained from Apple developer website
  • Register the device on the Apple Developer website and add the App ID.
  • Select device, App ID, and development certificate or production certificate to generate the Mobileprovision file

Cer or iOS_Distribution. cer certificate files and mobileprovision description files are available. By installing these files on the Mac, you can perform real machine debugging. Of course, if you have selected Automatically manage Signing in Xcode, then Xcode will Automatically do all of the above for us.

So, what is the function of each of these steps? What are the iOS_development. cer or iOS_Distribution. cer certificate files and mobileprovision description files obtained? What’s in those files?

IOS Signature Process

To understand exactly what all of the above files do, you need to understand the full iOS signing process. After compiling and running the project with Xcode, Xcode actually does the signing for us.

It’s just signing the.app file using the codeSign directive.

To prepare

To perform the iOS signature process, you need the following public and private key information

  • Mac device public key and private key, generally generated by the Mac device
  • Apple official private key, stored in the Apple background
  • Apple’s official public key. Apple’s official public key information is stored on every iPhone after delivery

Signature Process Analysis

IOS projects will generate.app files after compilation, and the app signature operation starts from getting the.app file

  • . The first step is to get the app files, use Mac. Private key signature app files for operation, to generate the signature file stored in. The app _CodeSignature/CodeResources in the directory

  • Step 2 use the Apple private key to sign the Mac public key and generate a certificate file

  • Step 3 Use the Apple private key to sign the certificate file obtained in Step 2, devices, APP ID, and entitlement to generate the Mobileprovision file, that is, the description file.

  • Step 4 Compress the signed. App file and the mobileprovision file generated in Step 3 to generate the IPA installation package.

  • Finally, the complete signature packaging process is as follows

Validation process

The. App installation package is signed, the IPA installation package is compressed, and the ipA installation package is installed on the iPhone. The signature verification operation is performed.

  • First, verify the signature in the Mobileprovision file using the Apple public key stored on the iPhone.
  • Second, after the signature verification succeeds, the device, APP ID, and entitlement information stored in Mobileprovision is obtained. Get the certificate file at the same time. The Apple public key is then used to validate the signature in the certificate. Obtain the Mac public key after successful authentication.
  • The third step, after getting the Mac public key, use the Mac public key to verify the signature file of App. If the verification is successful, it indicates that the source code of the current App has not been tampered. The App can then be installed on an iPhone
  • Finally, the complete signature and verification process is obtained as follows

In the Mobileprovision file, there are devices, APP ID, and entitlement information, which are used as follows:

  • Devices identify which devices can install the App. If the device is not in the device, the installation will fail.
  • App ID. Only the app specified with this id can be installed. If the unique IDENTIFIER of the APP does not correspond to the APP ID, the installation fails.
  • The entitlement of the App is stored in the entitlement of the App. If the entitlement of the App is inconsistent with that of the entitlement of the App, problems may occur.

Actual signing process

We have learned the specific process of iOS signature above. Now, we will perform the actual operation step by step to verify the signature process we have learned. Cer or iOS_Distribution. cer certificate, and mobileprovision.

  • First step, the generated on the Mac CertificateSigningRequest. CertSigningRequest file, the file is actually a Mac equipment’s public key.

  • Step 2: Go to the Apple developer website, get a certificate, and install it on your Mac device.
    • Create certificates

This step is to use the Apple private key to sign the Mac public key and generate certificate files iOS_development. cer and iOS_Distribution. cer

  • Third, generate mobileprovision
    • You can create Mobileprovision in a development environment or a production environment

This step is to use the Apple private key to sign the devices, APP ID, entitlement, and certificate file to generate the mobileprovision file. The generated Mobileprovision file determines which devices the App can be installed on, the BundleId of the App that can be installed, and the permissions the App has.

Apple official verification process

Apple’s official verification process is as follows:

Heavy signature

When we reverse engineer an App, we write the corresponding plug-in for the App and install it on our own jailbroken phone. However, the reverse App only works on your jailbroken phone, and if you want to repackage the App and our own plugins and install them on an unjailbroken iPhone, you’ll need to learn how to re-sign the App.

Before learning to re-sign, you need to pay attention to a few points

  • First, the executable file in the installation package must be shelled before re-signing takes effect; otherwise, the installation will fail
  • Second, the mobileprovision file required for re-signing must be applied for by a paid developer account. A free developer account cannot be re-signed.
  • Third, all dynamic libraries in the.app package (.framework,.dylib), AppExtension (PlugIns folder, extension name is appex), WatchApp (Watch folder) need to be re-signed

The CodeSign directive is re-signed

Specific steps

  • First, you need to prepare an Embedded. Mobileprovision file (which must be generated by a paid developer account and the appID, device, etc.) and put this file into the. App package

Mobileprovision files can be generated in either of two ways. The first is automatically generated by Xcode and can be found in the compiled App package. The second is generated by using the Apple official website.

  • Extract entitlements from embedded. Mobileprovision file, entitlements. Plist file, there are two steps:
// Export permission information from the embedded. Mobileprovision file to the temp.plist file security CMS -d -I embedded. Mobileprovision > temp.plist# Then use PlistBuddy tool to convert temp.plist into a file Entitlements. Plist in Entitlements format
/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist
Copy the code
  • View the certificate available on the Mac and obtain the Identity of the certificate, which is required for subsequent signature. The specific instructions are as follows
security find-identity -v -p codesigning
Copy the code

The result is as follows

➜ ~ security find - identity - v - p D9E2802126C89BF6BF6621064FC5547F895FC25E codesigning 1)"iPhone Developer: [email protected] (KT9PJDKFVG)"
Copy the code
  • Re-sign all dynamic libraries and AppExtension in the. App package, if these dynamic libraries or AppExtension have been modified, if there is no modified dynamic library or AppExtension, you can skip this step. The instructions are as follows:
# -fs is short for -f-sCodesign-fs certificate ID xxx.dylibCopy the code
  • For. App package signature, need to use entitlements. Plist file generated before, the command is as follows:
Codesign-fs Certificate ID -- Entitlements.plist XXX. AppCopy the code

Theos plugin is re-signed

When we build our own project with Xcode, we know the source code, so we know how to modify the Mach-O file, but if we reverse engineer someone else’s App, we don’t know the source code, so we can’t modify the Mach-O file directly.

You learned about Theos in previous articles and how to create Tweak projects to change the behavior of your App. See iOS Reverse Learning 6 (Theos Walkthrough) for details.

Tweak loading mode

Once the Tweak project is created and installed on a jailbroken phone via Cydia, you can change the behaviour of the App. How does that work?

  • First, the Tweak project is compiled to produce a dylib dynamic library file in the Tweak project directory. Theos /obj/debug/.
  • After executing make Package, generate the corresponding deb file and store it in packages directory.
  • Execution after make install, through Cydia installed to mobile phones, dylib file in ~ / Library/MobileSubstrate/DynamicLibraries/directory.
  • After the App starts, dylib will be loaded into the memory at the same time. If the App accesses the method in the class we hook, the method in Dylib will be directly executed.

Injection of dynamic libraries

Tweak project essentially makes dynamic libraries and they are not stored in the. App directory, so the first thing you need to do to install our reverse Tweak app on someone else’s phone is to inject the dynamic libraries from Tweak project into an executable in your app, aka a Mach-O file.

You can use the insert_dylib library to inject dynamic libraries into mach-O files, and you can download the insert_dylib tool from the insert_dylib library home page. Compile in the Release environment to get command line tools, and put the command line tools in /usr/local/bin.

Insert_dylib library usage

Insert_dylib essentially adds LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB to Load Commands in the Mach-O file. Specific injection methods are as follows:

Insert_dylib dynamic library loading path mach-o file --all-yes --weakCopy the code
  • The –weak option indicates that the App will not report an error even if the currently injected dynamic library cannot be found
  • –all-yes Indicates that all the following options are set to yes
View dynamic library dependencies for Mach-O

There are two ways to view dynamic library dependency information

  • Check the dynamic library dependencies of Mach-O using otool
Otool -l Mach -o fileCopy the code

  • View dynamic library dependencies for Mach-O using MachOView

Change the loading address of the dynamic library

After the dynamic library is injected into the mach-O file, you need to change the loading address of the dynamic library in the mach-O file, otherwise an error will be reported when the App runs because the dynamic library is not found.

You can use the install_name_tool directive to change the loading address of dynamic libraries in the Mach -o file:

Install_name_tool -change Old address New address Mach -o fileCopy the code

Note that the new address in the above directive must be filled with the full path address, but we do not know the specific address stored in dylib after the App is installed on the phone, so we can use the following two common environment variables:

  • The @executable_path represents the directory where the executables are located, which is where the Mach-o files are located. We put dylib in the same directory as the executables, and then changed the address to @executable_path/dylib name. This means that when loading a dynamic library, look for the dynamic library in the directory where the executable resides.
  • Loader_path indicates the directory where the dynamic library resides. This environment variable is usually used when the dynamic library depends on other dynamic libraries. If the dynamic library we need to inject also depends on other dynamic libraries, then we need to put the dependent dynamic library in the same directory as the original dynamic library. Then change the loading address of the dynamic library to @loader_path/ dynamic library name. This means loading the dependent dynamic library in the original dynamic library directory.

Theos developed dynamic library plug-in notes

  • We use the dylib plugin developed by Theos, which is dependent on CydiaSubstrate by default because it was installed using Cydia. CydiaSubstrate deposit plug-in directory for iPhone/Library/Frameworks/CydiaSubstrate framework/CydiaSubstrate.
  • If we want to package the dynamic library plug-in we developed into IPA, we need to package CydiaSubstrate into IPA at the same time, and modify the loading address of CydiaSubstrate.

Re-signing GUI tool

iReSign

You can click download iReSign source, run the Mac app inside, provide the path of the.app package, Entitlements. Plist path and Embedded. Mobileprovision path, you can re-sign the.app, and then package to generate an IPA file.

iOS App Signer

You can click to download the source code of iOS App Signer, select the Release environment for compilation, get the compiled Mac application, and then use it directly. Simply provide the path to the.app package and the path to Embedded. Mobileprovision

Re-signing exercise

Exercise 1: Re-sign the.app file generated by Xcode using the CoDesign directive

Now let’s use Xcode to generate the.app package and implement the re-signing process step by step.

  • First, create the iOS project TestSign and add the following code to the ViewController
#import "ViewController.h"

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *labelA;
@property (weak, nonatomic) IBOutlet UILabel *labelB;
@property (weak, nonatomic) IBOutlet UILabel *labelResult;

@end

@implementation ViewController

int a = 10;
int b = 20;

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.labelA.text = [NSString stringWithFormat:@"%d",a];
    self.labelB.text = [NSString stringWithFormat:@"%d",b];
    self.labelResult.text = [NSString stringWithFormat:@"%d",a + b];
}


@end
Copy the code
  • After running the project, you can see the effect of 10 + 20 = 30 on the interface. At this time, you can get the. App package testsign.app generated under the compilation Product directory
  • Ipa = PayLoad. Ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa = paypay. ipa The Mobileprovision file is automatically generated by Xcode and contains the current device.
  • In the mach-o file, global variables are stored in the __DATA section. Use MachOView to open the executable in estSign.app, as shown below

<font color=red>0A</font> 10, which corresponds to the global variable A, <font color=red>14, which corresponds to the global variable B, which corresponds to 20.Copy the code
  • Modify the Mach-o file directly to change the value of the global variable A to 14, that is, to 20.

  • If you install ipA on the same mobile phone by using iFunBox, there will be a message indicating installation failure, because the Mach-O file in app has been tampered and its signature will be invalid. Therefore, the signature verification of the App will fail when it is installed on iPhone, so the installation will fail. Now you need to re-sign your dot app.

  • Get embedded. Mobileprovision file in testSign. app package, extract entitlements. Plist file from embedded. Mobileprovision file, instructions as follows:

// Export permission information from the embedded. Mobileprovision file to the temp.plist file security CMS -d -I embedded. Mobileprovision > temp.plist# Then use PlistBuddy tool to convert temp.plist into a file Entitlements. Plist in Entitlements format
/usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist

Copy the code
  • Run the following command to obtain the certificate ID, which must be consistent with that in the embedded. Mobileprovision file:
security find-identity -v -p codesigning
Copy the code
  • Re-sign the.app package using the CoDesign directive
codesign -fs 1BEA2FE8783A297CF30B7728849EB225231D67E8 --entitlements entitlements.plist TestSign.app 
Copy the code

At this point, the testSign. app file is recompressed to obtain IPA, which can be successfully installed on the previous mobile phone. Meanwhile, because the value of global variable A is changed to 20, the interface shows 20 + 20 = 40. The re-signature operation is complete.

Exercise two, Theos plug-in development, injection Tencent video App, install to the non-jailbroken phone

The following is to develop Theos plug-in for Tencent Video, then inject it into Tencent Video App, regenerate IPA and install it on non-jailbroken phones.

  • First, download the Tencent Video App. You can download the unshelled App through Ace Assistant or PP Assistant, or download it from App Store, and then use the Clutch tool to unshuck the App. Note that the App can be re-signed only if it is unshelled; otherwise, the signature is invalid.
  • Connect the mobile phone, use Reveal to view the page of Tencent Video, and find the main interface QLHomeController. For details, please refer to iOS Reverse Learning ii (Remote Control of iPhone on Mac) and iOS Reverse Learning III (Cycript).
  • Create Tweak project. Create Tweak project using the nic.pl directive, fill in the required information step by step. Note that MobileSubstrate Bundle filter filled in the Bundle ID of Tencent Video App, and obtained the Bundle ID com.0ceh.live4iphone through Cycript.
  • Add the following code to Tweak. X file and the effect will be to pop up an Alert box on the homepage of Tencent Video.

@interface QLHomeController

- (id)presentViewController:(id)controller animated:(BOOL)animated completion:(id)completion;

@end

%hook QLHomeController

- (void)viewDidAppear:(BOOL)animated{

    %orig;
  
    UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"Prompt box" message:@"Test the Theos plugin" preferredStyle:UIAlertControllerStyleAlert];
    [alertVc addAction:[UIAlertAction actionWithTitle:@"Closed" style:UIAlertActionStyleCancel handler:nil]];
    [self presentViewController:alertVc animated:YES completion:nil];
}

%end

Copy the code
  • Execute make Package && make install to package Tweak project, install it to iPhone through Cydia, wait for iPhone to restart, then open Tencent Video, you can see the popbox we wrote on the home page.

  • Get some files required for the following signature

    • On the iPhone/var/mobile/Containers/Bundle/Application/directory to find live4iphone. The app install package.
    • In the/Library/MobileSubstrate/DynamicLibraries/directory to find our plugin generated by the dynamic libraries written test_live. Dylib.
    • In the/Library/Frameworks/CydiaSubstrate framework/directory to find test_live dylib dependent dynamic Library CydiaSubstrate.
    • Get the Embedded. Mobileprovision file used in the previous exercise.
  • Copy the test_live.dylib, CydiaSubstrate, and Embedded. Mobileprovision files to the Live4iphon. app package.

  • Inject the dynamic library into the executable in the live4iphone-app package

insert_dylib @executable_path/test_live.dylib live4iphone --all-yes --weak live4iphone
Copy the code

If the following information is displayed, the injection is successful:

➜ live4iphone. App insert_dylib@executable_path /test_live.dylib live4iphone --all-yes --weak Live4iphone live4iphone already exists. Overwrite it? [y/n] y Binary is a fat binary with 2 archs. LC_CODE_SIGNATURE loadcommand found. Remove it? [y/n] y
LC_CODE_SIGNATURE load command found. Remove it? [y/n] y
Added LC_LOAD_WEAK_DYLIB to all archs in live4iphone
Copy the code

Using the otool command or MachOView to check the executable file of Tencent Video, you can see that the dynamic library has been injected into the Mach-O file

  • Modify the path of the CydiaSubstrate library
    • Check the dependencies for test_live.dylib using otool.

<font color=red> the path of CydiaSubstrate</font> is <font Color = red > / Library/Frameworks/CydiaSubstrate framework/CydiaSubstrate < / font >, but in a prison break on the mobile phone is not the path, The install_name_tool directive is used to change the loading path of the dynamic library. ``` install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/CydiaSubstrate Dylib <font color=red>test_live.dylib</font> <font color=red> <font color=red>@loader_path/CydiaSubstrate</font>Copy the code
  • Resigning test_live.dylib and CydiaSubstrate respectively
➜ live4iphone. App codesign - fs 1 bea2fe8783a297cf30b7728849eb225231d67e8 test_live. Dylib test_live. Dylib: Replacing existing signature ➜ live4iphone. App codesign - fs 1 bea2fe8783a297cf30b7728849eb225231d67e8 CydiaSubstrate CydiaSubstrate: Replacing Existing Signature ➜ Live4iPh.appCopy the code
  • Use iOS App Signer to re-sign live4iphon. App to generate ipA installation package

  • If live4iphon. ipa is installed on a non-jailbroken phone, it can be found that the installation is successful, and a pop-up box appears after entering.