ProxymanApp / atlantis

Capture HTTP/HTTPS, and Websocket from iOS app without proxy.
https://proxyman.io
Apache License 2.0
1.26k stars 93 forks source link

AtlantisHelper crashes when using websockets and Intercom's new package #134

Closed chadparker closed 11 months ago

chadparker commented 1 year ago

Xcode 14.3.1 (14E300c)

Screenshot 2023-08-09 at 8 04 04 AM
NghiaTranUIT commented 1 year ago

Hey @chadparker just wondering: What Atlantis version and iOS version you're using?

I'd like to investigate it 👍

chadparker commented 1 year ago

Atlantis 1.21.1 iOS 15.4 and 16.4

chadparker commented 1 year ago

We have narrowed it down to moving to Intercom's new iOS package.

https://github.com/intercom/intercom-ios   <--- Atlantis worked just fine
https://github.com/intercom/intercom-ios-sp   <--- Atlantis crashed as shown above

When I revert back to the previous version Atlantis works again with websockets.

We were also having issues with the debugger not working while using the newer package:

(lldb) po hourlySummaries.count
error: expression failed to parse:
error: stat cache file '/Users/distiller/project/DerivedData/archive/SDKStatCaches.noindex/iphonesimulator16.4-20E238-.sdkstatcache' not found
error: stat cache file '/Users/distiller/project/DerivedData/archive/SDKStatCaches.noindex/iphonesimulator16.4-20E238-.sdkstatcache' not found

error: couldn't IRGen expression. Please check the above error messages for possible root causes.

but reverting to the previous version of Intercom fixes that as well. Very surprising it would cause issues like this. Going to send them a support message now.

NghiaTranUIT commented 1 year ago

Thanks for the update. Let me know if it's Atlantis bug, then I can check it.

yuravake commented 1 year ago

Having the same issue here, @chadparker did you had a chance to fix this?

chadparker commented 1 year ago

No, @yuravake we sent a support message to Intercom, and they suggested to try their next release but it didn't fix the issue. We reverted our Intercom version for now. Could you create a support ticket with Intercom to raise visibility into this?

yuravake commented 1 year ago

@chadparker yes, will do.

NghiaTranUIT commented 1 year ago

Hi @chadparker @yuravake do you think that I should have a function to enable/disable the WebSocket Interceptor on Atlantis ? So, you can opt-out and prevent internal crashes from the Intercom app.

NghiaTranUIT commented 1 year ago

By default, Atlantis performs the Method Swizzling from all available classes, including the main app, 3rd-party frameworks, and libraries.

I suggest:

It might solve all problems.

chadparker commented 12 months ago

@NghiaTranUIT That sounds like a good solution; that would be a great function to have! I'm not very familiar with the Atlantis code, but if you could give me things to try I'll definitely let you know if it fixes things.

NghiaTranUIT commented 12 months ago

@chadparker @yuravake can you check with the latest version of Intercom ?

Here is my setup:

Result:

CleanShot 2023-10-07 at 09 42 31@2x


NghiaTranUIT commented 12 months ago

@NghiaTranUIT That sounds like a good solution; that would be a great function to have! I'm not very familiar with the Atlantis code, but if you could give me things to try I'll definitely let you know if it fixes things.

Turn out it's not technically feasible:

yuravake commented 12 months ago

