TransWikia.com

pyelftools relocation section symbols

Reverse Engineering Asked by Wheat1ey on January 20, 2021

I have been trying to get into reverse engineering as of late and after playing with Radare2 I realized I was playing with a lot of things without really understanding what I was doing. In an effort to rectify this I decided to do something a little more hands on and do some simple reversing exercises with python. I started by following this somewhat dated post.

https://anee.me/reversing-an-elf-from-the-ground-up-4fe1ec31db4a

I was attempting to look up symbols in the relocation section and it seems that one section provides accurate addresses but another does not and i’m at a bit of a loss as to why.

My Code:

import sys
from elftools.elf.elffile import ELFFile
from elftools.elf.relocation import RelocationSection
from elftools.elf.descriptions import describe_reloc_type


def process_file(fname):
    with open(fname, 'rb') as f:
        e = ELFFile(f)
        for section in e.iter_sections():
            if not isinstance(section, RelocationSection):
                continue
            print(f'n{section.name} with {section.num_relocations()} Sections: ')
            symbol_table = e.get_section(section['sh_link'])
            for relocation in section.iter_relocations():
                symbol = symbol_table.get_symbol(relocation['r_info_sym'])
                addr = hex(relocation['r_offset'])
                type = describe_reloc_type(relocation['r_info_type'], e)
                print(f'{addr}t{type}t{symbol.name}')


if __name__ == '__main__':
    if len(sys.argv) == 2:
        process_file(sys.argv[1])

Returns:

.rela.dyn with 9 Sections: 
0x3de8  R_X86_64_RELATIVE   
0x3df0  R_X86_64_RELATIVE   
0x4048  R_X86_64_RELATIVE   
0x3fd8  R_X86_64_GLOB_DAT   _ITM_deregisterTMCloneTable
0x3fe0  R_X86_64_GLOB_DAT   __libc_start_main
0x3fe8  R_X86_64_GLOB_DAT   __gmon_start__
0x3ff0  R_X86_64_GLOB_DAT   _ITM_registerTMCloneTable
0x3ff8  R_X86_64_GLOB_DAT   __cxa_finalize
0x4050  R_X86_64_COPY       stdin

.rela.plt with 5 Sections: 
0x4018  R_X86_64_JUMP_SLOT  puts
0x4020  R_X86_64_JUMP_SLOT  printf
0x4028  R_X86_64_JUMP_SLOT  fgets
0x4030  R_X86_64_JUMP_SLOT  strcmp
0x4038  R_X86_64_JUMP_SLOT  malloc

All of the addresses under ‘.rela.plt’ have addresses that do not match the calls I know are being made to them.

For Example:

--cut--
0x11f0: mov eax, 0
0x11f5: call    0x1040 <<-- This is a call to printf
0x11fa: mov rdx, qword ptr [rip + 0x2e4f]       ** RIP + Offset: 0x4050  - calls: stdin
0x1201: mov rax, qword ptr [rbp - 8]
0x1205: mov esi, 0xa
0x120a: mov rdi, rax
0x120d: call    0x1050 <<-- This is a call to fgets
0x1212: mov rdx, qword ptr [rbp - 0x10]
--cut--

I have verified this with Radare2, and the correct addresses seem to be as follows.

 0x1030     sym.imp.puts                             
 0x1040     sym.imp.printf
 0x1050     sym.imp.fgets
 0x1060     sym.imp.strcmp
 0x1070     sym.imp.malloc

From what little I can find this may be due to dynamic linking but i’m not sure. I have been unable to find a way to get my script to output this section with what I believe are the appropriate addresses. Any information on how this process works, or how to retrieve the needed addresses with pyelftools would be greatly appreciated.

One Answer

The R_X86_64_JUMP_SLOT relocations are applied to the GOT (global offset table) slots, not to the call instructions you're seeing.

The call instructions go to the PLT (Program linkage table) stubs in the .plt section, and those, in turn, use the GOT and the .rela.plt relocations to resolve and jump to the final symbol in the external shared object. This process happens with the help of the dynamic linker (ld.so) and is a little too complicated to explain in this answer box, but you can find more information by searching for these terms.

Answered by Igor Skochinsky on January 20, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP