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.