ghidra icon indicating copy to clipboard operation
ghidra copied to clipboard

MIPS64: relocation issue

Open mumbel opened this issue 3 years ago • 11 comments
trafficstars

Describe the bug MIPS64 relocation handler discards the old symbol value resulting in symbols having the EA as their value. This binary is built to load at 0x0, so basically all of my .rel.dyn relocations are NULL pointers.

For example readelf shows:

000000667788  000000001203 R_MIPS_REL32     
                    Type2: R_MIPS_64        
                    Type3: R_MIPS_NONE   

with file data of: 000000667788: 00 00 00 00 XX YY ZZ WW and ghidra loads: 000000667788: 00 00 00 00 00 00 00 00

R_MIPS_REL32 handling has saveValue true and symbolIndex 0x0, resulting in symbolValue 0x0 Fall through in R_MIPS_32 extractAddend() false

R_MIPS_64 handling has saveValue false, addend 0x0, and symbolValue 0x0 resulting in overwriting the previous value with 0x0

Environment (please complete the following information):

  • OS: 20.04
  • Java Version: 17.0.4
  • Ghidra Version: 10.2-DEV b88cf85d5cef4e766e6093223b6320ee5ae7a113
  • Ghidra Origin: eclipse

mumbel avatar Oct 02 '22 00:10 mumbel

Could you please provide a binary which exhibits this behavior

ghidra1 avatar Oct 03 '22 13:10 ghidra1

It is possible that the section symbol is not picking up the address of the corresponding section block. Will need to investigate with a sample.

ghidra1 avatar Oct 03 '22 13:10 ghidra1

@ghidra1 I'll see if I can find a shareable binary or if I can generate an ELF.

I did work around with (still playing with the image, so not sure how good/bad this was):

for reloc in currentProgram.getRelocationTable().getRelocations():
    if reloc.getType() == 0x1203 and 0 == reloc.getValues()[0]:
        setBytes(reloc.getAddress(), reloc.getBytes())

mumbel avatar Oct 03 '22 14:10 mumbel

This binary is built to load at 0x0

Have you tried just changing the base import address to 0 instead of excepting the forced default (e.b., 0x10000) ? That is the purpose of the relocations. If the binary is not truely relocatable you need to force it to use the correct base address at import time.

ghidra1 avatar Oct 06 '22 18:10 ghidra1

Sorry that wasn't clear, I did word that weird. I did change base address to 0. So with that and reverting the relocations it looks good. Sorry I have been unable to find a shareable sample so far, plan to look more this weekend

mumbel avatar Oct 06 '22 18:10 mumbel

We do sometime struggle with pre-linked relocateable binaries - could this be one of those? The relocations are present but do not need to be applied. In those cases disabling relocation processing from import options may be the appropriate solution.

ghidra1 avatar Oct 06 '22 22:10 ghidra1

It's seems to be just the symbolIndex==0 maybe or maybe just the .rel.dyn section, I'll double check to see if I notice any patterns. There were a lot of relocations untouched by the above script

mumbel avatar Oct 06 '22 22:10 mumbel

I believe the intent of this relocation for symbolIndex==0 is:

R_MIPS_REL32
   value = imageBaseAdjustment + addend
   ***Assuming this is a REL type relocation, value should equal the original 
       bytes (32-bits) from the relocation address
   This value should be saved for use below
R_MIPS_64
   addend = value from above
   newValue = 0 + addend
   store value as 64-bit long

***Could the issue be caused by the R_MIPS_REL32 using the upper 32-bits instead of the lower 32-bits of the affected 64-bit location? It is using a 32-bit oldValue read from the relocation address. Since this code is shared for both 32-bit and 64-bit MIPS that oldValue read may be flawed for 64-bit MIPS and should have been a 64-bit read.

ghidra1 avatar Oct 06 '22 23:10 ghidra1

Could the issue be caused by the R_MIPS_REL32 using the upper 32-bits instead of the lower 32-bits of the affected 64-bit location? It is using a 32-bit oldValue read from the relocation address. Since this code is shared for both 32-bit and 64-bit MIPS that oldValue read may be flawed for 64-bit MIPS and should have been a 64-bit read.

ohhhhh, yeah... that is looking like the issue. I added a int tmpOldValue = memory.getInt(relocationAddress.add(4)); and got my original address

mumbel avatar Oct 07 '22 00:10 mumbel

The danger of a 32/64-bit consolidated handler :(

I will document and put in for repair based on this. It could easily impact other data relocations which use an extracted addend.

ghidra1 avatar Oct 07 '22 13:10 ghidra1

Thanks!

mumbel avatar Oct 07 '22 13:10 mumbel

@mumbel Can you please test this modified MIPS_ElfRelocationHandler before I commit? Thanks! MIPS_ElfRelocationHandler.java.txt

ghidra1 avatar Oct 25 '22 22:10 ghidra1

@ghidra1 Yes, looks good as far as I can tell for the R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE relocations. Thanks again (and thanks for adding/fixups for the xhash PR)

mumbel avatar Oct 25 '22 22:10 mumbel

Closed by 8c1fd57b72c84d99e8dca998ff0d1c22161bc4c4

ryanmkurtz avatar Oct 27 '22 04:10 ryanmkurtz