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

Fix Darwin symbolicator cache invalidator logic #768

Merged
merged 3 commits into from
Jan 10, 2024

Conversation

mrmacete
Copy link
Contributor

@mrmacete mrmacete commented Jan 9, 2024

There are 2 problems with the existing logic:

  1. Since Xcode 15.1, when Xcode launches an app it places a software breakpoint (brk / int3) instruction at the beginning of the notification_address returned by all_image_infos. That's a function which the cache invalidator hooks with Interceptor in order to trigger when any libraries are loaded or unloaded at runtime. The problem with this approach is that in this way Interceptor relocates the breakpoint instruction, so when it gets executed Xcode can't match it with the address it expected, resulting into an uncaught exception crashing the app.
  2. In cases where Interceptor can't work on system code (like the Gadget with required code-signing) the symbolicator cache is never invalidated

To overcome these problems what this change proposes is:

  • use _dyld_register_func_for_add_image / _dyld_register_func_for_remove_image when TeardownRequirement is MINIMAL (because there's no good way to unregister those handlers, so it's safe only if frida-gum knows it will never be unloaded)
  • otherwise still place an instruction-level hook using Interceptor, but on the instruction following the breakpoint if present

In order to do so, though, other 2 changes are present in this MR:

  • one brings back disassemble_instruction_at () in arm64-reader, so we can use it to check the breakpoint instruction presence
  • move the TeardownRequirement setting from the Gadget library to Gum's Process (following the same semantics as the codesign setting), so Gum can make better decisions taking into account its own promised lifetime like in this case

frida/frida-core#498 depends on this

It defaults to FULL, currently the Gadget can tweak it via config.
- Try to use _dyld_register_func* APIs instead of Interceptor if the
  TeardownRequirement is MINIMAL.
- Otherwise intercept infos.notification_address's second instruction
  in case the first one is a breakpoint, to avoid relocating any
  breakpoint set by Xcode 15.1+ and causing crashes.
@oleavr oleavr force-pushed the fix/darwin-symbolutil-cache-invalidator branch from 3bc1607 to 350ea00 Compare January 10, 2024 21:45
@oleavr oleavr merged commit 22805da into main Jan 10, 2024
4 of 17 checks passed
@oleavr oleavr deleted the fix/darwin-symbolutil-cache-invalidator branch January 10, 2024 21:45
@oleavr
Copy link
Member

oleavr commented Jan 10, 2024

w00t! 🤘 Thanks! 🙌

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

Successfully merging this pull request may close these issues.

2 participants