[docs]defadd_xref(self,xref):to_remove=set()# Overwrite existing "offset" refsifxref.type!=XRefType.Offset:existing=self.get_xrefs_by_ins_addr(xref.ins_addr)ifexisting:forexinexisting:ifex.dst==xref.dstandex.type==XRefType.Offset:# We want to remove this one and replace it with the new oneto_remove.add(ex)d0=self.xrefs_by_ins_addr[xref.ins_addr]d0.add(xref)d1=self.xrefs_by_dst[xref.dst]d1.add(xref)forexinto_remove:d0.discard(ex)d1.discard(ex)
[docs]defget_xrefs_by_dst_region(self,start,end):""" Get a set of XRef objects that point to a given address region bounded by start and end. Will only return absolute xrefs, not relative ones (like SP offsets) """deff(x):returnisinstance(x,int)andstart<=x<=endaddrs=filter(f,self.xrefs_by_dst.keys())refs=set()foraddrinaddrs:refs=refs.union(self.xrefs_by_dst[addr])returnrefs
[docs]defget_xrefs_by_ins_addr_region(self,start,end)->Set[XRef]:""" Get a set of XRef objects that originate at a given address region bounded by start and end. Useful for finding references from a basic block or function. """deff(x):returnisinstance(x,int)andstart<=x<=endaddrs=filter(f,self.xrefs_by_ins_addr.keys())refs=set()foraddrinaddrs:refs=refs.union(self.xrefs_by_ins_addr[addr])returnrefs
# TODO: Maybe add some helpers that accept Function or Block objects for the sake of clean analyses.@classmethoddef_get_cmsg(cls):returnxrefs_pb2.XRefs()
[docs]@classmethoddefparse_from_cmessage(cls,cmsg,cfg_model=None,kb=None,**kwargs):# pylint:disable=arguments-differmodel=XRefManager(kb)bits=kb._project.arch.bits# referencesforxref_pb2incmsg.xrefs:ifxref_pb2.data_ea==-1:l.warning("Unknown address of the referenced data item. Ignore the reference at %#x.",xref_pb2.ea)continuexref=XRef.parse_from_cmessage(xref_pb2,bits=bits)ifcfg_modelisnotNoneandisinstance(xref.dst,int):xref.memory_data=cfg_model.memory_data.get(xref.dst,None)model.add_xref(xref)returnmodel