Description
Modern Android tooling defaults to storing native libraries uncompressed and page-aligned within APKs (as opposed to the legacy behaviour where native libraries would be extracted upon app installation).
In turn, the dynamic linker supports loading these shared objects directly from an APK, which are identified by paths containing a !/
delimiter between the name of the APK on disk and the name of the shared object within the APK (ex: /data/app/com.example/base.apk!/lib/x86_64/mylib.so
).
Unfortunately, this behaviour breaks symbolication by backtrace-rs
.
Here's the result of executing the raw
example from an APK via the linker (supported since Android 10):
$ linker64 /data/local/tmp/android-test.apk!/embedded.so
frame #0 - 0x0000007d27046d44e9 - <no info>
frame #1 - 0x0000007d27046d4574 - <no info>
frame #2 - 0x0000007d27046d5420 - <no info>
frame #3 - 0x0000007d27046d53f6 - <no info>
frame #4 - 0x0000007d27046d53e6 - <no info>
frame #5 - 0x0000007d27046d53d6 - <no info>
frame #6 - 0x0000007d27046d53c6 - <no info>
frame #7 - 0x0000007d27046d644b - <no info>
frame #8 - 0x0000007d27046d414e - <no info>
frame #9 - 0x0000007d27046d53a1 - <no info>
frame #10 - 0x0000007d27047b3c19 - <no info>
frame #11 - 0x0000007d27046d537a - <no info>
frame #12 - 0x0000007d27046d544e - <no info>
frame #13 - 0x0000007d27012af9f0 - __libc_init
Executing the same binary outside an APK works as expected:
Show output
$ linker64 /data/local/tmp/embedded.so
frame #0 - 0x00000073ad9eea74e9 - backtrace::backtrace::libunwind::trace::h7981a4ba8bed542f
@ /build/src/backtrace/libunwind.rs:116
- backtrace::backtrace::trace_unsynchronized::h886ae3bd5307ab24
@ /build/src/backtrace/mod.rs:66
frame #1 - 0x00000073ad9eea7574 - backtrace::backtrace::trace::h3babacea16dfe94c
@ /build/src/backtrace/mod.rs:53
frame #2 - 0x00000073ad9eea8420 - raw::print::h888cb4e33408280e
@ /build/examples/raw.rs:22
frame #3 - 0x00000073ad9eea83f6 - raw::baz::h19a4b78d82386849
@ /build/examples/raw.rs:12
frame #4 - 0x00000073ad9eea83e6 - raw::bar::h8bda0e72cdb6bbd6
@ /build/examples/raw.rs:9
frame #5 - 0x00000073ad9eea83d6 - raw::foo::hdce5a0b20598f292
@ /build/examples/raw.rs:6
frame #6 - 0x00000073ad9eea83c6 - raw::main::h643b0d8609941fdb
@ /build/examples/raw.rs:2
frame #7 - 0x00000073ad9eea944b - core::ops::function::FnOnce::call_once::h46e77111b2243885
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:250
frame #8 - 0x00000073ad9eea714e - std::sys_common::backtrace::__rust_begin_short_backtrace::he3c9da883cb91455
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/sys_common/backtrace.rs:155
frame #9 - 0x00000073ad9eea83a1 - std::rt::lang_start::{{closure}}::hc05a7cf412050e03
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/rt.rs:159
frame #10 - 0x00000073ad9ef86c19 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h9e1344d9adadd47f
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/core/src/ops/function.rs:284
- std::panicking::try::do_call::h137d12f6c11841ab
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:559
- std::panicking::try::h815a26d384ec2b8d
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:523
- std::panic::catch_unwind::h531706c261612119
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panic.rs:149
- std::rt::lang_start_internal::{{closure}}::h625769a25b348b59
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/rt.rs:141
- std::panicking::try::do_call::h90a2ac93f8149da4
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:559
- std::panicking::try::h0ed7569647110e62
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panicking.rs:523
- std::panic::catch_unwind::h0aa9eb220b5e286e
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/panic.rs:149
- std::rt::lang_start_internal::hfb928f792e270378
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/rt.rs:141
frame #11 - 0x00000073ad9eea837a - std::rt::lang_start::h652e3781e0e00d35
@ /rustc/129f3b9964af4d4a709d1383930ade12dfe7c081/library/std/src/rt.rs:158
frame #12 - 0x00000073ad9eea844e - main
frame #13 - 0x00000073ad9daa89f0 - __libc_init
backtrace-rs
fails here because it attempts to open the filepath returned by dl_iterate_phdr
, which (in this case) doesn't actually exist in the filesystem.