Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: gum-js-loop (21): EXC_BAD_ACCESS #426

Closed
KittyNighthawk opened this issue May 7, 2020 · 2 comments
Closed

Bug: gum-js-loop (21): EXC_BAD_ACCESS #426

KittyNighthawk opened this issue May 7, 2020 · 2 comments

Comments

@KittyNighthawk
Copy link

Hiya Ole!

It would seem I have encountered a bug in frida-gum which is preventing the creation of a tool for assessing iOS/iPadOS applications. This was encountered when I was trying to inject some JavaScript into a UIWebView and WKWebView via their methods:

  • UIWebView.stringByEvaluatingJavaScriptFromString(_:)
  • WKWebView.evaluateJavaScript(_:completionHandler)

Below is the crash report generated when Xcode was attached to the application's process.

frida-gum-js_EXC_BAD_ACCESS

And the (snipped) log generated by Frida when the crash happens:

[iPhone::com.[REDACTED].WheresMyBrowser]-> var webview = new ObjC.Object(ptr('[WEBVIEW-ADDRESS]');
[iPhone::com.[REDACTED].WheresMyBrowser]-> webview.stringByEvaluatingJavaScriptFromString_('document.body.innerHTML += "<marquee>Testing JS</marquee>";');
Process crashed: Trace/BPT trap

***
Incident Identifier: F7773B62-DEB1-400E-954D-27722F7AC3A8
CrashReporter Key:   3456850ad33e979fed377460dab4753b65856181
Hardware Model:      iPhone7,2
Process:             WheresMyBrowser [4841]
Path:                /private/var/containers/Bundle/Application/[APP-GUID]/WheresMyBrowser.app/WheresMyBrowser
Identifier:          com.[REDACTED].WheresMyBrowser
Version:             2 (1.1)
Code Type:           ARM-64 (Native)
Role:                Non UI
Parent Process:      launchd [1]
Coalition:           com.[REDACTED].WheresMyBrowser [871]


Date/Time:           2020-05-07 12:08:05.8159 +0100
Launch Time:         2020-05-07 12:06:59.5476 +0100
OS Version:          iPhone OS 12.4.2 (16G114)
Baseband Version:    7.80.04
Report Version:      104

Exception Type:  EXC_BREAKPOINT (SIGTRAP)
Exception Codes: 0x0000000000000001, 0x000000020ab676c0
Termination Signal: Trace/BPT trap: 5
Termination Reason: Namespace SIGNAL, Code 0x5
Terminating Process: exc handler [4841]
Triggered by Thread:  5

[snipped]

Full crash report is in the text file below:

FridaCrashReport.txt

To trigger this crash, I did the following:

  1. Get an object at the WebViews address (var webview = new ObjC.Object(ptr('[WEBVIEW-ADDRESS]'));)
  2. Next, try to inject some JavaScript into the loaded WebView using the two methods mentioned above, UIWebView here for ease (webview.stringByEvaluatingJavaScriptFromString_('document.body.innerHTML += "<marquee>Testing JS Injection</marquee>";');

Upon submitting step 2, the application crashes and reports what's at the top of this ticket.

The expected outcome was that a marquee would be added to the bottom of the loaded page. When testing the JavaScript via Safari Web Inspector attached to the WebView, all works as expected.

Can provide any extra information to help debug this bug for you.

As always, so many thanks for creating and maintaining Frida!

@oleavr
Copy link
Member

oleavr commented Jul 12, 2020

(Sorry for the delay here, I'm terrible at context-switching.)

Did you try ensuring that the code is run on the main thread? E.g.:

ObjC.schedule(ObjC.mainQueue, function () {
  webview.stringByEvaluatingJavaScriptFromString_('document.body.innerHTML += "<marquee>Testing JS Injection</marquee>";');
});

UIKit-based APIs typically require methods to be invoked on the main thread. The ObjC.Object can still be constructed from the JS thread, though, as that won't invoke any methods on the particular class.

@oleavr
Copy link
Member

oleavr commented Jul 12, 2020

Another gotcha: If you use Objective-C APIs from a thread that doesn't have an NSAutoreleasePool this may also result in bad things happening. So for example if you're using such APIs from Frida's JS thread, you should do:

var NSAutoreleasePool = ObjC.classes.NSAutoreleasePool;

var pool = NSAutoreleasePool.alloc().init();
try {
  /* Call Objective-C methods here. */
} finally {
  pool.release();
}

Note that ObjC.schedule() does this for you, so this is only needed if you're running on Frida's JS thread, or an application thread that doesn't have any pool. (E.g. if you're using Objective-C APIs from Interceptor callbacks.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants