depoon / NetworkInterceptor

iOS URLRequest interception framework
MIT License
157 stars 35 forks source link

Build issues #16

Closed mgcrea closed 5 years ago

mgcrea commented 5 years ago

So I'm pretty much very junior to swift related development (did some Obj-C back in the days but a bit rusty too).

I haven't found a way to properly build the example project:

However it won't build anyway as it could not find the module:

~/Developer/foobar/ios-inject/NetworkInterceptor/NetworkInterceptorExample/NetworkInterceptorExample/ViewController.swift:10:8: No such module 'NetworkInterceptor'

Have a working static injection project (following your tutorial), but as well, I'm stuck properly loading the CodeInjectionSwift.swift code, not sure if because it's Swift or if there is as well an issue while loading the built framework (same drag&drop from build).

Would love any insight you could have on this,

Thanks for the great work! I'm looking to reverse-engineer an home automation app and your code looks like to be my last resort! (SSL certificate pinning).


EDIT

Tweaking the framework search path it looks like it loads it now but I'm encountering header issues:

screenshot 2018-10-04 at 16 23 43
depoon commented 5 years ago
  1. Please Open NetworkInterceptor.xcworkspace instead
  2. Build NetworkInterceptor target
  3. Run Example project

How do you wish to reverse engineer that app? I might have an easier solution

mgcrea commented 5 years ago

Thanks for the answer! Indeed opening the workspace seems to have fixed the build issues, back to work!

The app I'm trying to reverse is a free home automation app, available both on iOS and Android. They are quite famous in my country, but their system is totally closed unfortunately.

I was able to debug the initial login handshake that uses some kind of Digest access authentication but to initiate a WebSocket connection. That part is working fine and I'm properly receiving WebSocket (incoming) messages from the server (that looks like to be raw HTTP requests).

The big issue is that I don't have a clue what is the proper (outgoing) messages API to trigger stuff (tried a few variations of the received message with no luck).

I've spent a lot of time trying to debug these network frames using Charles for iOS, then a combination of mitm-proxy and WireShark combined with the use of a Remote Virtual Interface.

Big issue is that it looks like WebSocket frames do not use the proxy, were not properly SSL decrypted by Charles, and when I finally was able to force the SSL override (via the virtual interface) the app did not work anymore (I guess it is due to SSL pining).

So my only hope left was to somehow debug these WebSocket messages before they are sent / encrypted thanks to your work. If you have any other idea (or maybe some other iOS method injection to perform related to WebSocket usage), I'd be more than happy to hear them.

If you are interested, I can send you unencrypted version of both iOS/Android apps!

Thanks again for the help!


EDIT Somehow I can't seem to find the proper way to load your CodeInjectionSwift.swift code inside a Framework (for bundling in an app after), somehow it looks like bridging -Swift.h interfaces are not generated for frameworks (only apps). Do you have any idea on how to fix that or write the equivalent in pure obj-c?

screenshot 2018-10-07 at 23 21 29
depoon commented 5 years ago

Drop me an email regarding the unencrypted app pls. de_poon@hotmail.com

mgcrea commented 5 years ago

@depoon done, thanks!

depoon commented 5 years ago

On PatchLoader.m, since you are creating a framework, use this import instead

#import <PatchFramework/PatchFramework-Swift.h>

In CodeInjectionSwift you need to declare your class and func public in order to use them

mgcrea commented 5 years ago

Thanks, it did indeed fixed build issues.

Unfortunately it looks like I've hit another deadend, I can't import the required Swift dylibs as they crash (due to missing symbols), eg:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note:  EXC_CORPSE_NOTIFY
Termination Description: DYLD, Symbol not found: _$SSJN | Referenced from: /var/containers/Bundle/Application/7739779D-14CF-4DFD-AF21-4BF6B6E9617C/Tydom.app/Dylibs/libswiftSwiftOnoneSupport.dylib | Expected in: /private/var/containers/Bundle/Application/7739779D-14CF-4DFD-AF21-4BF6B6E9617C/Tydom.app/Frameworks/libswiftCore.dylib | in /var/containers/Bundle/Application/7739779D-14CF-4DFD-AF21-4BF6B6E9617C/Tydom.app/Dylibs/libswiftSwiftOnoneSupport.dylib

