Ejemplo n.º 1
0
	def runCode(self, fileName, parameters=None, stackSize=2048):
		message = LedgerWalletProxyRequest()
		f = open(fileName, 'rb')
		elffile = ELFFile(f)
		for section in elffile.iter_sections():
			if section.name == '.ledger':		
				message.startCode.signature = section.data()[0:ord(section.data()[1]) + 2]
				break
		if len(message.startCode.signature) == 0:
			raise Exception("Missing code signature")
		message.startCode.stackSize = stackSize
		message.startCode.entryPoint = elffile.header['e_entry']
		message.startCode.parameters = parameters
		for segment in elffile.iter_segments():
			if segment['p_type'] == 'PT_LOAD':
				codeRange = message.startCode.code.add()
				flags = 0
				if ((segment['p_flags'] & P_FLAGS.PF_W) == 0):
					flags = flags | 0x01
				codeRange.flags = flags
				codeRange.start = segment['p_vaddr']
				codeRange.end = segment['p_vaddr'] + segment['p_memsz']
				codeRange.dataLength = segment['p_filesz']
				codeRange.data = segment.data()

		response = self.transport.exchange(message)		
		while response.HasField('logAck'):
			print response.logAck.message
			message = LedgerWalletProxyRequest()
			message.resumeCode.CopyFrom(ResumeCode())
			response = self.transport.exchange(message)
		if response.HasField('startCodeResponseAck'):
			return response.startCodeResponseAck.response
		else:
			raise ProxyException("Unexpected response", response)
Ejemplo n.º 2
0
	def analyze(self, pkginfo, tar):
		exec_stacks = []

		for entry in tar:
			tmpname = _test_elf_and_extract(tar, entry)
			if not tmpname:
				continue

			try:
				fp = open(tmpname, 'rb')
				elffile = ELFFile(fp)

				for segment in elffile.iter_segments():
					if segment['p_type'] != 'PT_GNU_STACK': continue

					mode = segment['p_flags']
					if mode & 1: exec_stacks.append(entry.name)

				fp.close()
			finally:
				os.unlink(tmpname)

		if exec_stacks:
			self.warnings = [("elffile-with-execstack %s", i)
					for i in exec_stacks]
Ejemplo n.º 3
0
 def test_core_prpsinfo(self):
     with open(os.path.join('test',
                            'testfiles_for_unittests', 'core_linux64.elf'),
               'rb') as f:
         elf = ELFFile(f)
         for segment in elf.iter_segments():
             if not isinstance(segment, NoteSegment):
                 continue
             notes = list(segment.iter_notes())
             for note in segment.iter_notes():
                 if note['n_type'] != 'NT_PRPSINFO':
                     continue
                 desc = note['n_desc']
                 self.assertEquals(desc['pr_state'], 0)
                 self.assertEquals(desc['pr_sname'], b'R')
                 self.assertEquals(desc['pr_zomb'], 0)
                 self.assertEquals(desc['pr_nice'], 0)
                 self.assertEquals(desc['pr_flag'], 0x400600)
                 self.assertEquals(desc['pr_uid'], 1000)
                 self.assertEquals(desc['pr_gid'], 1000)
                 self.assertEquals(desc['pr_pid'], 23395)
                 self.assertEquals(desc['pr_ppid'], 23187)
                 self.assertEquals(desc['pr_pgrp'], 23395)
                 self.assertEquals(desc['pr_sid'], 23187)
                 self.assertEquals(
                     desc['pr_fname'],
                     b'coredump_self\x00\x00\x00')
                 self.assertEquals(
                     desc['pr_psargs'],
                     b'./coredump_self foo bar 42 ' + b'\x00' * (80 - 27))
Ejemplo n.º 4
0
 def test_core_prpsinfo(self):
     elf = ELFFile(self._core_file)
     for segment in elf.iter_segments():
         if not isinstance(segment, NoteSegment):
             continue
         notes = list(segment.iter_notes())
         for note in segment.iter_notes():
             if note['n_type'] != 'NT_PRPSINFO':
                 continue
             desc = note['n_desc']
             self.assertEqual(desc['pr_state'], 0)
             self.assertEqual(desc['pr_sname'], b'R')
             self.assertEqual(desc['pr_zomb'], 0)
             self.assertEqual(desc['pr_nice'], 0)
             self.assertEqual(desc['pr_flag'], 0x400600)
             self.assertEqual(desc['pr_uid'], 1000)
             self.assertEqual(desc['pr_gid'], 1000)
             self.assertEqual(desc['pr_pid'], 23395)
             self.assertEqual(desc['pr_ppid'], 23187)
             self.assertEqual(desc['pr_pgrp'], 23395)
             self.assertEqual(desc['pr_sid'], 23187)
             self.assertEqual(
                 desc['pr_fname'],
                 b'coredump_self\x00\x00\x00')
             self.assertEqual(
                 desc['pr_psargs'],
                 b'./coredump_self foo bar 42 ' + b'\x00' * (80 - 27))
Ejemplo n.º 5
0
    def load_file(self, filename=None):
        if filename is None:
            raise FormatError("Filename not specified.")

        try:
            elffile = ELFFile(open(filename, 'rb'))
        except:
            raise FormatError("Could not open ELF file \"%s\"." % filename)

        section_lma_map = dict()

        for section in elffile.iter_sections():
            if section["sh_type"] != "SHT_PROGBITS":
                continue

            if section["sh_flags"] & SH_FLAGS.SHF_ALLOC:
                for segment in elffile.iter_segments():
                    if segment.section_in_segment(section):
                        if not segment in section_lma_map:
                            section_lma_map[segment] = segment["p_paddr"]

                        segment_offset = section_lma_map[segment]

                        section_lma_map[segment] += section["sh_size"]
                        break

                new_section = FormatELF_Section(section, segment_offset)

                section_name = section.name[1 : ]
                self.sections[section_name] = new_section


        if len(self.sections) == 0:
            raise FormatError("ELF file \"%s\" contains no data." % filename)
Ejemplo n.º 6
0
def get_elf_info(filepath):
    """
    Parse and return ELFInfo.

    Adds various calculated properties to the ELF header, segments and sections.
    Such added properties are those with prefix 'x_' in the returned dicts.
    """
    local_path = pwndbg.file.get_file(filepath)
    with open(local_path, 'rb') as f:
        elffile = ELFFile(f)
        header = dict(elffile.header)
        segments = []
        for seg in elffile.iter_segments():
            s = dict(seg.header)
            s['x_perms'] = [
                mnemonic for mask, mnemonic in [(PF_R, 'read'), (PF_W, 'write'), (PF_X, 'execute')]
                if s['p_flags'] & mask != 0
            ]
            # end of memory backing
            s['x_vaddr_mem_end'] = s['p_vaddr'] + s['p_memsz']
            # end of file backing
            s['x_vaddr_file_end'] = s['p_vaddr'] + s['p_filesz']
            segments.append(s)
        sections = []
        for sec in elffile.iter_sections():
            s = dict(sec.header)
            s['x_name'] = sec.name
            s['x_addr_mem_end'] = s['x_addr_file_end'] = s['sh_addr'] + s['sh_size']
            sections.append(s)
        return ELFInfo(header, sections, segments)
