Fix SIGSEGV when enumerating exports from APK-embedded libraries (ONLINE mode)#1099
Fix SIGSEGV when enumerating exports from APK-embedded libraries (ONLINE mode)#1099monkeywave wants to merge 2 commits intofrida:mainfrom
Conversation
…_path contains ! (APK-embedded) on Android
…oduced the reading of .dynsym as fallback
|
Hey @oleavr, quick follow-up on this :-) I initially added a workaround for Update: I found that To reproduce the error we follow the same pattern as before but now for var m = Process.getModuleByName("libmonochrome_64.so"); // could be different on other Android versions
m.enumerateSymbols();Only reproduces when the module path is APK-embedded (contains Root cause (what seems to happen)When Changes included in this PR (all in
|
|
Hey! Thank you for the kind words ❤️ Glad to hear that 😊 I'm not able to reproduce the crash on an Android 16 AVD, but I'm fairly confident that this is because I'm running the latest frida-core from git, where our libc-shim's stdio bits recently had some fixes applied, such as this one. Does latest git of frida-core work any better for you? Cheers, |
|
Hey @oleavr , thanks for looking into this :-) I built frida-server with the latest frida-core (including your That said, I think the changes in this PR are still valuable as a complementary fix at the frida-gum layer:
Your libc-shim fix is the right solution at the stdio layer -- it benefits all code in the agent that touches shimmed file handles. This PR just makes sure frida-gum takes the optimal code path for APK-embedded ELFs in the first place. Happy to hear your thoughts :-) |
|
Thanks for testing, that's good to hear! :)
Is it safe to assume that this is always the case, and there aren't APKs out there with unstripped .so files? I haven't looked into this and lack data, so I'm hesitant to assume so.
Makes sense. Let's land this part now. |
|
Just landed the .dynsym fallback in 01eadbf. Thanks! 🙌 |
Good question — I should probably clarify the motivation behind the The idea is less about assuming that .so files inside APKs are always stripped, and more about avoiding the extraction path when the ELF is already mapped in memory. In the APK case, Frida already has access to the in-memory image via the loader (if I'm not mistaken), so extracting the .so with minizip just to read section seems somewhat redundant in most cases. Regarding unstripped .so files: my understanding is that stripped libraries are generally the default. The official NDK documentation also seems to assume this and provides guidance on how to keep symbols if needed. So while it is definitely possible to ship an APK with unstripped .so files, my impression is that this would be relatively uncommon in practice. So the main motivation here was simply to prefer the already-mapped in-memory ELF when possible and avoid the extra APK extraction step 🙂 |
Ahh, makes sense. Yeah that sounds good to me. Feel free to rebase on latest main if you want to take a stab at it |
Hey @oleavr,
first of all: thank you for your amazing work on Frida 🙏 — it’s hugely appreciated :-)
I tried the recent changes from #1094, but on my side the crash still happens (now consistently in a different code-path). I also left details here, in case it helps for cross-reference:
#1094 (comment)
Summary
On Android 14 + Android 16 AVD (Google APIs, arm64) with
com.android.chrome, this still crashes:It only reproduces when the module is APK-embedded (path contains
!), e.g.:The tombstone’s top frame points at
__fseeko64(), which suggests we’re crashing in the minizip APK extraction path, i.e., not the in-memory ELF parsing path.Proposed fix in this PR
If we’re in ONLINE mode and the path contains
!, we can skipgum_maybe_extract_from_apk()and use the already-mapped bytes atbase_addressdirectly:Rationale: for ONLINE mode, the in-memory module image is already available and sufficient for export enumeration; avoiding APK I/O also avoids the minizip
FILE*crash entirely.Result
With the patch applied,
enumerateExports()works reliably and returns a normal export list (example):Crash excerpt (before patch)
Thanks again :-)
All the best
Daniel