[dropbear] recently found herself in a pickle. Dumping some data out of an Android app at a specific point for reverse engineering purposes. While it worked great in the simulator, it was painfully slow on hardware via lldb. The solution was to write a patch and apply it to the ELF file.
Writing the AArch64 assembly to dump the buffer is relatively trivial, but adding it to the existing ELF and repackaging it into a new APK leads to strange errors. The relative offsets into .rodata
are now all wrong. For those who don’t routinely interface with the format of ELF files, we have a fantastic resource to take you into the dark depths. But the quick summary version is that sections contain various resources, and you find parts of those resources by relative offsets. The program header describes what type of resources each section contains.
[dropbear] found a NOTE section that just contained some metadata. She created a new section at the end of the file for her custom assembly and modified the header to declare the NOTE section as a LOAD section that pointed at her new section, which would get mapped into memory. All that was left to do was tweak the assembly in the actual code to jump to her new code that dumps. The BSS section was extended by a few bytes so that her program could store its state there.
It’s an impressive technique, and her program for modifying the program header is on her website under a BSD-3 license.
news.ycombinator.com just saying
please help!
Why not add another section .hack and make it load the code you need? I don’t think the ELF loader cares about the names of the sections, just what it should load vs what it should not.
You can also change the ELF entry point to your code and patch the original code at run-time, then jump to the original start.
All this violates the APK signature though. You can re-sign the APK with your own key, but if the original code is worth it’s salt it should check the signature.
There is also the LD_PRELOAD trick where you instruct the ELF loader to load and execute the init code from a random shared library in the process before it runs the executable. It may take some more work on Android and again can be mitigated against in the code.