def get_callee_address( global_state: GlobalState, dynamic_loader: DynLoader, symbolic_to_address: Expression, ): """Gets the address of the callee. :param global_state: state to look in :param dynamic_loader: dynamic loader to use :param symbolic_to_address: The (symbolic) callee address :return: Address of the callee """ environment = global_state.environment try: callee_address = hex(util.get_concrete_int(symbolic_to_address)) except TypeError: log.debug("Symbolic call encountered") match = re.search(r"storage_(\d+)", str(simplify(symbolic_to_address))) log.debug("CALL to: " + str(simplify(symbolic_to_address))) if match is None or dynamic_loader is None: raise ValueError() index = int(match.group(1)) log.debug("Dynamic contract address at storage index {}".format(index)) # attempt to read the contract address from instance storage try: callee_address = dynamic_loader.read_storage( environment.active_account.address, index ) # TODO: verify whether this happens or not except: log.debug("Error accessing contract storage.") raise ValueError # testrpc simply returns the address, geth response is more elaborate. if not re.match(r"^0x[0-9a-f]{40}$", callee_address): callee_address = "0x" + callee_address[26:] return callee_address
def _post_process_report(self, report: Report, target_address: Text, dyn_loader: DynLoader) -> None: for result in [ result for report_item in report.reports for result in report_item.results ]: for attr_name, attr_value in [ (k, v) for k, v in result.attributes.items() if k.startswith('_index') ]: attr_name_pretty = ' '.join( map(lambda s: s.capitalize(), attr_name.split('_')[2:])) result.add_attribute(f'{attr_name_pretty} Storage Index', attr_value) if dyn_loader: result.add_attribute( attr_name_pretty, dyn_loader.read_storage(target_address, attr_value)) result.remove_attribute(attr_name)