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.
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP