about summary refs log tree commit diff stats
path: root/miasm2/analysis/binary.py
blob: 996ea4b9e71f4f56d0dba9797bba75e9bb6abdd4 (plain) (blame)
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
71
72
73
74
75
76
77
78
79
80
import logging

from miasm2.core.bin_stream import *
from elfesteem import pe_init, elf_init
from miasm2.jitter.jitload import vm_load_pe, vm_load_elf
from miasm2.jitter.csts import PAGE_READ


log = logging.getLogger("binary")
console_handler = logging.StreamHandler()
console_handler.setFormatter(logging.Formatter("%(levelname)-5s: %(message)s"))
log.addHandler(console_handler)
log.setLevel(logging.ERROR)


class Container(object):
    """Container abstraction layer

    This class aims to offer a common interface for abstracting container
    such as PE and ELF.
    """

    def __init__(self, filename, vm = None, addr = None):
        "Instanciate a container and parse the binary"

        # Initialisation
        with open(filename) as fdesc:
            data = fdesc.read()
        log.info('load binary')
        e, bs, ep = None, None, None

        # Parse container header and instanciate common elements
        if data.startswith('MZ'):
            try:
                if vm is not None:
                    e = vm_load_pe(vm, filename)
                else:
                    e = pe_init.PE(data)
                if e.isPE() and e.NTsig.signature_value == 0x4550:
                    bs = bin_stream_pe(e.virt)
                    ep = e.rva2virt(e.Opthdr.AddressOfEntryPoint)
            except:
                log.error('Cannot read PE!')
        elif data.startswith('\x7fELF'):
            try:
                if vm is not None:
                    e = vm_load_elf(vm, filename)
                else:
                    e = elf_init.ELF(data)
                bs = bin_stream_elf(e.virt)
                ep = e.Ehdr.entry
            except:
                log.error('Cannot read ELF!')
        else:
            bs = bin_stream_str(data)
            if vm is not None:
                if addr is None:
                    raise ValueError('set load addr')
                vm.add_memory_page(addr,
                                   PAGE_READ,
                                   data)

        self._entry_point = ep
        self._bin_stream = bs
        self._executable = e

    @property
    def bin_stream(self):
        "Return the BinStream instance corresponding to container content"
        return self._bin_stream

    @property
    def executable(self):
        "Return the abstract instance standing for parsed executable"
        return self._executable

    @property
    def entry_point(self):
        "Return the detected entry_point"
        return self._entry_point