Ejemplo n.º 7
0
class Elf(Binary):
    def __init__(self, filename):
        super(Elf, self).__init__(filename)
        self.elf = ELFFile(file(filename)) 
        self.arch = {'x86':'i386','x64':'amd64'}[self.elf.get_machine_arch()]
        assert self.elf.header.e_type in ['ET_DYN', 'ET_EXEC', 'ET_CORE']


        #Get interpreter elf
        self.interpreter = None
        for elf_segment in self.elf.iter_segments():
            if elf_segment.header.p_type != 'PT_INTERP':
                continue
            self.interpreter = Elf(elf_segment.data()[:-1])
            break
        if not self.interpreter is None:
            assert self.interpreter.arch == self.arch
            assert self.interpreter.elf.header.e_type in ['ET_DYN', 'ET_EXEC']


    def maps(self):
        for elf_segment in self.elf.iter_segments():
            if elf_segment.header.p_type != 'PT_LOAD' or elf_segment.header.p_memsz == 0:
                continue

            flags = elf_segment.header.p_flags
            #PF_X 0x1 Execute - PF_W 0x2 Write - PF_R 0x4 Read
            perms = ['   ', '  x', ' w ', ' wx', 'r  ', 'r x', 'rw ', 'rwx'][flags&7]
            if 'r' not in perms:
                raise Exception("Not readable map from cgc elf not supported")

            #CGCMAP--
            assert elf_segment.header.p_filesz != 0 or elf_segment.header.p_memsz != 0 
            yield((elf_segment.header.p_vaddr,
                  elf_segment.header.p_memsz,
                  perms, 
                  elf_segment.stream.name, elf_segment.header.p_offset, elf_segment.header.p_filesz))

    def getInterpreter(self):
        return self.interpreter

    def threads(self):
        yield(('Running', {'EIP': self.elf.header.e_entry}))
Ejemplo n.º 8
0
    def test_dynamic_segment(self):
        """Verify that we can process relocations on the PT_DYNAMIC segment without section headers"""

        test_dir = os.path.join('test', 'testfiles_for_unittests')
        with open(os.path.join(test_dir, 'x64_bad_sections.elf'), 'rb') as f:
            elff = ELFFile(f)

            for seg in elff.iter_segments():
                if isinstance(seg, DynamicSegment):
                    relos = seg.get_relocation_tables()
                    self.assertEqual(set(relos), {'JMPREL', 'RELA'})
Ejemplo n.º 9
0
def is_dynamic_executable(path):
    """Is `path` a dynamic executable?"""
    from elftools.elf.elffile import ELFFile
    from elftools.common.exceptions import ELFError
    # This way of answering the question is perhaps a bit OTT. But it works.
    try:
        e = ELFFile(open(path, 'rb'))
        return 'PT_DYNAMIC' in [s.header.p_type for s in e.iter_segments()]
    except ELFError as e:
        print("ELFFile({}) failed {}".format(path, e))
        return False
Ejemplo n.º 10
0
    def test_reading_symbols(self):
        """Verify we can read symbol table without SymbolTableSection"""
        with open(os.path.join("test", "testfiles_for_unittests", "aarch64_super_stripped.elf"), "rb") as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != "PT_DYNAMIC":
                    continue

                symbol_names = [x.name for x in segment.iter_symbols()]

        exp = [b"", b"__libc_start_main", b"__gmon_start__", b"abort"]
        self.assertEqual(symbol_names, exp)
Ejemplo n.º 11
0
def test_disasm_against_objdump(objdump_path, binary_path):
    # TODO: code repetition from test_disasm_standalone, encapsulate inner functionality.

    start_time = time.time()
    total_inst = 0
    match_inst = 0

    print(('Processing file:', binary_path))
    elf_file = ELFFile(open(binary_path, 'rb'))

    if elf_file.num_segments() == 0:
        print('There are no program headers in this file.')
        return

    objdump = ObjdumpWrapper(objdump_path)
    disasm = HexagonDisassembler(objdump_compatible=True)

    for segment in elf_file.iter_segments():
        if segment['p_flags'] & P_FLAGS.PF_X:

            print("Offset: {:x}".format(segment['p_offset']))
            print("VirtAddr: {:x}".format(segment['p_vaddr']))
            print("FileSiz: {:x}".format(segment['p_filesz']))

            segment_data = segment.data()
            data_pos = 0

            while data_pos + INST_SIZE <= len(segment_data):

                addr = segment['p_vaddr'] + data_pos

                inst_as_int = struct.unpack('<I', segment_data[data_pos: data_pos + 4])[0]

                disasm_output = disasm.disasm_one_inst(inst_as_int, addr).text.strip()

                objdump_output = objdump.disasm_packet_raw(
                    segment_data[data_pos: min(data_pos + 4 * 4, segment_data)],
                    addr).strip()

                if (objdump_output != disasm_output):
                    print("[{:08x}] {:s}".format(addr, objdump_output))
                    print("[{:08x}] {:s}".format(addr, disasm_output))
                    print()
                else:
                    match_inst += 1

                data_pos += 4
                total_inst += 1

    elapsed_time = time.time() - start_time

    print("Elapsed time: {0:.2f}".format(elapsed_time))
    print('Match: {0:.2f}%'.format(match_inst / total_inst * 100))
