[docs]def__init__(self,starts=None,hook_all=False):self.results={}ifstartsisNone:starts=[imp.resolvedby.rebased_addrforimpinself.project.loader.main_object.imports.values()]foraddrinstarts:withself._resilience():size=self.analyze(addr)ifsizeisNone:l.info("Couldn't find return for function at %#x",addr)else:self.results[addr]=sizeifhook_all:foraddr,sizeinself.results.items():ifself.project.is_hooked(addr):continueifsize%self.project.arch.bytes!=0:l.error("Function at %#x has a misaligned return?",addr)continueargs=size//self.project.arch.bytescc=self.project.factory.cc()prototype=cc.guess_prototype([0]*args)cc.CALLEE_CLEANUP=Truesym=self.project.loader.find_symbol(addr)name=sym.nameifsymisnotNoneelseNonelib=self.project.loader.find_object_containing(addr)libname=lib.providesiflibisnotNoneelseNoneself.project.hook(addr,SIM_PROCEDURES["stubs"]["ReturnUnconstrained"](cc=cc,prototype=prototype,display_name=name,library_name=libname,is_stub=True),)
[docs]defanalyze(self,addr):seen=set()todo=[addr]whiletodo:addr=todo.pop(0)seen.add(addr)irsb=self.project.factory.block(addr,opt_level=0).vexifirsb.jumpkind=="Ijk_Ret":# got it!forstmtinreversed(irsb.statements):ifstmt.tag=="Ist_IMark":l.error("VERY strange return instruction at %#x...",addr)breakifstmt.tag=="Ist_WrTmp":ifstmt.data.tag=="Iex_Binop":ifstmt.data.op.startswith("Iop_Add"):returnstmt.data.args[1].con.value-self.project.arch.byteselifirsb.jumpkind=="Ijk_Call":ifaddr+irsb.sizenotinseen:todo.append(addr+irsb.size)else:todo.extend(irsb.constant_jump_targets-seen)returnNone