Slide 1

Slide 1 text

Hacking iOS Simulator Writing your own plugin for Simulator, enhancing development workflow INTRODUCING @ahmed_sulajman

Slide 2

Slide 2 text

Ahmed Sulaiman Co-founder of https://flawlessapp.io & Engineer & UI Designer ahmed@flawlessapp.io @ahmed_sulajman HELLO @ahmed_sulajman

Slide 3

Slide 3 text

HELLO Our Products @ahmed_sulajman Reduce App Awesome Design Tools Design Tools Weekly

Slide 4

Slide 4 text

HELLO Our Products DESIGN REAL APP iOS Simulator @ahmed_sulajman

Slide 5

Slide 5 text

SIMULATOR INTRO Loading custom code into iOS Simulator And how this will enhance your developmnet worflow @ahmed_sulajman !

Slide 6

Slide 6 text

SIMULATOR INTRO Current state of Simulator and Xcode @ahmed_sulajman

Slide 7

Slide 7 text

@ahmed_sulajman SIMULATOR INTRO New in Simulator since Xcode 9 Launch multiple iOS Simulator Resize iOS Simulator like regular window Full-Screen mode along with Xcode

Slide 8

Slide 8 text

@ahmed_sulajman SIMULATOR INTRO Why Simulator is important 30% 30% 30% 10% ! " # Testing in iOS Simulator during development Actual Development Communication Meetings Compiling & Building…

Slide 9

Slide 9 text

@ahmed_sulajman AGENDA Intro to simctl What is simctl and what it allows you to do now ! Method Swizzling How you can change implementation of the method you have no access to " Building Dynamic Library How to make a dynamic library for iOS and how to upload it to iOS Simulator # What’s next for iOS Simulator plugins Where to go from here and how you can enhance iOS Simulator plugins even more $ simctl

Slide 10

Slide 10 text

@ahmed_sulajman Intro to simctl What is simctl and what it allows you to do now !

Slide 11

Slide 11 text

@ahmed_sulajman SIMCTL What is simctl Simulator ≠ Emulator

Slide 12

Slide 12 text

@ahmed_sulajman SIMCTL What is simctl Simulator ≠ Emulator

Slide 13

Slide 13 text

@ahmed_sulajman SIMCTL What is simctl > xcrun simctl Command line utility to control the Simulator

Slide 14

Slide 14 text

@ahmed_sulajman SIMCTL What simctl can do devices list > xcrun simctl list -j [devices|devicetypes|runtimes|pairs] List available devices, device types, runtimes, or device pairs

Slide 15

Slide 15 text

@ahmed_sulajman SIMCTL > xcrun simctl list -j [devices|devicetypes|runtimes|pairs] > xcrun simctl list -j devices $someSearchTerm What simctl can do devices list

Slide 16

Slide 16 text

@ahmed_sulajman SIMCTL > xcrun simctl list -j [devices|devicetypes|runtimes|pairs] { "devices" : { "com.apple.CoreSimulator.SimRuntime.iOS-12-2" : [ { "availability" : "(available)", "state" : "Shutdown", "isAvailable" : true, "name" : "iPad Air (3rd generation)", "udid" : "18D30337-C8E3-43AE-8765-5D935D9408BF", "availabilityError" : "" } ] } } What simctl can do devices list

Slide 17

Slide 17 text

@ahmed_sulajman SIMCTL > xcrun simctl boot Boot a specific device > xcrun simctl shutdown | all Shutdown a specific device or all devices What simctl can do boot & shutdown device

Slide 18

Slide 18 text

@ahmed_sulajman SIMCTL > xcrun simctl io booted recordVideo --type=mp4 Records the display to the specified file or url (use "-" for stdout). What simctl can do video recording

Slide 19

Slide 19 text

@ahmed_sulajman SIMCTL > xcrun simctl spawn Spawn a process by executing a given executable on a device. ! What simctl can do spawn process

Slide 20

Slide 20 text

@ahmed_sulajman SIMCTL > xcrun simctl spawn syslog leaks malloc_history ... heap notifyutil log stringdups iOS Simulator Tools and utils in iOS Runtime macOS Environment Launching process from macOS inside Simulator spawn What simctl can do spawn process

Slide 21

Slide 21 text

@ahmed_sulajman SIMCTL > xcrun simctl spawn Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/ Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/ Resources/RuntimeRoot/usr/... Collect system log into a log archive, watch live system logs log ! Search through a process for leaked memory leaks ! Displays/aggregates allocation histories in a process malloc_history ! What simctl can do spawn process

Slide 22

Slide 22 text

@ahmed_sulajman SIMCTL > xcrun simctl spawn booted What simctl can do spawn process

Slide 23

Slide 23 text

@ahmed_sulajman SIMCTL > xcrun simctl spawn booted syslog leaks malloc_history ... heap notifyutil launchctl log stringdups launchd spawn What simctl can do spawn process

Slide 24

Slide 24 text

@ahmed_sulajman SIMCTL SimulatorKit framework Xcode SimulatorKit simctl

Slide 25

Slide 25 text

@ahmed_sulajman SIMCTL Conclusions simctl is the main interface to iOS Simulator simctl via simctl interact with Simulator and explore its process as it isn’t an Emulator ! spawn tool allows you to launch internal tools spawn By typing exact executable you can spawn a process in iOS Simulator ! Using launchctl allows you to manage services launchctl spawn allows you to launch internal tools inside iOS Simulator !

Slide 26

Slide 26 text

@ahmed_sulajman Method Swizzling How you can change implementation of the method you have no access to !

Slide 27

Slide 27 text

@ahmed_sulajman Objective-C Zone

Slide 28

Slide 28 text

@ahmed_sulajman SWIZZLING How does it work Objective-C Runtime The Objective-C runtime is a runtime library that provides support for the dynamic properties of the Objective-C language, and as such is linked to by all Objective-C apps #import

Slide 29

Slide 29 text

@ahmed_sulajman SWIZZLING How does it work class dispatch table Objetive-C Class Dispatch Table

Slide 30

Slide 30 text

@ahmed_sulajman SWIZZLING How does it work class dispatch table Dispatch Table Objetive-C Class Method Selector Implementation Method Selector Implementation Method Selector Implementation

Slide 31

Slide 31 text

@ahmed_sulajman SWIZZLING How does it work class dispatch table @interface HelloRuntime: NSObject - (void)hello:(NSString *)text; @end @implementation HelloRuntime - (void)hello:(NSString *)text { NSLog(@"Hello, %@!", text); } @end

Slide 32

Slide 32 text

@ahmed_sulajman SWIZZLING How does it work Method: -[hello:] Selector: @selector(hello:) class dispatch table NSLog(@"Hello, %@!", text); Implementation

Slide 33

Slide 33 text

@ahmed_sulajman SWIZZLING How does it work replace method implementation NSLog(@"Hello, %@!", text); Implementation Alt Implementation Method: -[hello:] Method: -[alt_hello:] Selector: @selector(hello:) Selector: @selector(alt_hello:)

Slide 34

Slide 34 text

@ahmed_sulajman SWIZZLING How does it work replace method implementation Alt Implementation NSLog(@"Hello, %@!", text); Implementation Method: -[hello:] Method: -[alt_hello:] Selector: @selector(hello:) Selector: @selector(alt_hello:)

Slide 35

Slide 35 text

@ahmed_sulajman - (void)alt_hello:(NSString *)text { [self alt_hello:@"Cocoaheads Kyiv"]; // DO not call original -[hello:] here // it will lead to infinite loop // [self hello:@"Cocoaheads Kyiv"]; } SWIZZLING How does it work replace method implementation

Slide 36

Slide 36 text

@ahmed_sulajman SWIZZLING How to implement it How-to Swizzle + (void)load { }

Slide 37

Slide 37 text

@ahmed_sulajman SWIZZLING How to implement it How-to Swizzle + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ }); }

Slide 38

Slide 38 text

@ahmed_sulajman SWIZZLING How to implement it + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(hello:); SEL swizzledSelector = @selector(alt_hello:); Method originalMethod = class_getInstanceMethod(class, originalSeletor); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); method_exchangeImplementations(originalMethod, swizzledMethod); }); } How-to Swizzle

Slide 39

Slide 39 text

@ahmed_sulajman SWIZZLING How to implement it + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(hello:); SEL swizzledSelector = @selector(alt_hello:); Method originalMethod = class_getInstanceMethod(class, originalSeletor); Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); method_exchangeImplementations(originalMethod, swizzledMethod); }); } How-to Swizzle method_exchangeImplementations( ) Use method_exchangeImplementations( ) with cautions. Better explore class_addMethod( ) and class_replaceMethod( ) ⚠

Slide 40

Slide 40 text

@ahmed_sulajman SWIZZLING Conclusions Every class has dispatch table It allows the class to understand which selector corresponds to which method ! Change dispatch table in runtime Objective-C Runtime allow us to change dispatch table and assign different IMP to SEL ! Pay a!ention when doing swizzling Use +[load] and dispatch_once to ensure your code runs once when the class has been loaded !

Slide 41

Slide 41 text