Ejemplo n.º 12
0
    def test_reading_symbols(self):
        """Verify we can read symbol table without SymbolTableSection"""
        with open(os.path.join('test', 'testfiles_for_unittests',
                               'aarch64_super_stripped.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                symbol_names = [x.name for x in segment.iter_symbols()]

        exp = [b'', b'__libc_start_main', b'__gmon_start__', b'abort']
        self.assertEqual(symbol_names, exp)
Ejemplo n.º 13
0
    def loadELF(self, filename):
        try:
            elf = ELFFile(open(filename, 'rb'))
        except:
            raise Exception("[-] This file is not an ELF file: %s" % filename)

        self.arch = elf.get_machine_arch()
        self.entry = elf.header.e_entry
        self.memory = self.load_code_segments(elf.iter_segments(), filename)
        self.symtab, self.thumbtab, self.code_addrs = self.load_section_info(elf.iter_sections())

        self.thumbtab.sort(key=lambda tup: tup[0])
        self.code_addrs = sorted(self.code_addrs, key=lambda k: k['address'])
Ejemplo n.º 14
0
def test_disasm_standalone(binary_path, timeout = None):

    profile = cProfile.Profile()
    profile.enable()

    start_time = time.time()

    print(('Processing file:', binary_path))
    elf_file = ELFFile(open(binary_path, 'rb'))

    if elf_file.num_segments() == 0:
        print('There are no program headers in this file.')
        return

    disasm = HexagonDisassembler()

    total_inst = 0

    for segment in elf_file.iter_segments():
        if segment['p_flags'] & P_FLAGS.PF_X:
            print("Offset: {:x}".format(segment['p_offset']))
            print("VirtAddr: {:x}".format(segment['p_vaddr']))
            print("FileSiz: {:x}".format(segment['p_filesz']))

            segment_data = segment.data()
            data_pos = 0

            while data_pos + INST_SIZE <= len(segment_data):

                addr = segment['p_vaddr'] + data_pos

                inst_as_int = struct.unpack('<I', segment_data[data_pos: data_pos + 4])[0]

                dis = disasm.disasm_one_inst(inst_as_int, addr)
                print("[{:08x}] {:s}".format(addr, dis.text))

                data_pos += 4
                total_inst += 1

                if timeout and (time.time() - start_time) > timeout:
                    break

    profile.disable()
    prof_stats = pstats.Stats(profile)
    prof_stats.strip_dirs().sort_stats('cumulative').print_stats(20)

    print("Total instructions: " + str(total_inst))
    elapsed_time = time.time() - start_time
    print("Elapsed time: " + str(elapsed_time))
Ejemplo n.º 15
0
    def test_get_number_of_syms(self):
        """ Verify we can get get the number of symbols from a GNU hash
            section.
        """

        with open(os.path.join('test', 'testfiles_for_unittests',
                               'lib_versioned64.so.1.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                _, hash_offset = segment.get_table_offset('DT_GNU_HASH')
            hash_section = GNUHashSection(elf.stream, hash_offset, elf)
            self.assertEqual(hash_section.get_number_of_symbols(), 24)
Ejemplo n.º 16
0
    def _load_binary_elf(self, filename):
        logger.info("Loading ELF image into memory")

        f = open(filename, 'rb')

        elffile = ELFFile(f)

        for index, segment in enumerate(elffile.iter_segments()):
            logger.info("Loading segment #{} ({:#x}-{:#x})".format(index, segment.header.p_vaddr,
                                                                   segment.header.p_vaddr + segment.header.p_filesz))

            for i, b in enumerate(bytearray(segment.data())):
                self.ir_emulator.write_memory(segment.header.p_vaddr + i, 1, b)

        f.close()
Ejemplo n.º 17
0
class SharedObjectInfo():
    def __init__(self, path, baddr):
        self.path = path
        self._set_elf_file()

        self.low_addr = baddr
        self.high_addr = baddr + self._get_mem_size()

        # Check whether the ELF file is position independent code
        self.is_pic = self.elf_file.header['e_type'] == 'ET_DYN'

        # Don't set the so info's dwarf_info initially, only when
        # symbol lookup is first required
        self._dwarf_info = None

    @property
    def dwarf_info(self):
        if self._dwarf_info is None:
            self._set_dwarf_info()

        return self._dwarf_info

    def _set_elf_file(self):
        try:
            binary_file = open(self.path, 'rb')
            self.elf_file = ELFFile(binary_file)
        except IOError:
            print('Failed to open ' + self.path, file=sys.stderr)
            sys.exit(-1)

    def _set_dwarf_info(self):
        if not self.elf_file.has_dwarf_info():
            print('Binary ' + self.path + ' has no DWARF info',
                  file=sys.stderr)
            sys.exit(-1)

        self._dwarf_info = self.elf_file.get_dwarf_info()

    def _get_mem_size(self):
        mem_size = 0
        for segment in self.elf_file.iter_segments():
            if segment['p_type'] == 'PT_LOAD':
                alignment = segment['p_align']
                segment_size = segment['p_memsz']
                aligned_size = math.ceil(segment_size / alignment) * alignment
                mem_size += aligned_size

        return mem_size
Ejemplo n.º 18
0
    def test_missing_sections(self):
        """Verify we can get dynamic strings w/out section headers"""

        libs = []
        with open(os.path.join("test", "testfiles_for_unittests", "aarch64_super_stripped.elf"), "rb") as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != "PT_DYNAMIC":
                    continue

                for t in segment.iter_tags():
                    if t.entry.d_tag == "DT_NEEDED":
                        libs.append(t.needed.decode("utf-8"))

        exp = ["libc.so.6"]
        self.assertEqual(libs, exp)
Ejemplo n.º 19
0
    def _load_binary_elf(self, filename):
        logger.info("Loading ELF image into memory")

        f = open(filename, 'rb')

        elffile = ELFFile(f)

        for index, segment in enumerate(elffile.iter_segments()):
            logger.info("Loading segment #{} ({:#x}-{:#x})".format(
                index, segment.header.p_vaddr,
                segment.header.p_vaddr + segment.header.p_filesz))

            for i, b in enumerate(bytearray(segment.data())):
                self.ir_emulator.write_memory(segment.header.p_vaddr + i, 1, b)

        f.close()
Ejemplo n.º 20
0
def load_elf_and_run(f):
    elffile = ELFFile(f)

    for segment in elffile.iter_segments():
        t = describe_p_type(segment['p_type'])
        print("Program Header: Size: %d, Virtual Address: 0x%x, Type: %s" %
              (segment['p_filesz'], segment['p_vaddr'], t))
        if not (segment['p_vaddr'] & 0x80000000):
            continue
        if segment['p_filesz'] == 0 or segment['p_vaddr'] == 0:
            print("Skipped")
            continue
        write_ram(segment['p_vaddr'], segment.data(), True)

    print("Entry: 0x%x" % elffile['e_entry'])
    go_ram(elffile['e_entry'])
Ejemplo n.º 21
0
class CGCElf(Binary):
    @staticmethod
    def _cgc2elf(filename):
        # hack begin so we can use upstream Elftool
        with open(filename, 'rb') as fd:
            stream = io.BytesIO(fd.read())
            stream.write(b'\x7fELF')
            stream.name = fd.name
            return stream

    def __init__(self, filename):
        super().__init__(filename)
        stream = self._cgc2elf(filename)
        self.elf = ELFFile(stream)
        self.arch = {
            'x86': 'i386',
            'x64': 'amd64'
        }[self.elf.get_machine_arch()]

        assert 'i386' == self.arch
        assert self.elf.header.e_type in ['ET_EXEC']

    def maps(self):
        for elf_segment in self.elf.iter_segments():
            if elf_segment.header.p_type not in [
                    'PT_LOAD', 'PT_NULL', 'PT_PHDR', 'PT_CGCPOV2'
            ]:
                raise Exception("Not Supported Section")

            if elf_segment.header.p_type != 'PT_LOAD' or elf_segment.header.p_memsz == 0:
                continue

            flags = elf_segment.header.p_flags
            # PF_X 0x1 Execute - PF_W 0x2 Write - PF_R 0x4 Read
            perms = ['   ', '  x', ' w ', ' wx', 'r  ', 'r x', 'rw ',
                     'rwx'][flags & 7]
            if 'r' not in perms:
                raise Exception("Not readable map from cgc elf not supported")

            # CGCMAP--
            assert elf_segment.header.p_filesz != 0 or elf_segment.header.p_memsz != 0
            yield ((elf_segment.header.p_vaddr, elf_segment.header.p_memsz,
                    perms, elf_segment.stream.name,
                    elf_segment.header.p_offset, elf_segment.header.p_filesz))

    def threads(self):
        yield (('Running', {'EIP': self.elf.header.e_entry}))
Ejemplo n.º 22
0
    def test_missing_sections(self):
        """Verify we can get dynamic strings w/out section headers"""

        libs = []
        with open(os.path.join('test', 'testfiles_for_unittests',
                               'aarch64_super_stripped.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                for t in segment.iter_tags():
                    if t.entry.d_tag == 'DT_NEEDED':
                        libs.append(t.needed.decode('utf-8'))

        exp = ['libc.so.6']
        self.assertEqual(libs, exp)
Ejemplo n.º 23
0
    def _program_elf(self, file_obj: IO[bytes], **kwargs: Any) -> None:
        assert self._loader

        elf = ELFFile(file_obj)
        for segment in elf.iter_segments():
            addr = segment['p_paddr']
            if segment.header.p_type == 'PT_LOAD' and segment.header.p_filesz != 0:
                data = bytearray(segment.data())
                LOG.debug("Writing segment LMA:0x%08x, VMA:0x%08x, size %d", addr, 
                          segment['p_vaddr'], segment.header.p_filesz)
                try:
                    self._loader.add_data(addr, data)
                except ValueError as e:
                    LOG.warning("Failed to add data chunk: %s", e)
            else:
                LOG.debug("Skipping segment LMA:0x%08x, VMA:0x%08x, size %d", addr,
                          segment['p_vaddr'], segment.header.p_filesz)
Ejemplo n.º 24
0
    def __init__(self, elf=None):
        self.segments = []

        if elf != None:

            callback, path = elf.split(':')
            self.callback = int(callback)

            with open(path, 'rb') as file:
                elffile = ELFFile(file)

                self.entry = elffile['e_entry']

                for segment in elffile.iter_segments():
                    if segment['p_type'] == 'PT_LOAD':
                        self.segments.append(
                            BinarySegment(segment['p_paddr'], segment.data()))
Ejemplo n.º 25
0
 def GetElfSegments(self):
     if self.isOpen() == False:
         return b""
     ret = []
     elffile = ELFFile(self.__file_handler)
     for segment in elffile.iter_segments():
         if segment['p_type'] == 'PT_LOAD':
             addr = segment['p_paddr']
             if addr == 0 and elffile["e_entry"] != 0:
                 addr = elffile["e_entry"]
                 ret.append(
                     ElfSegments(addr,
                                 segment.data()[addr:len(segment.data())]))
             else:
                 ret.append(ElfSegments(addr, segment.data()))
     self.__file_handler.seek(0)
     return ret
Ejemplo n.º 26
0
    def __parse_binaries(self, width):

        self.mem = {}

        for binary in self.binaries:

            with open(binary, 'rb') as file:
                elffile = ELFFile(file)

                for segment in elffile.iter_segments():

                    if segment['p_type'] == 'PT_LOAD':

                        data = segment.data()
                        addr = segment['p_paddr']
                        size = len(data)

                        load = True
                        if len(self.areas) != 0:
                            load = False
                            for area in self.areas:
                                if addr >= area[0] and addr + size <= area[1]:
                                    load = True
                                    break

                        if load:

                            self.dump(
                                '  Handling section (base: 0x%x, size: 0x%x)' %
                                (addr, size))

                            self.__add_mem(addr, size, data, width)

                            if segment['p_filesz'] < segment['p_memsz']:
                                addr = segment['p_paddr'] + segment['p_filesz']
                                size = segment['p_memsz'] - segment['p_filesz']
                                self.dump(
                                    '  Init section to 0 (base: 0x%x, size: 0x%x)'
                                    % (addr, size))
                                self.__add_mem(addr, size, [0] * size, width)

                        else:

                            self.dump(
                                '  Bypassing section (base: 0x%x, size: 0x%x)'
                                % (addr, size))
Ejemplo n.º 27
0
def write_elf(path: str) -> None:
    with open(path, 'rb') as f:
        elffile = ELFFile(f)

        if elffile['e_machine'] != 189:
            logger.error('incompatible elf file, not for microblaze')

        for segment in elffile.iter_segments():
            offset = segment['p_vaddr']
            data = segment.data()
            logger.debug('writing 0x%X bytes at 0x%X', len(data), offset)
            # hack to write to the correct memory space
            if offset < mem_i.mmio.length:
                mem_i.write(offset, data)
            else:
                offset -= mem_i.mmio.length
                mem_d.write(offset, data)
Ejemplo n.º 28
0
 def __init__(self, blockSize = 0, elf = None, encrypt = False, aesKey = None, aesIv = None):
     self.blockSize = blockSize
     self.encrypt = encrypt
     self.aesKey = aesKey
     self.aesIv = aesIv
     
     self.bin = BlockBuffer(blockSize)
     self.elf = elf
     self.segments = []
     
     if elf:
         elffile = ELFFile(elf)
         self.entry = elffile['e_entry']
         
         for segment in elffile.iter_segments():
             if segment['p_type'] == 'PT_LOAD':
                 self.segments.append(BinarySegment(segment['p_paddr'], segment.data()))
Ejemplo n.º 29
0
def readelf_interp(binary_path):
    """
    This reads the program interpreter (INTERP), usually ld-linux.so from the
    given binary. It will return None if it can't find it.
    """

    # Use pyelftools to extract the program header
    elffile = ELFFile(open(binary_path))

    # Go through the segments until we INTERP segment
    interp = None

    for segment in elffile.iter_segments():
        if isinstance(segment, InterpSegment):
            interp = segment.get_interp_name()

    return interp
Ejemplo n.º 30
0
Archivo: linux.py Proyecto: jlisee/xpkg
def readelf_interp(binary_path):
    """
    This reads the program interpreter (INTERP), usually ld-linux.so from the
    given binary. It will return None if it can't find it.
    """

    # Use pyelftools to extract the program header
    elffile = ELFFile(open(binary_path))

    # Go through the segments until we INTERP segment
    interp = None

    for segment in elffile.iter_segments():
        if isinstance(segment, InterpSegment):
            interp = segment.get_interp_name()

    return interp
    def __init__(self, elf=None):
        self.segments = []

        if elf != None:

            with open(elf, 'rb') as file:
                print("Reading ELF file")
                elffile = ELFFile(file)

                self.entry = elffile['e_entry']

                for segment in elffile.iter_segments():
                    if segment['p_type'] == 'PT_LOAD':
                        print("  Segment : %x %x" %
                              (segment['p_paddr'], len(segment.data())))
                        self.segments.append(
                            BinarySegment(segment['p_paddr'], segment.data()))
Ejemplo n.º 32
0
    def load_elf(self, binary):
        if self.verbose:
            print('Loading %s' % binary)

        with open(binary, 'rb') as file:
            elffile = ELFFile(file)

            for segment in elffile.iter_segments():

                if segment['p_type'] == 'PT_LOAD':

                    data = segment.data()
                    addr = segment['p_paddr']
                    size = len(data)

                    if self.verbose:
                        print('Loading section (base: 0x%x, size: 0x%x)' %
                              (addr, size))

                    self.write(addr, size, data)

                    if segment['p_filesz'] < segment['p_memsz']:
                        addr = segment['p_paddr'] + segment['p_filesz']
                        size = segment['p_memsz'] - segment['p_filesz']
                        print('Init section to 0 (base: 0x%x, size: 0x%x)' %
                              (addr, size))
                        self.write(addr, size, [0] * size)

            set_pc_addr_config = self.config.get('**/debug_bridge/set_pc_addr')

            if set_pc_addr_config is not None:
                set_pc_offset_config = self.config.get(
                    '**/debug_bridge/set_pc_offset')
                entry = elffile.header['e_entry']

                if set_pc_offset_config is not None:
                    entry += set_pc_offset_config.get_int()

                if self.verbose:
                    print('Setting PC (base: 0x%x, value: 0x%x)' %
                          (set_pc_addr_config.get_int(), entry))

                return self.write_32(set_pc_addr_config.get_int(), entry)

        return 0
Ejemplo n.º 33
0
def get_binary_info(prog):
    """Look for the loader requested by the program, and record existing
    mappings required by program itself."""

    interp = None
    binary_mappings = []

    with open(prog, 'rb') as f:
        e = ELFFile(f)
        for seg in e.iter_segments():
            if isinstance(seg, InterpSegment):
                interp = seg.get_interp_name()
            if seg['p_type'] == 'PT_LOAD':
                binary_mappings.append((seg['p_vaddr'], seg['p_memsz']))
    if interp is None:
        raise Exception("Could not find interp in binary")

    return interp, binary_mappings
Ejemplo n.º 34
0
    def test_get_number_of_syms(self):
        """ Verify we can get get the number of symbols from an ELF hash
            section.
        """
        with open(os.path.join('test', 'testfiles_for_unittests',
                               'aarch64_super_stripped.elf'), 'rb') as f:
            elf = ELFFile(f)
            dynamic_segment = None
            for segment in elf.iter_segments():
                if segment.header.p_type == 'PT_DYNAMIC':
                    dynamic_segment = segment
                    break

            _, hash_offset = dynamic_segment.get_table_offset('DT_HASH')

            hash_section = ELFHashTable(elf, hash_offset, dynamic_segment)
            self.assertIsNotNone(hash_section)
            self.assertEqual(hash_section.get_number_of_symbols(), 4)
Ejemplo n.º 35
0
 def _extract_elf_mmap (self, fobj):
     try:
         _mle_elf = ELFFile (fobj)
         _tmp_file = tempfile.TemporaryFile ()
         for segment in _mle_elf.iter_segments ():
             if segment ['p_type'] is 'PT_LOAD':
                 _p_offset = segment ['p_offset']
                 _p_filesz = segment ['p_filesz']
                 _p_memsz  = segment ['p_memsz']
                 _elf_end = _p_offset + _p_filesz
                 # copy segment
                 _tmp_file.write (fobj [_p_offset : _elf_end])
                 # 0 fill remaining area
                 for a in range (_p_memsz - _p_filesz):
                     _tmp_file.write ('\x00')
         return mmap.mmap (_tmp_file.fileno (), 0, access=mmap.ACCESS_WRITE)
     except IOError as e:
         raise MLEError ('error decompressing ELF file {0}: {1}'.format (e.filename, e.strerror))
Ejemplo n.º 36
0
class ELF:

    # TODO: check valid
    def __init__(self, filename):
        self.valid = False
        with open(filename, 'rb') as f:
            try:
                self.elf = ELFFile(f)
                self.base_addr = 0
                self.seg_raw_offsets = {}
                self.seg_va_offsets = {}
                for seg in self.elf.iter_segments():
                    if seg["p_type"] == "PT_LOAD":
                        if self.base_addr == 0 or seg[
                                "p_vaddr"] < self.base_addr:
                            self.base_addr = seg["p_vaddr"]

                    self.seg_raw_offsets[seg["p_offset"]] = {
                        "va": seg["p_vaddr"],
                        "raw_size": seg["p_filesz"]
                    }
                    self.seg_va_offsets[seg["p_vaddr"]] = {
                        "raw": seg["p_offset"],
                        "v_size": seg["p_memsz"]
                    }
                self.valid = True
            except ELFError as ex:
                sys.stderr.write("Error: not ELF file")

    def raw2va(self, raw):
        for raw_start, seg in self.seg_raw_offsets.items():
            if raw >= raw_start and raw < raw_start + seg["raw_size"]:
                return raw - raw_start + seg["va"]
        sys.stderr.write("Error: could not calculate virtual address for " +
                         hex(raw) + "\n")
        return -1

    def va2raw(self, va):
        for va_start, seg in self.seg_va_offsets.items():
            if va >= va_start and va < va_start + seg["v_size"]:
                return va - va_start + seg["raw"]
        sys.stderr.write("Error: could not calculate raw offset for " +
                         hex(va) + "\n")
        return -1
Ejemplo n.º 37
0
	def analyze(self, pkginfo, tar):
		missing_relro = []

		for entry in tar:
			if not entry.isfile():
				continue
			fp = tar.extractfile(entry)
			if not is_elf(fp):
				continue
			elffile = ELFFile(fp)
			if any(seg['p_type'] == 'PT_GNU_RELRO' for seg in elffile.iter_segments()):
				if self.has_bind_now(elffile):
					continue

			missing_relro.append(entry.name)

		if missing_relro:
			self.warnings = [("elffile-without-relro %s", i)
					for i in missing_relro]
Ejemplo n.º 38
0
class CGCElf(Binary):

    @staticmethod
    def _cgc2elf(filename):
        #hack begin so we can use upstream Elftool
        with open(filename, 'rb') as fd:
            stream = StringIO.StringIO(fd.read())
            stream.write('\x7fELF')
            stream.name = fd.name
            return stream

    def __init__(self, filename):
        super(CGCElf, self).__init__(filename)
        stream = self._cgc2elf(filename)
        self.elf = ELFFile(stream)
        self.arch = {'x86':'i386','x64':'amd64'}[self.elf.get_machine_arch()]

        assert 'i386' == self.arch
        assert self.elf.header.e_type in ['ET_EXEC']

    def maps(self):
        for elf_segment in self.elf.iter_segments():
            if elf_segment.header.p_type not in ['PT_LOAD', 'PT_NULL', 'PT_PHDR', 'PT_CGCPOV2']:
                raise Exception("Not Supported Section")

            if elf_segment.header.p_type != 'PT_LOAD' or elf_segment.header.p_memsz == 0:
                continue

            flags = elf_segment.header.p_flags
            #PF_X 0x1 Execute - PF_W 0x2 Write - PF_R 0x4 Read
            perms = ['   ', '  x', ' w ', ' wx', 'r  ', 'r x', 'rw ', 'rwx'][flags&7]
            if 'r' not in perms:
                raise Exception("Not readable map from cgc elf not supported")

            #CGCMAP--
            assert elf_segment.header.p_filesz != 0 or elf_segment.header.p_memsz != 0 
            yield((elf_segment.header.p_vaddr,
                  elf_segment.header.p_memsz,
                  perms, 
                  elf_segment.stream.name, elf_segment.header.p_offset, elf_segment.header.p_filesz))

    def threads(self):
        yield(('Running', {'EIP': self.elf.header.e_entry}))
Ejemplo n.º 39
0
    def test_dynamic_segment(self):
        """ Test that the degenerate case for the dynamic segment does not crash
        """
        with open(
                os.path.join('test', 'testfiles_for_unittests',
                             'debug_info.elf'), 'rb') as f:
            elf = ELFFile(f)

            seen_dynamic_segment = False
            for segment in elf.iter_segments():
                if segment.header.p_type == 'PT_DYNAMIC':
                    self.assertEqual(
                        segment.num_tags(), 0,
                        "The dynamic segment in this file should be empty")
                    seen_dynamic_segment = True
                    break

            self.assertTrue(seen_dynamic_segment,
                            "There should be a dynamic segment in this file")
Ejemplo n.º 40
0
def read_sections(config: Config, ef: ELFFile) -> SectionDF:
    """Read a section table from an ELFFile."""
    columns = ['section', 'type', 'address', 'size', 'flags', 'segment']
    index = []
    rows = []
    for i, section in enumerate(ef.iter_sections()):
        index.append(i)
        segment_number = -1
        for j, segment in enumerate(ef.iter_segments()):
            if segment.section_in_segment(section):
                segment_number = j
                break
        rows.append([
            section.name,
            elftools.elf.descriptions.describe_sh_type(section['sh_type']),
            section['sh_addr'], section['sh_size'], section['sh_flags'],
            segment_number
        ])
    return SectionDF(rows, index=index, columns=columns)
Ejemplo n.º 41
0
    def load(self):

        binaries = self.get_config().get('load-binary_eval')
        if binaries is not None:
            binaries = [eval(binaries)]
        else:
            binaries = self.get_config().get('binaries')

        elffile = None

        if binaries is not None:
            for binary in binaries:
                with open(binary, 'rb') as file:
                    elffile = ELFFile(file)
                    for segment in elffile.iter_segments():
                        if segment['p_type'] == 'PT_LOAD':
                            self.get_impl().module.loader_io_req(
                                self.get_impl().instance, segment['p_paddr'],
                                segment['p_filesz'], True, segment.data())
                            if segment['p_filesz'] < segment['p_memsz']:
                                self.get_impl().module.loader_memset(
                                    self.get_impl().instance,
                                    segment['p_paddr'] + segment['p_filesz'],
                                    segment['p_memsz'] - segment['p_filesz'],
                                    0)

            set_pc_addr = self.get_json().get_child_int('set_pc_addr')
            set_pc_offset = self.get_json().get_child_int('set_pc_offset')
            start_addr = self.get_json().get_child_int('start_addr')
            start_value = self.get_json().get_child_int('start_value')

            if set_pc_addr is not None and elffile is not None:
                entry = elffile.header['e_entry']
                if set_pc_offset is not None:
                    entry += set_pc_offset
                self.get_impl().module.loader_io_req(
                    self.get_impl().instance, set_pc_addr, 4, True,
                    (entry).to_bytes(4, byteorder='little'))

            if start_addr is not None:
                self.get_impl().module.loader_io_req(
                    self.get_impl().instance, start_addr, 4, True,
                    (start_value).to_bytes(4, byteorder='little'))
Ejemplo n.º 42
0
    def load(self, binary):

        print('Loading ELF file (path: %s)' % binary)

        self.jtag_set_dbg_mode_soc()

        with open(binary, 'rb') as file:
            elffile = ELFFile(file)

            for segment in elffile.iter_segments():
                if segment['p_type'] == 'PT_LOAD':

                    data = segment.data()
                    addr = segment['p_paddr']
                    size = len(data)

                    print('Loading section (base: 0x%x, size: 0x%x)' %
                          (addr, size))

                    self.jtag_write(addr, size, data)
Ejemplo n.º 43
0
def read_elf_bin_file_segments(target_file):
    """Will ingest a simple statically linked ELF binary and return its relevant
    segments in a tuple for use by emulator.
    """
    if not target_file:
        return False

    # At least check if file exists in some matter at all at some point.
    if not os.path.isfile(target_file) and os.access(target_file, os.R_OK):
        raise IOError("Error obtaining file")

    elf_segments = []
    with open(target_file, "rb") as bin_file:
        elf_bin = ELFFile(bin_file)
        # Will store section name, offset, and size as a 3-tuple
        for seg in elf_bin.iter_segments():
            elf_segments.append((seg.header['p_type'], seg.header['p_vaddr'],
                                 seg.header['p_memsz'], seg.data()))

    return elf_segments
Ejemplo n.º 44
0
def parse_elf(elffile):
	'''Parses an ELF executable and return the image base, list of sections,
	the symbol table
	Args:
		elfffile (str): path to an ELF file
	Returns:
		imgbase: image base
		segs: binary segments list
		funcs: binary functions list from symbol table		
	'''
	funcs = []
	segs = []
	#imgbase not needed here, function's virtual address is calculated based on segments(address, offset, size)
	imgbase = 0
	try:
		with open(elffile, 'rb') as f:
			elffile = ELFFile(f)
			sec = elffile.get_section_by_name('.symtab')
			if not sec:
				sys.stderr.write("No symbol table found bin binary\n")
			'''if isinstance(sec, SymbolTableSection):
				for i in range(1, sec.num_symbols() + 1):
					if sec.get_symbol(i)["st_info"]["type"] == "STT_FUNC":
						fcn = BinaryFunction()
						fcn.name = sec.get_symbol(i).name
						fcn.offset = sec.get_symbol(i)["st_value"]
						fcn.size = sec.get_symbol(i)["st_size"]
						funcs.append(fcn)
			'''
			f.seek(0)			
			for segment in elffile.iter_segments():
				if segment['p_type'] == 'PT_LOAD':
					seg = BinarySegment()
					seg.addr = segment['p_vaddr']
					seg.size = segment['p_filesz']
					seg.offset = segment['p_offset']
					segs.append(seg)
	except ELFError:
		sys.stderr.write('Unable to parse ELF file')
		sys.exit(1)
	return imgbase, segs, funcs
Ejemplo n.º 45
0
def parse_elf(elffile):
    '''Parses an ELF executable and return the image base, list of sections,
    the symbol table
    Args:
        elfffile (str): path to an ELF file
    Returns:
        imgbase: image base
        segs: binary segments list
        funcs: binary functions list from symbol table
    '''
    funcs = []
    segs = []
    #imgbase not needed here, function's virtual address is calculated based on segments(address, offset, size)
    imgbase = 0
    try:
        with open(elffile, 'rb') as f:
            elffile = ELFFile(f)
            sec = elffile.get_section_by_name('.symtab')
            if not sec:
                sys.stderr.write("No symbol table found bin binary\n")
            '''if isinstance(sec, SymbolTableSection):
                for i in range(1, sec.num_symbols() + 1):
                    if sec.get_symbol(i)["st_info"]["type"] == "STT_FUNC":
                        fcn = BinaryFunction()
                        fcn.name = sec.get_symbol(i).name
                        fcn.offset = sec.get_symbol(i)["st_value"]
                        fcn.size = sec.get_symbol(i)["st_size"]
                        funcs.append(fcn)
            '''
            f.seek(0)
            for segment in elffile.iter_segments():
                if segment['p_type'] == 'PT_LOAD':
                    seg = BinarySegment()
                    seg.addr = segment['p_vaddr']
                    seg.size = segment['p_filesz']
                    seg.offset = segment['p_offset']
                    segs.append(seg)
    except ELFError:
        sys.stderr.write('Unable to parse ELF file')
        sys.exit(1)
    return imgbase, segs, funcs
Ejemplo n.º 46
0
def process_file(filename):
    print('Processing file:', filename)

    functions = {}
    with open(filename, 'rb') as f:
        p_vaddr = []
        p_offset = []
        elffile = ELFFile(f)
        for seg in elffile.iter_segments():

            __printSectionInfo(seg)
            if seg.header.p_type == 'PT_LOAD':
                p_vaddr.append(seg.header.p_vaddr)
                p_offset.append(seg.header.p_offset)
                print(p_offset)
                print(p_vaddr)


        section = elffile.get_section_by_name('.symtab')
        if not section:
            print('No symbol table found. Perhaps this ELF has been stripped?')
            return
        min_address_find = []
        for symb in section.iter_symbols():
            if symb.entry.st_info.type == 'STT_FUNC':
                if symb.entry.st_shndx == 'SHN_UNDEF':
                    continue
                if symb.entry.st_size == 0:
                    continue
                st_value = symb.entry.st_value
                for i in range(len(p_vaddr) - 1, -1, -1):
                    if (symb.entry.st_value >= p_vaddr[i]):
                        print(symb.entry.st_value,p_vaddr[i],p_offset[i])
                        st_value = symb.entry.st_value - p_vaddr[i] + p_offset[i]
                # print(symb.name, st_value, symb.entry.st_size) #, symb.entry.st_shndx)
                functions[symb.name] = {'value': st_value, 'size': symb.entry.st_size}
                min_address_find.append(st_value)

        print(hex(min(min_address_find)))
    # print(functions)
    return functions
Ejemplo n.º 47
0
    def test_reading_symbols_elf_hash(self):
        """ Verify we can read symbol table without SymbolTableSection but with
            a SYSV-style symbol hash table"""
        with open(os.path.join('test', 'testfiles_for_unittests',
                               'aarch64_super_stripped.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                num_symbols = segment.num_symbols()
                symbol_names = [x.name for x in segment.iter_symbols()]
                symbol_at_index_3 = segment.get_symbol(3)
                symbols_abort = segment.get_symbol_by_name('abort')

        self.assertEqual(num_symbols, 4)
        exp = ['', '__libc_start_main', '__gmon_start__', 'abort']
        self.assertEqual(symbol_names, exp)
        self.assertEqual(symbol_at_index_3.name, 'abort')
        self.assertIsNotNone(symbols_abort)
        self.assertEqual(symbols_abort[0], symbol_at_index_3)
Ejemplo n.º 48
0
def buildLoadMap(elfFileName, memConf):
    memMapConf = {}
    with open(elfFileName, 'rb') as f:
        elfFileObj = ELFFile(f)
        for segment in elfFileObj.iter_segments():
            if ( 'PT_LOAD' == segment.header['p_type'] and
                segment.header['p_vaddr'] != segment.header['p_paddr']):
                for section in elfFileObj.iter_sections():
                    if (    not section.is_null() and
                            not ((section['sh_flags'] & SH_FLAGS.SHF_TLS) != 0 and
                                section['sh_type'] == 'SHT_NOBITS' and
                                segment['p_type'] != 'PT_TLS') and
                            segment.section_in_segment(section)):
                        loadAddr = 0
                        if ( (section['sh_flags'] & SH_FLAGS.SHF_ALLOC) != 0 and
                                section['sh_type'] != 'SHT_NOBITS') :
                            loadAddr = segment.header['p_paddr'] + section['sh_addr'] - segment.header['p_vaddr']
                        else :
                            loadAddr = segment.header['p_paddr'] + section['sh_offset'] - segment.header['p_offset']
                        memMapConf[section.name] = (addr2region(segment.header['p_paddr'], memConf), loadAddr)
    return memMapConf
Ejemplo n.º 49
0
    def test_reading_symbols_elf_hash(self):
        """ Verify we can read symbol table without SymbolTableSection but with
            a SYSV-style symbol hash table"""
        with open(
                os.path.join('test', 'testfiles_for_unittests',
                             'aarch64_super_stripped.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                num_symbols = segment.num_symbols()
                symbol_names = [x.name for x in segment.iter_symbols()]
                symbol_at_index_3 = segment.get_symbol(3)
                symbols_abort = segment.get_symbol_by_name('abort')

        self.assertEqual(num_symbols, 4)
        exp = ['', '__libc_start_main', '__gmon_start__', 'abort']
        self.assertEqual(symbol_names, exp)
        self.assertEqual(symbol_at_index_3.name, 'abort')
        self.assertIsNotNone(symbols_abort)
Ejemplo n.º 50
0
	def analyze(self, pkginfo, tar):
		exec_stacks = []

		for entry in tar:
			if not entry.isfile():
				continue
			fp = tar.extractfile(entry)
			if not is_elf(fp):
				continue
			elffile = ELFFile(fp)
			for segment in elffile.iter_segments():
				if segment['p_type'] != 'PT_GNU_STACK':
					continue

				mode = segment['p_flags']
				if mode & 1:
					exec_stacks.append(entry.name)

		if exec_stacks:
			self.warnings = [("elffile-with-execstack %s", i)
					for i in exec_stacks]
Ejemplo n.º 51
0
def create_binary(header, elf, boot=False):
    elf_data = load(elf)
    with open(elf,'rb') as f:
        elffile = ELFFile(f)
        data = []
        for segment in elffile.iter_segments():
            offset = segment['p_offset']
            v_addr = segment['p_vaddr']
            filesz = segment['p_filesz']
            memsz  = segment['p_memsz']
            if segment['p_type'] != 'PT_LOAD':
                continue
            print offset,v_addr,filesz,memsz
            data.append(elf_data[offset:offset + filesz] + '\x00'*(memsz-filesz))
        data = ''.join(data)

        entry_point = elffile.header['e_entry']
        symbols = [c for c in get_symbols(elffile)]
    if boot:
        with open('build/boot.o','rb') as f:
            elf = ELFFile(f)
            boot_symbols = [c for c in get_symbols(elf)]
            symbols = boot_symbols + symbols

    symbols.sort( lambda x,y: cmp(x[0], y[0]) )
            
    #get rid of any "bx lr"s
    data = data.replace(struct.pack('<I',0xe12fff1e),struct.pack('<I',0xe1a0f00e))
    #We'll stick the symbols on the end
    symbols = ''.join(struct.pack('>I',value) + name + '\00' for (value,name) in symbols)

    if boot:
        header = load(header)
        header = header.replace(struct.pack('<I',0xcafebabe),struct.pack('<I',entry_point))
        assert len(header) < 0x1000
        header = header + '\x00'*(0x1000 - len(header))
        entry_point = None
    else:
        header = ''
    return to_synapse_format(header+data, symbols, entry_point)
Ejemplo n.º 52
0
 def _procelf(self):
     rf = cStringIO.StringIO(self.elfcontents)
     f = ELFFile(rf)
     filemap = []
     floor = SLCell.FLASH_BASE
     for segment in f.iter_segments():
         if len(segment.data()) == 0:
             continue
         binaddr = segment["p_paddr"] - floor
         if binaddr < 0:
             raise InvalidCellFileException("File contains addresses before payload area")
         end = binaddr + len(segment.data())
         if end >= SLCell.PAYLOAD_LENGTH:
             raise InvalidCellFileException("File contains addresses after payload area: \nend = 0x%08x" % end)
         if end >= len(filemap):
             filemap += ["\xFF"]*(end-len(filemap) + 1)
         for d in segment.data():
             filemap[binaddr] = d
             binaddr += 1
     self._rawimage = "".join(filemap)
     #Here we would check for variants
     self._cellobj["variant_consts"] = []
Ejemplo n.º 53
0
def main():
	if(len(sys.argv)!=3):
		print "Usage: %s <ELF filename> <output filename>" % sys.argv[0]
		return	
	
	print "Opening ELF file: %s" % sys.argv[1] 
	elffile = ELFFile(open(sys.argv[1],'r'))
	print "Entry point: 0x%x" % elffile.header['e_entry']
		
	loadsegments = list()
	for segment in elffile.iter_segments():
		segtype = describe_p_type(segment['p_type'])
		if(segtype=="LOAD"):
			loadsegments.append(segment)
			
	imgsize = 0
	for segment in loadsegments:
		if(elffile.elfclass == 32):
			print "Load offset " + str(describe_p_flags(segment['p_flags'])) + \
			" 0x%08x at 0x%08x, align 0x%0x" % \
			(segment['p_offset'], segment['p_vaddr'], segment['p_align'])
		else:
			print "Load offset " + str(describe_p_flags(segment['p_flags'])) + \
			" 0x%016x at 0x%016x, align 0x%0x" % \
			(segment['p_offset'], segment['p_vaddr'], segment['p_align'])		
		print "\tFile size: 0x%x\tMem size: 0x%x" % (segment['p_filesz'], segment['p_memsz'])
		imgsize = max(imgsize,segment['p_vaddr']+segment['p_memsz'])
	print "Image size: 0x%x" % imgsize 
	
	buf = ctypes.create_string_buffer(imgsize)
	for segment in loadsegments:
		offset = segment['p_vaddr']
		data = segment.data()
		for i in range(len(segment.data())):
			buf[offset+i] = data[i]
	
	outfile = file(sys.argv[2],'w')
	for char in buf:
		outfile.write(char)
Ejemplo n.º 54
0
def verify_firmware(firmware):
    """Verify a firmware image.

    Validate that the header is well formed and the checksums for the ELF
    segments are correct. Throw an AssertionError on validation failure.
    """

    assert len(firmware) > ctypes.sizeof(ElfHeader), "Invalid header"
    header = ElfHeader.from_buffer_copy(firmware)
    elfdata = firmware[ctypes.sizeof(ElfHeader):]

    # verify the header
    assert header.magic == 0x05b1adba, "Invalid header"
    assert header.version == 1, "Invalid header"
    assert header.num_cksums == 1, "Invalid header"

    # verify the header checksums and offsets are consistent and fall within
    # the right segments
    elf = ELFFile(io.BytesIO(elfdata))
    load_segments = [seg for seg in elf.iter_segments() if seg.header.p_type == "PT_LOAD"]
    assert len(load_segments) == 2, "Image corrupted"

    # verify that both checksums are in the first (text) segment
    seg = load_segments[0]
    assert seg.header.p_flags == (P_FLAGS.PF_R | P_FLAGS.PF_X), "Invalid header"
    assert header.c1_offset >= seg.header.p_offset, "Invalid header"
    assert header.c1_offset < seg.header.p_offset + seg.header.p_filesz, "Invalid header"

    # verify the header checksums match the embedded checksums
    c1_embedded = elfdata[header.c1_offset:header.c1_offset+4]
    assert header.c1_cksum == struct.unpack("<I", c1_embedded)[0], "Invalid header or image corrupted"

    # recalculate and verify the checksums
    segdata = load_segments[0].data()
    c1_idx = header.c1_offset - load_segments[0].header.p_offset
    crc32 = crcmod.predefined.Crc("crc-32")
    crc32.update(segdata[:c1_idx])
    crc32.update(segdata[c1_idx + 4:])
    assert crc32.crcValue == header.c1_cksum, "Image corrupted"
Ejemplo n.º 55
0
Archivo: util.py Proyecto: dbwodlf3/SMC
def getCodeSegment(binary_file):
    """Get executable segments area from binary file.

    Parameters:
        binary_file (str): binary file including path.
    
    Returns:
        [(int, int)]
    """
    result = []
    if binary_file:
        with open(binary_file, 'rb') as f:
            elffile = ELFFile(f)

            for segment in elffile.iter_segments():
                if (segment['p_flags'] & 0b1):
                    start = segment['p_vaddr']
                    end = start + segment['p_memsz']
                    result.append((start, end))
        return result
    else:
        return result
Ejemplo n.º 56
0
def prelink_libs(libs, outdir, existing_mappings, baseaddr=0xf0ffffff):
    """For every library we calculate its size and alignment, find a space in
    our new compact addr space and create a copy of the library that is
    prelinked to the addr. Start mapping these from the *end* of the addr space
    down, but leaving a bit of space at the top for stuff like the stack."""

    for lib in libs:
        with open(lib, 'rb') as f:
            # Determine the alignment and size required for all LOAD segments
            # combined
            align, size = 0, 0
            e = ELFFile(f)
            for seg in e.iter_segments():
                if seg['p_type'] != 'PT_LOAD':
                    continue
                if seg['p_align'] > align:
                    align = seg['p_align']
                size = seg['p_vaddr'] + seg['p_memsz']

            baseaddr -= size

            # Search for a slot that is not overlapping with anything else and
            # aligned properly
            found = False
            while not found:
                if baseaddr % align:
                    baseaddr -= baseaddr % align
                overlap = get_overlap((baseaddr, size), existing_mappings)
                if overlap:
                    baseaddr = overlap[0] - size
                else:
                    found = True

            print "Found %08x - %08x for %s" % (baseaddr, baseaddr + size, lib)

            newlib = os.path.join(outdir, os.path.basename(lib))
            shutil.copy(lib, newlib)
            ex("prelink -r 0x%x \"%s\"" % (baseaddr, newlib))
Ejemplo n.º 57
0
    def test_reading_symbols_gnu_hash(self):
        """ Verify we can read symbol table without SymbolTableSection but with
            a GNU symbol hash table"""
        with open(os.path.join('test', 'testfiles_for_unittests',
                               'android_dyntags.elf'), 'rb') as f:
            elf = ELFFile(f)
            for segment in elf.iter_segments():
                if segment.header.p_type != 'PT_DYNAMIC':
                    continue

                num_symbols = segment.num_symbols()
                symbol_names = [x.name for x in segment.iter_symbols()]
                symbol_at_index_3 = segment.get_symbol(3)
                symbols_atfork = segment.get_symbol_by_name('__register_atfork')

        self.assertEqual(num_symbols, 212)
        exp = ['', '__cxa_finalize' , '__cxa_atexit', '__register_atfork',
               '__stack_chk_fail', '_ZNK7android7RefBase9decStrongEPKv',
               '_ZN7android7RefBaseD2Ev', '_ZdlPv', 'pthread_mutex_lock']
        self.assertEqual(symbol_names[:9], exp)
        self.assertEqual(symbol_at_index_3.name, '__register_atfork')
        self.assertIsNotNone(symbols_atfork)
        self.assertEqual(symbols_atfork[0], symbol_at_index_3)
Ejemplo n.º 58
0
from elftools.elf.elffile import ELFFile
from elftools.elf.segments import InterpSegment

installdir = sys.argv[1]

# generate shell wrappers for dynamically linked ELF to run them with embedded dynamic linker
for root, dirs, files in os.walk(installdir):
    for file in files:
        filepath = os.path.join(root, file)
        try:
            with open(filepath, 'rb') as filed:
                try:
                    e = ELFFile(filed)
                    if e.header.e_type == 'ET_EXEC':
                        is_dynamic_elf = False
                        for s in e.iter_segments():
                            if isinstance(s, InterpSegment):  # This ELF is a dynamically linked one
                                dynamic_linker_path = s.get_interp_name()
                                is_dynamic_elf = True
                                break
                        if is_dynamic_elf:
                            del e
                            filed.close()
                            wrapped_path = os.path.join(root, file + '_wrapped')
                            os.rename(filepath, wrapped_path)
                            target_path = wrapped_path.replace(installdir, '')
                            filed = open(filepath, 'w+')
                            filed.write("""#!/bin/sh
export ROOTFS_RO=$SNAP
export ROOTFS_RW=$SNAP_DATA
export LD_LIBRARY_PATH=$SNAP/usr/lib:$SNAP/lib:$LD_LIBRARY_PATH
Ejemplo n.º 59
0
        start, end = map(lambda x: int(x, 16), m.groups()[:2])
        mappings.append((start, end, m.group(3), mapping))


    hooks = dict()
    deps = list()
    soname = '?'
    base = int(argv[2], 16)

    with open(argv[1], 'rb') as inp:
        try:
            elf = ELFFile(inp, loadbase = base)            
        except ELFError:
            exit(1)

        for seg in elf.iter_segments():
            if not isinstance(seg, DynamicSegment):
                continue

            try:
                soname = seg['DT_SONAME'].soname
                print >>stderr, seg['DT_SONAME']
            except KeyError:
                soname = 'main'

            for tag in seg.iter_tags():
                if tag.entry.d_tag == 'DT_NEEDED':
                    print >> stderr, tag
                    deps.append(tag.needed)

            try: