Example #1
0
    def load_dyn_sym(self):
        arch = self.elf.get_machine_arch()

        if arch == "ARM" or arch == "MIPS":
            for (rel, symtab) in self.__iter_reloc():
                self.__resolve_symtab(rel, symtab, arch)
            return

        # x86/x64

        # TODO: .plt can be renamed ?
        plt = self.elf.get_section_by_name(b".plt")

        if plt is None:
            warning(".plt section not found")
            return

        # TODO: .got.plt can be renamed or may be removed ?
        got_plt = self.elf.get_section_by_name(b".got.plt")
        addr_size = 8 if arch == "x64" else 4

        if got_plt is None:
            warning(".got.plt section not found")
            return

        for (rel, symtab) in self.__iter_reloc():
            self.__x86_resolve_reloc(rel, symtab, plt, got_plt, addr_size)
Example #2
0
    def load_dyn_sym(self):
        arch = self.elf.get_machine_arch()

        if arch == "ARM" or arch == "MIPS":
            for (rel, symtab) in self.__iter_reloc():
                self.__resolve_symtab(rel, symtab, arch)
            return

        # x86/x64

        # TODO: .plt can be renamed ?
        plt = self.elf.get_section_by_name(b".plt")

        if plt is None:
            warning(".plt section not found")
            return

        # TODO: .got.plt can be renamed or may be removed ?
        got_plt = self.elf.get_section_by_name(b".got.plt")
        addr_size = 8 if arch == "x64" else 4

        if got_plt is None:
            warning(".got.plt section not found")
            return

        for (rel, symtab) in self.__iter_reloc():
            if isinstance(symtab, NullSection):
                continue
            self.__x86_resolve_reloc(rel, symtab, plt, got_plt, addr_size)
Example #3
0
    def __x86_resolve_reloc(self, rel, symtab, plt, got_plt, addr_size):
        # Save all got offsets with the corresponding symbol
        got_off = {}
        for r in rel.iter_relocations():
            sym = symtab.get_symbol(r.entry.r_info_sym)
            name = sym.name.decode()
            ad = r.entry.r_offset
            if name and ad:
                ty = self.sym_type_lookup.get(sym.entry.st_info.type, MEM_UNK)
                got_off[ad] = [name, ty]

        # .got.plt is an array of addresses to the .plt

        data = got_plt.data()

        unpack_str = "<" if self.elf.little_endian else ">"
        unpack_str += str(int(len(data) / addr_size))
        unpack_str += "Q" if addr_size == 8 else "I"

        got_values = struct.unpack(unpack_str, data)
        plt_data = plt.data()
        wrong_jump_opcode = False
        opcode_jmp = [b"\xff\x25", b"\xff\xa3"]

        # Read the .got.plt and for each address in the plt, substract 6
        # to go at the begining of the plt entry.

        off = got_plt.header.sh_addr - addr_size

        for jump_in_plt in got_values:
            off += addr_size

            if off in got_off:
                plt_entry_start = jump_in_plt - 6

                if self.classbinary.is_address(ad):
                    plt_off = plt_entry_start - plt.header.sh_addr

                    # Check "jmp *(ADDR)" opcode.
                    if plt_data[plt_off:plt_off+2] not in opcode_jmp:
                        wrong_jump_opcode = True
                        continue

                    name, ty = got_off[off]
                    if name in self.classbinary.symbols:
                        continue

                    self.classbinary.imports[plt_entry_start] = True
                    self.classbinary.reverse_symbols[plt_entry_start] = name
                    self.classbinary.symbols[name] = plt_entry_start

                    self.mem.add(plt_entry_start, 1, ty)

        if wrong_jump_opcode:
            warning("I'm expecting to see a jmp *(ADDR) on each plt entry")
            warning("opcode \\xff\\x25 was not found, please report")
Example #4
0
    def load(self, filename):
        gc.disable()

        self.__init_vars()

        dirname = os.path.dirname(filename)
        self.path = dirname + "/" if dirname != "" else ""
        self.path += "." + os.path.basename(filename) + ".db"

        if os.path.exists(self.path):
            info("open database %s" % self.path)

            fd = open(self.path, "rb")

            data = self.__check_old_json_db(fd)
            if data is None:
                data = fd.read()
                if data.startswith(b"ZLIB"):
                    data = zlib.decompress(data[4:])
                data = msgpack.unpackb(data, encoding="utf-8")
                fd.close()

            self.__load_meta(data)
            self.__load_memory(data)
            self.__load_symbols(data)
            self.__load_jmptables(data)
            self.__load_comments(data)
            self.__load_functions(data)
            self.__load_history(data)
            self.__load_xrefs(data)
            self.__load_imports(data)

            if self.version <= 1.5:
                self.__load_labels(data)

            if self.version != VERSION:
                warning(
                    "the database version is old, some information may be missing"
                )

            self.loaded = True

        gc.enable()
Example #5
0
    def load(self, filename):
        gc.disable()

        self.__init_vars()

        dirname = os.path.dirname(filename)
        self.path = dirname + "/" if dirname != "" else ""
        self.path +=  "." + os.path.basename(filename) + ".db"

        if os.path.exists(self.path):
            info("open database %s" % self.path)

            fd = open(self.path, "rb")

            data = self.__check_old_json_db(fd)
            if data is None:
                data = fd.read()
                if data.startswith(b"ZLIB"):
                    data = zlib.decompress(data[4:])
                data = msgpack.unpackb(data, encoding="utf-8")
                fd.close()

            self.__load_meta(data)
            self.__load_memory(data)
            self.__load_symbols(data)
            self.__load_jmptables(data)
            self.__load_comments(data)
            self.__load_functions(data)
            self.__load_history(data)
            self.__load_xrefs(data)
            self.__load_imports(data)

            if self.version <= 1.5:
                self.__load_labels(data)

            if self.version != VERSION:
                warning("the database version is old, some information may be missing")

            self.loaded = True

        gc.enable()
Example #6
0
    def __init__(self):
        self.__init_vars()

        if msgpack.version < (0, 4, 6):
            warning("your version of msgpack is less than 0.4.6")
Example #7
0
    def __init__(self):
        self.__init_vars()

        if msgpack.version < (0, 4, 6):
            warning("your version of msgpack is less than 0.4.6")
Example #8
0
import pefile
from capstone.x86 import (X86_OP_INVALID, X86_OP_IMM, X86_OP_MEM, X86_REG_RIP,
        X86_REG_EIP)
from ctypes import sizeof

from reverse.lib.exceptions import ExcPEFail
from reverse.lib.fileformat.pefile2 import PE2, SymbolEntry, PE_DT_FCN, PE_DT_PTR
from reverse.lib.fileformat.binary import SectionAbs
from reverse.lib.utils import warning
from reverse.lib.memory import MEM_FUNC, MEM_UNK

try:
    # This folder is not present in simonzack/pefile-py3k
    import ordlookup
except:
    warning("you should use the most recent port of pefile")
    warning("https://github.com/mlaferrera/python3-pefile")
    pass


class PE:
    def __init__(self, mem, classbinary, filename):
        import capstone as CAPSTONE

        self.classbinary = classbinary
        self.mem = mem

        self.pe = PE2(filename, fast_load=True)
        self.__data_sections = []
        self.__data_sections_content = []
        self.__exec_sections = []