def_check(self):getpc_calls=self._find_getpc_calls()returnbool(getpc_calls),{"getpc_calls":getpc_calls,}def_analyze(self,cache=None):getpc_calls=NoneifcacheisnotNone:getpc_calls=cache.get("getpc_calls",None)ifgetpc_callsisNone:getpc_calls=self._find_getpc_calls()ifnotgetpc_calls:return# update each blockforblock_key,stmt_idx,getpc_reg,getpc_reg_valueingetpc_calls:pcreg_offset=self.project.arch.registers[getpc_reg][0]old_block=self.blocks_by_addr_and_idx[block_key]block=old_block.copy()old_stmt=block.statements[stmt_idx]block.statements[stmt_idx]=ailment.Stmt.Assignment(old_stmt.idx,ailment.Expr.Register(None,None,pcreg_offset,32,reg_name=getpc_reg),ailment.Expr.Const(None,None,getpc_reg_value,32),**old_stmt.tags,)# remove the statement that pushes return address onto the stackifstmt_idx>0andisinstance(block.statements[stmt_idx-1],ailment.Stmt.Store):block.statements=block.statements[:stmt_idx-1]+block.statements[stmt_idx:]self._update_block(old_block,block)def_find_getpc_calls(self)->List[Tuple[Any,int,str,int]]:""" Find all blocks that are calling __x86.get_pc_thunk functions. :return: A list of tuples. Each tuple is in the form of (block_key, statement ID, pc-storing register, value of the pc-storing register). """results=[]forkey,blockinself._blocks_by_addr_and_idx.items():if(block.statementsandisinstance(block.statements[-1],ailment.Stmt.Call)andisinstance(block.statements[-1].target,ailment.Expr.Const)):call_func_addr=block.statements[-1].target.valuetry:call_func=self.kb.functions.get_by_addr(call_func_addr)exceptKeyError:continueif"get_pc"incall_func.info:results.append((key,len(block.statements)-1,call_func.info["get_pc"],block.addr+block.original_size),)returnresults