Probably because either XCode is too recent (and device is in 10.3) or maybe the fact that it is 32-bit.

I've found out this repo with historical runtime headers:

https://github.com/nst/iOS-Runtime-Headers/releases/tag/10.3

But there is no libswiftSwiftOnoneSupport.dylib that is required by the framework.

oli06 commented 5 years ago

Hi @mgcrea,

Not sure, if I'm on the right way understanding your issue. But I also got into trouble using the required (or not required) Swift dylibs while experimenting with CodeInjection.

First I used all the default Swift dylibs (/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift), but soon found out, that the easiest way of using only the required dylibs is to build your framework, open it in finder and copy all dylibs from the /Frameworks directory.

Especially for libswiftSwiftOnoneSupport.dylib, this was only required if I wanted to use a debug version of the framework on my iOS-device. Otherwise this dylib is not required (and shouldn't therefore not be included).

mgcrea commented 5 years ago

Indeed it looks like I was building it in debug mode. Had been able to get a 64-bit device and wanted to try again but I'm not sure if an Xcode update broke something but I get:

dyld: Library not loaded: @rpath/NetworkInterceptor.framework/NetworkInterceptor
  Referenced from: /var/containers/Bundle/Application/96A22878-6F2A-4670-99ED-268CF907F9D2/NetworkInterceptorExample.app/NetworkInterceptorExample
  Reason: image not found

When trying to run the example (clean checkout from this repo). I've opened the workspace and built the NetworkInterceptor target first. Any ideas?


EDIT: Fixed it by adding it to Embedded Binaries:

screenshot 2018-12-15 at 02 18 28

EDIT 2: Unfortunately I hit another cryptic error once sideloaded along the actual app

Termination Description: DYLD, Symbol not found: _$SBOWV | Referenced from: /var/containers/Bundle/Application/75125D53-6E8C-4D4A-A7D8-0E80936408B1/Tydom.app/Dylibs/NetworkInterceptor | Expected in: /private/var/containers/Bundle/Application/75125D53-6E8C-4D4A-A7D8-0E80936408B1/Tydom.app/Frameworks/libswiftCore.dylib | in /var/containers/Bundle/Application/75125D53-6E8C-4D4A-A7D8-0E80936408B1/Tydom.app/Dylibs/NetworkInterceptor

EDIT 3: It looks like the app I'm trying to sideload is built for iOS9 so I tried to set Deployment Target to 9.0 and build in release mode but no more luck.

I'm exactly hitting this error message: https://github.com/razorpay/react-native-razorpay/issues/125

@depoon do you think it would be possible to skip the NetworkInspector framework and do some basic pre-query body dumping directly with Objective-C?

mgcrea commented 5 years ago

Finally made it work today!! had to compile my framework with Xcode 9 (still downloadable on Apple developer) to be on the same SDK than the app.

However I'm receiving truncated body/content in the console,

default 01:07:35.829411 +0100   Tydom   Task <157440F7-FB34-41CC-A208-968EB2C32118>.<0> sent request, body N
default 01:07:35.838641 +0100   Tydom   Task <157440F7-FB34-41CC-A208-968EB2C32118>.<0> received response, status 401 content U

EDIT: nevermind, found the actual logs Request # but I don't have any interesting log there (only third-party metrics). It looks like the app relies on https://github.com/robbiehanson/CocoaAsyncSocket to perform some of its requests and https://github.com/daltoniam/Starscream for WebSockets, and I guess it's not properly caught by this interceptor. Any idea @depoon?

Anyway I guess I can close this!

depoon commented 5 years ago

Sorry for not keeping up. I will investigate how to apply the same concept for WebSockets