[docs]classRelocation:""" A representation of a relocation in a binary file. Smart enough to relocate itself. :ivar owner: The binary this relocation was originaly found in, as a cle object :ivar symbol: The Symbol object this relocation refers to :ivar relative_addr: The address in owner this relocation would like to write to :ivar resolvedby: If the symbol this relocation refers to is an import symbol and that import has been resolved, this attribute holds the symbol from a different binary that was used to resolve the import. :ivar resolved: Whether the application of this relocation was successful """
[docs]defresolve_symbol(self,solist:"List[Any]",thumb=False,extern_object=None,**kwargs):# pylint: disable=unused-argumentifself.resolved:returnif(self.symbolisNoneorself.symbol.type==SymbolType.TYPE_NONE)andself.AUTO_HANDLE_NONE:self.resolve(None,extern_object=extern_object)returnifself.symbol.is_staticorself.symbol.is_local:# A static or local symbol should only be resolved by itself.self.resolve(self.symbol,extern_object=extern_object)returnweak_result=Noneforsoinsolist:symbol=so.get_symbol(self.symbol.name)ifsymbolisnotNoneandsymbol.is_export:ifnotsymbol.is_weak:self.resolve(symbol,extern_object=extern_object)returnelifweak_resultisNone:weak_result=symbol# TODO: Was this check obsolted by the addition of is_static?# I think right now symbol.is_import = !symbol.is_exportelifsymbolisnotNoneandnotsymbol.is_importandsoisself.owner:ifnotsymbol.is_weak:self.resolve(symbol,extern_object=extern_object)returnelifweak_resultisNone:weak_result=symbolifweak_resultisnotNone:self.resolve(weak_result,extern_object=extern_object)returnifself.symbol.is_weak:returnnew_symbol=extern_object.make_extern(self.symbol.name,sym_type=self.symbol._type,thumb=thumb)self.resolve(new_symbol,extern_object=extern_object)
[docs]defresolve(self,obj,**kwargs):# pylint: disable=unused-argumentself.resolvedby=objself.resolved=Trueifself.symbolisnotNone:ifobjisnotNone:log.debug("%s from %s resolved by %s from %s at %#x",self.symbol.name,self.owner.provides,obj.name,obj.owner.provides,obj.rebased_addr,)self.symbol.resolve(obj)else:ifnotself.AUTO_HANDLE_NONE:raiseTypeError("Programming error: resolving symbol with None but does not have CAN_HANDLE_NONE set")
@propertydefrebased_addr(self):""" The address in the global memory space this relocation would like to write to """returnAT.from_rva(self.relative_addr,self.owner).to_mva()@propertydeflinked_addr(self):returnAT.from_rva(self.relative_addr,self.owner).to_lva()@propertydefdest_addr(self):returnself.relative_addr@propertydefvalue(self):# pylint: disable=no-self-uselog.error("Value property of Relocation must be overridden by subclass!")return0
[docs]defrelocate(self):""" Applies this relocation. Will make changes to the memory object of the object it came from. This implementation is a generic version that can be overridden in subclasses. """ifnotself.resolved:returnFalseself.owner.memory.pack_word(self.dest_addr,self.value)returnTrue
# compatibility layer_complained_owner=False@propertydefowner_obj(self):ifnotRelocation._complained_owner:Relocation._complained_owner=Truelog.critical("Deprecation warning: use relocation.owner instead of relocation.owner_obj")returnself.owner