@ahmed_sulajman Building Dynamic Library How to make a dynamic library for iOS and how to upload it to iOS Simulator !

Slide 42

Slide 42 text

@ahmed_sulajman DYLIB What is dynamic library Dynamic Library

Slide 43

Slide 43 text

@ahmed_sulajman DYLIB What is dynamic library Static vs Dynamic App with Dynamic Libraries App with Static Libraries VS Source Code Static Libs Source Code Dynamic Libs References

Slide 44

Slide 44 text

@ahmed_sulajman DYLIB What is dynamic library How does it work DYLD_LIBRARY_PATH Specify primary directories where in file system dynamic loader needs to search for dynamic libraries. DYLD_FALLBACK_LIBRARY_PATH Specify secondary directories where in file system dynamic loader needs to search for dynamic libraries before searching in system directories in case there was nothing found in primary directories. DYLD_INSERT_LIBRARIES Specify dynamic libraries which needs to be loaded before primary libraries.

Slide 45

Slide 45 text

@ahmed_sulajman DYLIB What is dynamic library How does it work DYLD_LIBRARY_PATH Specify primary directories where in file system dynamic loader needs to search for dynamic libraries. DYLD_FALLBACK_LIBRARY_PATH Specify secondary directories where in file system dynamic loader needs to search for dynamic libraries before searching in system directories in case there was nothing found in primary directories. DYLD_INSERT_LIBRARIES Specify dynamic libraries which needs to be loaded before primary libraries.

Slide 46

Slide 46 text

@ahmed_sulajman Demo DYLIB How to build dynamic library

Slide 47

Slide 47 text

@ahmed_sulajman What’s next for iOS Simulator plugins Where to go from here and how you can enhance iOS Simulator plugins even more !

Slide 48

Slide 48 text

@ahmed_sulajman NEXT STEPS What might be improved Add communication channel Launch simple server in iOS Simulator plugin to send requests and handle them !

Slide 49

Slide 49 text

@ahmed_sulajman NEXT STEPS What might be improved Add communication channel Launch simple server in iOS Simulator plugin to send requests and handle them ! Swizzle public and private methods BY using objc_getClass("ClassName") you can get access to privat classes and get its instance. Explore class-dump to get privat methods !

Slide 50

Slide 50 text

@ahmed_sulajman NEXT STEPS Real use-cases Add communication channel Launch simple server in iOS Simulator plugin to send requests and handle them " Swizzle public and private methods BY using objc_getClass("ClassName") you can get access to privat classes and get its instance. Explore class-dump to get privat methods " Capture screenshot with context Intercept screenshot capture event to put additional information for debugging purpose !

Slide 51

Slide 51 text

@ahmed_sulajman NEXT STEPS Real use-cases Add communication channel Launch simple server in iOS Simulator plugin to send requests and handle them " Swizzle public and private methods BY using objc_getClass("ClassName") you can get access to privat classes and get its instance. Explore class-dump to get privat methods " Live UI editing Select UI components in running application and change their style in the runtime ! Capture screenshot with context Intercept screenshot capture event to put additional information for debugging purpose !

Slide 52

Slide 52 text

@ahmed_sulajman Conclusions simctl is a powerfull iOS Simulator tool simctl by itself opens a range of possibnoities for interacting with iOS Simulator ☝ Method Swizzling Using Objective-C runtime you can change implementation of methods you have to access to ☝ Dynamic Libraries as plugins for iOS Simulator Build and upload dynamic libraries into iOS Simulator to enhamce its functionaly ☝

Slide 53

Slide 53 text

Hacking iOS Simulator THANK YOU FOR LISTENING! Ahmed Sulaiman ahmed@flawlessapp.io @ahmed_sulajman

Slide 54

Slide 54 text

Links Mach-O Executables: https://www.objc.io/issues/6-build-tools/mach-o-executables/ Attributes in Clang: https://clang.llvm.org/docs/AttributeReference.html Method Swizzling: https://nshipster.com/method-swizzling/ Objective-C Runtime: https://developer.apple.com/documentation/objectivec/objective-c_runtime Associated Objects https://nshipster.com/associated-objects/ Overview of Dynamic Libraries https://developer.apple.com/library/archive/documentation/DeveloperTools/ Conceptual/DynamicLibraries/100-Articles/OverviewOfDynamicLibraries.html DYLD man page https://www.manpagez.com/man/1/dyld/ Dynamic linking on iOS http://ddeville.me/2014/04/dynamic-linking Static and Dynamic Libraries http://nickdesaulniers.github.io/blog/2016/11/20/static-and-dynamic-libraries/ class-dump tool https://github.com/nygard/class-dump