def __init__(self, binary, custom_offset=None, segments=None, **kwargs): """ :param custom_arch: (required) an :class:`archinfo.Arch` for the binary blob. :param custom_offset: Skip this many bytes from the beginning of the file. :param segments: List of tuples describing how to map data into memory. Tuples are of ``(file_offset, mem_addr, size)``. You can't specify both ``custom_offset`` and ``segments``. """ Backend.__init__(self, binary, **kwargs) arch, base, entry = autodetect_initial(self.binary_stream) if self.arch is None: if arch is None: raise CLEError( "AutoBlob couldn't determine your arch. Try specifying one.!" ) if isinstance(arch, str): try: arch = arch_from_id(arch) except: raise RuntimeError( "We do not know how to support architecture %s.") self.set_arch(arch) self.linked_base = kwargs.get('custom_base_addr', base) if self.linked_base is None: l.warning( "AutoBlob could not detect the base address. Assuming 0") self.linked_base = 0 self.mapped_base = self.linked_base l.error(hex(self.mapped_base)) self._entry = self._custom_entry_point if self._custom_entry_point is not None else entry if self._entry is None: l.warning("Autoblob could not detect the entry point, assuming 0") self._entry = 0 self._min_addr = 2**64 self._max_addr = 0 #TODO: This doesn't look right self.os = 'unknown' # TODO: Let this be specified somehow # TODO: Actually use this """ if custom_offset is not None: if segments is not None: l.error("You can't specify both custom_offset and segments. Taking only the segments data") else: self.binary_stream.seek(0, 2) segments = [(custom_offset, 0, self.binary_stream.tell() - custom_offset)] else: if segments is not None: pass else: self.binary_stream.seek(0, 2) segments = [(0, self.linked_base, self.binary_stream.tell())] """ self.binary_stream.seek(0, 2) segments = [(0, self.linked_base, self.binary_stream.tell())] for file_offset, mem_addr, size in segments: self._load(file_offset, mem_addr, size)
def allocate(self, size=1, alignment=8, thumb=False, tls=False) -> int: if not self._is_mapped: raise CLEError("Can't allocate with extern object before it is mapped") result = self._allocate(size=size, alignment=alignment, thumb=thumb, tls=tls) if result is None: if self._next_object is None: # we're at the end of the line. make a new extern object # this should only be hit if we're doing this outside a loading pass self._make_new_externs(size, alignment, tls) result = self._next_object.allocate(size=size, alignment=alignment, thumb=thumb, tls=tls) return result + (0 if tls else self.mapped_base)
def get_pseudo_addr(self, name) -> int: if not self._is_mapped: raise CLEError("Can't allocate with extern object before it is mapped") return self.make_extern(name).rebased_addr