summaryrefslogtreecommitdiffstats
path: root/elfdump.py
blob: 88fae22ecba7e8460bdc3f54ade0494cf54213dd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#! /usr/bin/env python3

import sys
from oe.parsers.elf import Elf

def find_program_segment(elf, ph_type):
    for h in elf.header.program_headers:
        if h.type == ph_type:
            return h
    return None

def find_section_header(elf, sh_type):
    for h in elf.header.section_headers:
        if h.type == sh_type:
            return h
    return None

def stripped(elf):
    for h in elf.header.section_headers:
        if h.type == Elf.ShType.progbits and h.name == ".debug_info":
            return False
    return True

def is_dynamic(elf):
    return find_program_segment(elf, Elf.PhType.interp) is not None

def dynamic_by_tag(tag):
    dynamic = find_section_header(elf, Elf.ShType.dynamic)
    if not dynamic:
        return None
    
    for entry in dynamic.body.entries:
        if entry.tag_enum == tag:
            yield entry.value_str

def dynamic_by_tag_first(tag):
    values = dynamic_by_tag(tag)
    try:
        return next(values)
    except StopIteration:
        return None

def linkage(elf):
    dynamic = find_section_header(elf, Elf.ShType.dynsym)
    if not dynamic:
        return

    strings = None
    for h in elf.header.section_headers:
        if h.type == Elf.ShType.strtab and h.name == ".dynstr":
            strings = h
    if not strings:
        return

    for entry in dynamic.dynsym.entries:
        elf._io.seek(strings.offset + entry.name_offset)
        name = elf._io.read_bytes_term(0, False, True, True).decode(u"ASCII")
        print(name)


elf = Elf.from_file(sys.argv[1])
print("ELF binary, {} {}, for {}".format({Elf.Bits.b32: "32-bit", Elf.Bits.b64: "64-bit"}[elf.bits],
                                         {Elf.Endian.le: "little-endian", Elf.Endian.be: "big-endian"}[elf.endian],
                                         elf.header.machine.name))
print("Stripped" if stripped(elf) else "Not stripped")
print("Dynamically linked" if is_dynamic(elf) else "Statically linked")
print(f"SONAME {dynamic_by_tag_first(Elf.DynamicArrayTags.soname)}")
print(f"RPATH {dynamic_by_tag_first(Elf.DynamicArrayTags.rpath)}")
print(f"RUNPATH {dynamic_by_tag_first(Elf.DynamicArrayTags.runpath)}")
print(f"NEEDED {', '.join(dynamic_by_tag(Elf.DynamicArrayTags.needed))}")