Hacking iOS Simulator

Hacking iOS Simulator

Talk by Ahmed Sulaiman

Originally posted here: https://www.slideshare.net/AhmedSulaiman15/hacking-ios-simulator-writing-your-own-plugins-for-simulator

Ахмед расскажет нам о том, как сломать, починить, снова сломать и снова починить один из самых загадочных инструментов iOS-девелопера - iOS Simulator.
Ахмед тезисно о своем докладе:
➡️ рассказываю про низкоуровневый механизм, который позволяет писать свой кастомный функционал и загружать его в симулятор
➡️ делаю небольшой пример и демо как это работает
➡️ рассказываю, как еще можно расширить этот пример. (в частности как построить механизм обратной связи с macOS и iOS в симуляторе)
➡️ еще одно минимальное демо такого механизма

This talk was made for CocoaHeads Kyiv #15 which took place Jul 28, 2019. (https://cocoaheads.org.ua/cocoaheadskyiv/15)

Video: https://youtu.be/h4a7aJa__aE

Db84cf61fdada06b63f43f310b68b462?s=128

CocoaHeads Ukraine

July 28, 2019
Tweet

Transcript

  1. Hacking iOS Simulator Writing your own plugin for Simulator, enhancing

    development workflow INTRODUCING @ahmed_sulajman
  2. Ahmed Sulaiman Co-founder of https://flawlessapp.io & Engineer & UI Designer

    ahmed@flawlessapp.io @ahmed_sulajman HELLO @ahmed_sulajman
  3. HELLO Our Products @ahmed_sulajman Reduce App Awesome Design Tools Design

    Tools Weekly
  4. HELLO Our Products DESIGN REAL APP iOS Simulator @ahmed_sulajman

  5. SIMULATOR INTRO Loading custom code into iOS Simulator And how

    this will enhance your developmnet worflow @ahmed_sulajman !
  6. SIMULATOR INTRO Current state of Simulator and Xcode @ahmed_sulajman

  7. @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
  8. @ahmed_sulajman SIMULATOR INTRO Why Simulator is important 30% 30% 30%

    10% ! " # Testing in iOS Simulator during development Actual Development Communication Meetings Compiling & Building…
  9. @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
  10. @ahmed_sulajman Intro to simctl What is simctl and what it

    allows you to do now !
  11. @ahmed_sulajman SIMCTL What is simctl Simulator ≠ Emulator

  12. @ahmed_sulajman SIMCTL What is simctl Simulator ≠ Emulator

  13. @ahmed_sulajman SIMCTL What is simctl > xcrun simctl Command line

    utility to control the Simulator
  14. @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
  15. @ahmed_sulajman SIMCTL > xcrun simctl list -j [devices|devicetypes|runtimes|pairs] > xcrun

    simctl list -j devices $someSearchTerm What simctl can do devices list
  16. @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
  17. @ahmed_sulajman SIMCTL > xcrun simctl boot <device> Boot a specific

    device > xcrun simctl shutdown <device> | all Shutdown a specific device or all devices What simctl can do boot & shutdown device
  18. @ahmed_sulajman SIMCTL > xcrun simctl io booted recordVideo --type=mp4 <file

    path> Records the display to the specified file or url (use "-" for stdout). What simctl can do video recording
  19. @ahmed_sulajman SIMCTL > xcrun simctl spawn Spawn a process by

    executing a given executable on a device. ! What simctl can do spawn process
  20. @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
  21. @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
  22. @ahmed_sulajman SIMCTL > xcrun simctl spawn booted <tool name> What

    simctl can do spawn process
  23. @ahmed_sulajman SIMCTL > xcrun simctl spawn booted <tool name> syslog

    leaks malloc_history ... heap notifyutil launchctl log stringdups launchd spawn What simctl can do spawn process
  24. @ahmed_sulajman SIMCTL SimulatorKit framework Xcode SimulatorKit simctl

  25. @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 !
  26. @ahmed_sulajman Method Swizzling How you can change implementation of the

    method you have no access to !
  27. @ahmed_sulajman Objective-C Zone

  28. @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 <objc/runtime.h>
  29. @ahmed_sulajman SWIZZLING How does it work class dispatch table Objetive-C

    Class Dispatch Table
  30. @ahmed_sulajman SWIZZLING How does it work class dispatch table Dispatch

    Table Objetive-C Class Method Selector Implementation Method Selector Implementation Method Selector Implementation
  31. @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
  32. @ahmed_sulajman SWIZZLING How does it work Method: -[hello:] Selector: @selector(hello:)

    class dispatch table NSLog(@"Hello, %@!", text); Implementation
  33. @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:)
  34. @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:)
  35. @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
  36. @ahmed_sulajman SWIZZLING How to implement it How-to Swizzle + (void)load

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

    { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ }); }
  38. @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
  39. @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( ) ⚠
  40. @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 !
  41. @ahmed_sulajman Building Dynamic Library How to make a dynamic library

    for iOS and how to upload it to iOS Simulator !
  42. @ahmed_sulajman DYLIB What is dynamic library Dynamic Library

  43. @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
  44. @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.
  45. @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.
  46. @ahmed_sulajman Demo DYLIB How to build dynamic library

  47. @ahmed_sulajman What’s next for iOS Simulator plugins Where to go

    from here and how you can enhance iOS Simulator plugins even more !
  48. @ahmed_sulajman NEXT STEPS What might be improved Add communication channel

    Launch simple server in iOS Simulator plugin to send requests and handle them !
  49. @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 !
  50. @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 !
  51. @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 !
  52. @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 ☝
  53. Hacking iOS Simulator THANK YOU FOR LISTENING! Ahmed Sulaiman ahmed@flawlessapp.io

    @ahmed_sulajman
  54. 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