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

Shared Object for ARMv7L Target Has Incorrect Offsets on x86_64 Host #314

Closed
coverclock opened this Issue Apr 2, 2019 · 5 comments

Comments

Projects
None yet
3 participants
@coverclock
Copy link

coverclock commented Apr 2, 2019

Describe the bug

I installed the 9.0.1 on my x86_64 Ubuntu desktop, created a new project from scratch, and imported a shared object (library) compiled for an ARMv7L target that contains multiple object files. I am still seeing Ghidra get confused about what symbols are where due to the incorrect 0x10000 offset.

When I compare the output of objdump for the same file and run the ARMv7L target itself, I can see that Ghidra has the disassembly for the function diminuto_cue_debounce correct, but because of the incorrect offset, it places it in the middle of an entirely different object module diminuto_controller.o and proceeds to interpret the variables as if they were in that module (e.g. "numerator" etc.) instead of diminuto_cue.o. Remarkably, the decompile for diminuto_due_debounce seems reasonable.

I similarly analyzed the same shared object but compiled for two different x86_64 targets (one of which was the host on which I ran Ghidra) and both disassemblies seem correct; I don't see the incorrect offset and the disassembly interprets the variables correctly.

To Reproduce

  1. Run Ghidra on your favorite x86_64 Linux host.
  2. Create a new project.
  3. Import the a shared object (see attachment) compiled for ARMv7L.
  4. Look for the function "diminuto_cue_debounce" (for example).
  5. Note that it's misplaced by offset 0x10000 placing it in the middle of an unrelated object module.

Expected behavior

Placement of symbols (e.g. functions) in disassembly should match output of tools run on the target like objdump; they don't for an ARMv7L target, they do for an x86_64 target.

Screenshots

Ghidra version

nm run on the target

objdump -x -d run on target

Ghidra run on host

Attachments

libdiminuto.so.54.3 for ARMv7L

Environment (please complete the following information):

HOST

  • OS: Ubuntu 18.04.1 "bionic" Linux 4.15.0
  • Java Version: OpenJDK 11.0.2
  • Ghidra Version: 9.0.1 2019-Mar-25

TARGET

  • OS: Raspbian 9.8 "stretch" Linux 4.14.98
  • GNU C Version: 6.3.0

Additional context

Maybe this is a different bug than #52 ... but it sure seems like #52 from Ghidra 9.0.

@ghidra1

This comment has been minimized.

Copy link
Collaborator

ghidra1 commented Apr 4, 2019

The import of this file looks fine. If your only concern is the 0x10000 offset when compared to objdump this is not an import error unless the file has been prelinked in which case we should use the prelinked image base. This file is a relocatable shared library which can generally be imported to any base address of your choosing (see importer options). We default to offset 0x10000 which is somewhat arbitrary. We try to avoid loading at offset 0 when possible to help avoid mistaking small constants for address offsets. The importer has an image base offset option which can be set.

It's unclear what you are using as a basis for your module memory map since this is a relocatable module. Do you get the expected result if you set the import image base to 0?

@ghidra1 ghidra1 added question and removed bug labels Apr 4, 2019

@coverclock

This comment has been minimized.

Copy link
Author

coverclock commented Apr 4, 2019

Setting the import image base to zero seems to have worked. Interesting I didn't have to do this for the .so of the same source for the x86_64 target. Having the base at 0x10000 led to very misleading (and incorrect) results. Thanks!

@ryanmkurtz ryanmkurtz closed this Apr 4, 2019

@coverclock

This comment has been minimized.

Copy link
Author

coverclock commented Apr 4, 2019

BTW, my concern wasn't that it didn't match the output of objdump; my concern was that the disassembly was incorrect, placing symbols in the wrong locations. I can deal with issues in the decompile (I'm kind of amazed that it works at all) because I can read the disassembly to resolve any ambiguities. Example: when I insert some memory barrier machine instructions into the C code, in either the x86_64 or ARMv7L build, the decompiler gets confused and drops some of the idiomatic C instruction sequences (like straightforward variable assignments); but the disassembly is correct. I can live with that. But putting symbols in the wrong locations in the disassembly is very misleading.

@ghidra1

This comment has been minimized.

Copy link
Collaborator

ghidra1 commented Apr 4, 2019

When I originally looked at your sample I had only done an import to see where the ELF loader was placing symbols. Having just run analysis I now see the issue you pointed out. You may have also noticed a bunch of DWARF related errors in your log during analysis when an image base of 0x10000 was used. Using an image base of 0 likely avoids these errors. We currently are not handling relocation of DWARF debug data which is based at 0 for your sample. This results in DWARF analysis laying down symbols at the incorrect offset since the image base adjustment had not been applied. When DWARF data exists the 0 image base should probably be used until we are able to handle DWARF debug data relocations.

@coverclock

This comment has been minimized.

Copy link
Author

coverclock commented Apr 4, 2019

10-4!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.