Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

CocoaHeads Ukraine

July 28, 2019
Tweet

More Decks by CocoaHeads Ukraine

Other Decks in Programming

Transcript

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. SIMULATOR INTRO Current state of Simulator and Xcode
    @ahmed_sulajman

    View Slide

  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

    View Slide

  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…

    View Slide

  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

    View Slide

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

    View Slide

  11. @ahmed_sulajman
    SIMCTL What is simctl
    Simulator ≠ Emulator

    View Slide

  12. @ahmed_sulajman
    SIMCTL What is simctl
    Simulator ≠ Emulator

    View Slide

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

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  17. @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

    View Slide

  18. @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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  24. @ahmed_sulajman
    SIMCTL SimulatorKit framework
    Xcode SimulatorKit
    simctl

    View Slide

  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
    !

    View Slide

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

    View Slide

  27. @ahmed_sulajman
    Objective-C Zone

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide

  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

    View Slide

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

    View Slide

  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:)

    View Slide

  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:)

    View Slide

  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

    View Slide

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

    View Slide

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

    View Slide

  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

    View Slide

  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( )

    View Slide

  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
    !

    View Slide

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

    View Slide

  42. @ahmed_sulajman
    DYLIB What is dynamic library
    Dynamic Library

    View Slide

  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

    View Slide

  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.

    View Slide

  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.

    View Slide

  46. @ahmed_sulajman
    Demo
    DYLIB How to build dynamic library

    View Slide

  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
    !

    View Slide

  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
    !

    View Slide

  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
    !

    View Slide

  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
    !

    View Slide

  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
    !

    View Slide

  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

    View Slide

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

    View Slide

  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

    View Slide