Microsoft Word - iOSAppReverseEngineering.docx

(Romina) #1

6.3.2 Change process execution flow


Why do we need to change process execution flow? Commonly it’s because the code we


want to debug could only be executed in specific conditions, which are hard to meet in the


original execution flow. Under such circumstances, we have to change the flow to redirect the


process to execute the target code for debugging. Reads awkward? Let’s see an example.


// clang -arch armv7 -isysroot `xcrun --sdk iphoneos --show-sdk-path` -framework
Foundation -framework UIKit -o MainBinary main.m

#include <stdio.h>
#include <dlfcn.h>
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

extern void ImportantAndComplicatedFunction(void)
{
NSLog(@"iOSRE: Suppose I'm a very important and complicated function");
}

int main(int argc, char **argv)
{
if ([[[UIDevice currentDevice] systemVersion] isEqualToString:@"8.1.1"])
ImportantAndComplicatedFunction();
return 0;
}

Save this snippet as main.m, and compile it with the sentence in the comments, then copy


MainBinary to “/var/tmp/” on iOS:


snakeninnys-MacBook:6 snakeninny$ scp MainBinary root@iOSIP:/var/tmp/
MainBinary 100% 49KB
48.6KB/s 00:00

Run it:


FunMaker-5:~ root# /var/tmp/MainBinary
FunMaker-5:~ root#

Because I’m using iOS 8.1, there is no output for sure. What if I am interested in


ImportantAndComplicatedFunction but don’t have iOS 8.1.1 in hand? Then I have to


dynamically change the execution flow to make this function get called. I’ll show you how,


please keep focused. Drag and drop MainBinary into IDA, then locate to the branch before


ImportantAndComplicatedFunction, as shown in figure 6-52.

Free download pdf