[docs]classX86ElfPicPltResolver(IndirectJumpResolver):""" In X86 ELF position-independent code, PLT stubs uses ebx to resolve library calls, where ebx stores the address to the beginning of the GOT. We resolve the target by forcing ebx to be the beginning of the GOT and simulate the execution in fast path mode. """
def_got_addr(self,obj):ifobjnotinself._got_addr_cache:ifnotisinstance(obj,cle.MetaELF):self._got_addr_cache[obj]=Noneelse:# ALERT: HACKS AHEADgot_plt_section=obj.sections_map.get(".got.plt",None)got_section=obj.sections_map.get(".got",None)ifgot_plt_sectionisnotNone:l.debug("Use address of .got.plt section as the GOT base for object %s.",obj)self._got_addr_cache[obj]=got_plt_section.vaddrelifgot_sectionisnotNone:l.debug("Use address of .got section as the GOT base for object %s.",obj)self._got_addr_cache[obj]=got_section.vaddrelse:l.debug("Cannot find GOT base for object %s.",obj)self._got_addr_cache[obj]=Nonereturnself._got_addr_cache[obj]
[docs]deffilter(self,cfg,addr,func_addr,block,jumpkind):ifnotisinstance(self.project.arch,archinfo.ArchX86):returnFalsesection=self.project.loader.find_section_containing(addr)ifsectionisNone:returnFalseifsection.name!=".plt":returnFalseifblock.size!=6:returnFalseifblock.instructions!=1:returnFalse# TODO: check whether ebx/edx is usedreturnTrue
[docs]defresolve(self,cfg,addr,func_addr,block,jumpkind,func_graph_complete:bool=True,**kwargs):# pylint:disable=unused-argumentobj=self.project.loader.find_object_containing(addr)ifobjisNone:returnFalse,[]got_addr=self._got_addr(obj)ifgot_addrisNone:# cannot get the base address of GOTreturnFalse,[]ifcfg._initial_stateisnotNone:state=cfg._initial_state.copy()else:state=self.project.factory.blank_state()state.regs.ebx=got_addrsuccessors=self.project.factory.default_engine.process(state,block,force_addr=addr)iflen(successors.flat_successors)!=1:returnFalse,[]target=state.solver.eval_one(successors.flat_successors[0].ip)returnTrue,[target]