@NghiaTranUIT unfortunately, we can still reproduce this crash on the latest versions(

NghiaTranUIT commented 12 months ago

@yuravake can you share with me your setup?

djbe commented 11 months ago

Have the same exact crash.

Some info:

NghiaTranUIT commented 11 months ago

Hix, not sure why I can't reproduce the crash:

@djbe can you share your setup?

Thanks in advance 🙇


Screenshot 2023-11-08 at 10 27 14

djbe commented 11 months ago
Output of `bt` ``` (lldb) bt * thread #6, queue = 'com.apple.NSURLSession-delegate', stop reason = EXC_BAD_ACCESS (code=2, address=0x16d618000) frame #0: 0x00000001051b3840 libsystem_platform.dylib`_platform_memmove + 112 frame #1: 0x00000001800c2ce4 libsystem_blocks.dylib`_Block_copy + 92 * frame #2: 0x00000001047443d4 Atlantis`closure #1 in static AtlantisHelper.swizzleWebSocketReceiveMessage(message=0x00006000000213d0, error=nil, responseHandler=0x0000000104761230 Atlantis`partial apply forwarder for closure #1 (Swift.Optional, Swift.Optional, Swift.Optional) -> () in closure #1 (Swift.AnyObject, Swift.AnyObject) -> () in Atlantis.NetworkInjector._swizzleURLSessionWebSocketReceiveMessageSelector(Swift.AnyObject.Type) -> () at , originalHandler=0x000000016d6127f8) at AtlantisHelper.swift:75:13 frame #3: 0x00000001047449cc Atlantis`thunk for @escaping @callee_guaranteed (@guaranteed NSObject?, @guaranteed NSError?) -> () at :0 frame #4: 0x00000001074780f0 libdispatch.dylib`_dispatch_call_block_and_release + 24 frame #5: 0x000000010747993c libdispatch.dylib`_dispatch_client_callout + 16 frame #6: 0x0000000107481bd8 libdispatch.dylib`_dispatch_lane_serial_drain + 916 frame #7: 0x000000010748291c libdispatch.dylib`_dispatch_lane_invoke + 420 frame #8: 0x000000010748f2f8 libdispatch.dylib`_dispatch_root_queue_drain_deferred_wlh + 324 frame #9: 0x000000010748e754 libdispatch.dylib`_dispatch_workloop_worker_thread + 488 frame #10: 0x000000010549f924 libsystem_pthread.dylib`_pthread_wqthread + 284 ```
Output of `bt all` ``` (lldb) bt all thread #1, queue = 'com.apple.main-thread' frame #0: 0x0000000106be8c10 libsystem_kernel.dylib`mach_msg2_trap + 8 frame #1: 0x0000000106bf9da4 libsystem_kernel.dylib`mach_msg2_internal + 76 frame #2: 0x0000000106bf0e34 libsystem_kernel.dylib`mach_msg_overwrite + 532 frame #3: 0x0000000106be8f88 libsystem_kernel.dylib`mach_msg + 20 frame #4: 0x00000001803c5ed8 CoreFoundation`__CFRunLoopServiceMachPort + 156 frame #5: 0x00000001803c05b8 CoreFoundation`__CFRunLoopRun + 1148 frame #6: 0x00000001803bfd28 CoreFoundation`CFRunLoopRunSpecific + 572 frame #7: 0x000000018986ebc0 GraphicsServices`GSEventRunModal + 160 frame #8: 0x0000000114e4bfdc UIKitCore`-[UIApplication _run] + 868 frame #9: 0x0000000114e4fc54 UIKitCore`UIApplicationMain + 124 frame #10: 0x0000000114311ab8 UIKitCore`UIKit.UIApplicationMain(Swift.Int32, Swift.Optional>>, Swift.Optional, Swift.Optional) -> Swift.Int32 + 100 frame #11: 0x0000000102abb274 Terhills`static UIApplicationDelegate.main() at :0 frame #12: 0x0000000102abb1f0 Terhills`static AppDelegate.$main(self=Terhills.AppDelegate) at :0 frame #13: 0x0000000102abb2f0 Terhills`main at AppDelegate.swift:9:13 frame #14: 0x0000000103685558 dyld_sim`start_sim + 20 frame #15: 0x000000010302e058 dyld`start + 2224 thread #2 frame #0: 0x0000000106bea74c libsystem_kernel.dylib`__workq_kernreturn + 8 thread #3 frame #0: 0x000000010549e6dc libsystem_pthread.dylib`start_wqthread thread #4 frame #0: 0x0000000106bea74c libsystem_kernel.dylib`__workq_kernreturn + 8 thread #5, name = 'com.apple.uikit.eventfetch-thread' frame #0: 0x0000000106be8c10 libsystem_kernel.dylib`mach_msg2_trap + 8 frame #1: 0x0000000106bf9da4 libsystem_kernel.dylib`mach_msg2_internal + 76 frame #2: 0x0000000106bf0e34 libsystem_kernel.dylib`mach_msg_overwrite + 532 frame #3: 0x0000000106be8f88 libsystem_kernel.dylib`mach_msg + 20 frame #4: 0x00000001803c5ed8 CoreFoundation`__CFRunLoopServiceMachPort + 156 frame #5: 0x00000001803c05b8 CoreFoundation`__CFRunLoopRun + 1148 frame #6: 0x00000001803bfd28 CoreFoundation`CFRunLoopRunSpecific + 572 frame #7: 0x0000000180dafa98 Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 208 frame #8: 0x0000000180dafcbc Foundation`-[NSRunLoop(NSRunLoop) runUntilDate:] + 60 frame #9: 0x0000000114eee304 UIKitCore`-[UIEventFetcher threadMain] + 404 frame #10: 0x0000000180dd627c Foundation`__NSThread__start__ + 720 frame #11: 0x00000001054a34c0 libsystem_pthread.dylib`_pthread_start + 104 * thread #6, queue = 'com.apple.NSURLSession-delegate', stop reason = EXC_BAD_ACCESS (code=2, address=0x16d618000) frame #0: 0x00000001051b3840 libsystem_platform.dylib`_platform_memmove + 112 frame #1: 0x00000001800c2ce4 libsystem_blocks.dylib`_Block_copy + 92 * frame #2: 0x00000001047443d4 Atlantis`closure #1 in static AtlantisHelper.swizzleWebSocketReceiveMessage(message=0x00006000000213d0, error=nil, responseHandler=0x0000000104761230 Atlantis`partial apply forwarder for closure #1 (Swift.Optional, Swift.Optional, Swift.Optional) -> () in closure #1 (Swift.AnyObject, Swift.AnyObject) -> () in Atlantis.NetworkInjector._swizzleURLSessionWebSocketReceiveMessageSelector(Swift.AnyObject.Type) -> () at , originalHandler=0x000000016d6127f8) at AtlantisHelper.swift:75:13 frame #3: 0x00000001047449cc Atlantis`thunk for @escaping @callee_guaranteed (@guaranteed NSObject?, @guaranteed NSError?) -> () at :0 frame #4: 0x00000001074780f0 libdispatch.dylib`_dispatch_call_block_and_release + 24 frame #5: 0x000000010747993c libdispatch.dylib`_dispatch_client_callout + 16 frame #6: 0x0000000107481bd8 libdispatch.dylib`_dispatch_lane_serial_drain + 916 frame #7: 0x000000010748291c libdispatch.dylib`_dispatch_lane_invoke + 420 frame #8: 0x000000010748f2f8 libdispatch.dylib`_dispatch_root_queue_drain_deferred_wlh + 324 frame #9: 0x000000010748e754 libdispatch.dylib`_dispatch_workloop_worker_thread + 488 frame #10: 0x000000010549f924 libsystem_pthread.dylib`_pthread_wqthread + 284 thread #7 frame #0: 0x0000000106bea74c libsystem_kernel.dylib`__workq_kernreturn + 8 thread #8 frame #0: 0x0000000106bea74c libsystem_kernel.dylib`__workq_kernreturn + 8 thread #9 frame #0: 0x000000010549e6dc libsystem_pthread.dylib`start_wqthread thread #10, name = 'com.apple.CFSocket.private' frame #0: 0x0000000106bf31a8 libsystem_kernel.dylib`__select + 8 frame #1: 0x00000001803d48a0 CoreFoundation`__CFSocketManager + 612 frame #2: 0x00000001054a34c0 libsystem_pthread.dylib`_pthread_start + 104 thread #11, name = 'com.apple.CFStream.LegacyThread' frame #0: 0x0000000106be8c10 libsystem_kernel.dylib`mach_msg2_trap + 8 frame #1: 0x0000000106bf9da4 libsystem_kernel.dylib`mach_msg2_internal + 76 frame #2: 0x0000000106bf0e34 libsystem_kernel.dylib`mach_msg_overwrite + 532 frame #3: 0x0000000106be8f88 libsystem_kernel.dylib`mach_msg + 20 frame #4: 0x00000001803c5ed8 CoreFoundation`__CFRunLoopServiceMachPort + 156 frame #5: 0x00000001803c05b8 CoreFoundation`__CFRunLoopRun + 1148 frame #6: 0x00000001803bfd28 CoreFoundation`CFRunLoopRunSpecific + 572 frame #7: 0x00000001803e35b4 CoreFoundation`_legacyStreamRunLoop_workThread + 260 frame #8: 0x00000001054a34c0 libsystem_pthread.dylib`_pthread_start + 104 thread #12, name = 'com.apple.NSURLConnectionLoader' frame #0: 0x0000000106be8c10 libsystem_kernel.dylib`mach_msg2_trap + 8 frame #1: 0x0000000106bf9da4 libsystem_kernel.dylib`mach_msg2_internal + 76 frame #2: 0x0000000106bf0e34 libsystem_kernel.dylib`mach_msg_overwrite + 532 frame #3: 0x0000000106be8f88 libsystem_kernel.dylib`mach_msg + 20 frame #4: 0x00000001803c5ed8 CoreFoundation`__CFRunLoopServiceMachPort + 156 frame #5: 0x00000001803c05b8 CoreFoundation`__CFRunLoopRun + 1148 frame #6: 0x00000001803bfd28 CoreFoundation`CFRunLoopRunSpecific + 572 frame #7: 0x00000001844256c8 CFNetwork`___lldb_unnamed_symbol13732 + 336 frame #8: 0x0000000180dd627c Foundation`__NSThread__start__ + 720 frame #9: 0x00000001054a34c0 libsystem_pthread.dylib`_pthread_start + 104 thread #13 frame #0: 0x000000010549e6dc libsystem_pthread.dylib`start_wqthread thread #14 frame #0: 0x0000000106bea74c libsystem_kernel.dylib`__workq_kernreturn + 8 thread #15 frame #0: 0x000000010549e6dc libsystem_pthread.dylib`start_wqthread ```
NghiaTranUIT commented 11 months ago

Thanks @djbe . I'm working on the fix now.

djbe commented 11 months ago

Hmmm, definitely better than what I'm doing currently (disable Intercom in debug builds).

Any idea on the root cause? Presumably it's something that Intercom and Atlantis are both doing (with web sockets), but what 🤷

NghiaTranUIT commented 11 months ago

Sorry for the delay.

@djbe @yuravake @chadparker If you don't mind, let's update Atlantis to v1.23.0 and use this code:

Atlantis.start(hostName: "<Your host name>", shouldCaptureWebSocketTraffic: false)

It will skip the Method Swillzing on the WS/WSS connection, which prevents the unexpected crash on the Intercom package 👍

Any idea on the root cause? Presumably it's something that Intercom and Atlantis are both doing (with web sockets), but what 🤷

I'm still investigating it, but not found a solution yet. This fix can help you workaround it 👍

djbe commented 11 months ago

Can confirm that with the flag set to false, the crash no longer occurs 🎉

zocario commented 10 months ago

Hello @NghiaTranUIT and thanks for the fix 👍 For your information we have the same issue with the iOS SDK of Gleap (https://docs.gleap.io/ios/) and using the flag fixes it, maybe it could help you to locate the root cause.

chaseklingelzen commented 8 months ago

For what it's worth, we are on Intercom 16.4.0 and that was the reason Atlantis wouldn't work for us. Once we removed Intercom, Atlantis worked great.

NghiaTranUIT commented 8 months ago

@chadparker if you want to keep the Intercom, you can use v1.23.0, and opt-out the WebSocket interception 👍

chadparker commented 8 months ago

@chadparker Thank you! I have opted out of websockets for Atlantis and it works. Thanks again!

markanderson-underdog commented 7 months ago

Hey! I'm a new Atlantis user and I'm encountering this same problem, and just found this issue. I can also confirm that adding the shouldCaptureWebSocketTraffic to false fixes the app crash! However, as the name implies, I now cannot see messages from Websocket traffic in Proxyman, which is what I want to use Atlantis for. Is there any other solution planned, or workaround that others have found?

NghiaTranUIT commented 7 months ago

@markanderson-underdog unfortunately, there is no workaround atm because I can't reproduce the crash on my side with Atlantis + Intercome.

I suggest disabling the Intercome if possible to see the WS/WSS traffic.

May I ask:

markanderson-underdog commented 7 months ago

@NghiaTranUIT awesome! By removing the line of code where we init() the Intercom SDK by calling Intercom.setApiKey(), the app crash no longer occurs and I can view Websocket traffic using Atlantis 🎉

The Intercom version is 1.6.5 (the latest), and we're using SPM for both Intercom and Atlantis.

The STR is as simple as just launching the application, and letting the SDKs initialize. Below is the full variable debugger when the crash in Atlantis. Please let me know if there's anything else I can provide!

Screenshot 2024-02-23 at 9 00 04 AM