$30 off During Our Annual Pro Sale. View Details »

EXC_BAD_ACCESS in <redacted>. Now what?

EXC_BAD_ACCESS in <redacted>. Now what?

Swizzling your way around proprietary code bugs and crashes.

Sash Zats

July 08, 2015
Tweet

More Decks by Sash Zats

Other Decks in Technology

Transcript

  1. None
  2. Intro

  3. Intro

  4. Intro

  5. Intro

  6. None
  7. None
  8. #!/usr/bin/ruby developers_dir = `xcode-select -p`.chomp frameworks_dir = "#{developers_dir}/Platforms/iPhoneSimulator.platform" frameworks_dir +=

    "/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/*" swift_frameworks_count = 0 Dir[frameworks_dir].each { |file| framework = "#{file}/#{File.basename(file, ".*")}" next unless File.exist?(framework) puts framework unless `otool -l #{framework} | grep -i swift`.empty? }
  9. System frameworks built with Swift1 1 This slide is intentionally

    left blank
  10. It's not my fault

  11. Demo: UIKitty

  12. if let cls = NSClassFromString("UIPrinterSearchingView") { let block: @objc_block (AspectInfo)

    -> Void = { (aspectInfo) in if let view = aspectInfo.instance() as? UIView { view.frame.size.height = view.superview!.frame.height - 44 } } let blockObject = unsafeBitCast(block, AnyObject.self) cls.aspect_hookSelector( Selector("layoutSubviews"), withOptions: .PositionAfter, usingBlock: blockObject, error: nil ) }
  13. Swizzling 1. Swizzling is still possible in Swift. 2. Set

    applicable OS versions for the patch. 3. Test extensively. On device! 4. Aspect oriented programming.
  14. Organizer

  15. Demo: Organizer

  16. None
  17. None
  18. None
  19. Hopper Disassembler

  20. None
  21. None
  22. None
  23. None
  24. None
  25. diffArrays(var_24, eax, edi->_changedItems, nil, nil, nil, nil, nil); void diffArrays(NSArray

    <NSManagedObject *> *arg0, NSArray <NSManagedObject *> *arg1, NSArray <NSManagedObject *> *arg2, NSIndexSet **arg3, NSIndexSet **arg4, NSIndexSet **arg5, NSArray <NSManagedObject *> **arg6, NSIndexSet **arg7);
  26. The easiest part

  27. // Internal structures struct swift_func_wrapper { var trampolinePtr: UnsafeMutablePointer<uintptr_t> var

    functionObject: UnsafeMutablePointer<swift_func_object> } struct swift_func_object { var original_type_ptr: UnsafeMutablePointer<uintptr_t> var unknown: UnsafeMutablePointer<UInt64> var address: uintptr_t var selfPtr: UnsafeMutablePointer<uintptr_t> } // Method we want to call func hello(world: String) -> Void typedef helloFn = (String) -> Void // C function pointer let fn = UnsafeMutablePointer<helloFn>.alloc(1) fn.initialize(hello) let fnWrapper = UnsafeMutablePointer<swift_func_wrapper>(fn) let opaque = COpaquePointer(bitPattern: fnWrapper.memory.functionObject.memory.address) let cFunction = CFunctionPointer<helloFn>(opaque)
  28. // Internal structures struct swift_func_wrapper { var trampolinePtr: UnsafeMutablePointer<uintptr_t> var

    functionObject: UnsafeMutablePointer<swift_func_object> } struct swift_func_object { var original_type_ptr: UnsafeMutablePointer<uintptr_t> var unknown: UnsafeMutablePointer<UInt64> var address: uintptr_t var selfPtr: UnsafeMutablePointer<uintptr_t> }
  29. // Method we want to call func hello(world: String) ->

    Void { print("Hello, \(world)") } typedef helloFn = (String) -> Void
  30. // C function pointer let fn = UnsafeMutablePointer<helloFn>.alloc(1) fn.initialize(hello) let

    fnWrapper = UnsafeMutablePointer<swift_func_wrapper>(fn) let address = fnWrapper.memory.functionObject.memory.address let opaque = COpaquePointer(bitPattern: address) let cFunction = CFunctionPointer<helloFn>(opaque)
  31. C-functions patching · Find the goddamn thing. · Patch implementation.

    · Fishhook - dynamically rebinding symbols in Mach-O binaries. · Call the original implementation maybe?
  32. Conclusions · Objective-C + swizzling = ! · C functions2

    + fishhook = " · Swift + optimization -O = # 2 calling IMP directly from Swift might be possible with @convention syntax
  33. Credits · Perceptual Debugging @kendalldevdiary · Reverse Engineering @Dirk_Gently ·

    Unsafe Swift: For Fun & Profit @xenadu02 · Peter Steinberger's blog by @steipete · All WWDC sessions about debugging by @apple · Aspects by @steipete, fishhook by @facebook
  34. @zats

  35. Questions?