def generate_callgraph(disassembly, physics): _svm = svm.SVM(disassembly) _svm.sym_exec() html = graph_html.replace("[JS]", serialize(_svm)) html = html.replace("[ENABLE_PHYSICS]", str(physics).lower()) return html
def __init__(self, contracts, dynloader = None, simplified=False): # Convert ETHContract objects to LASER SVM "modules" modules = {} for contract in contracts: modules[contract.address] = contract.as_dict() self.svm = svm.SVM(modules, simplified = simplified, dynamic_loader=dynloader) self.svm.sym_exec(contracts[0].address) self.modules = modules self.nodes = self.svm.nodes self.edges = self.svm.edges # Analysis self.calls = [] self.suicides = [] self.sstors = {} for key in self.svm.nodes: for instruction in self.nodes[key].instruction_list: op = instruction['opcode'] if op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'): stack = copy.deepcopy(self.svm.nodes[key].states[instruction['address']].stack) if op in ('CALL', 'CALLCODE'): gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \ get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()) self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas, value)) else: gas, to, meminstart, meminsz, memoutstart, memoutsz = \ get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()) self.calls.append(Call(self.nodes[key], instruction['address'], op, to, gas)) elif op == 'SSTORE': stack = copy.deepcopy(self.svm.nodes[key].states[instruction['address']].stack) index, value = stack.pop(), stack.pop() try: self.sstors[str(index)].append(SStore(self.nodes[key], instruction['address'], value)) except KeyError: self.sstors[str(index)] = [SStore(self.nodes[key], instruction['address'], value)] self.sstor_analysis()
def __init__(self, contracts, dynloader=None, max_depth=12): # Convert ETHContract objects to LASER SVM "modules" modules = {} for contract in contracts: modules[contract.address] = contract.as_dict() self.svm = svm.SVM(modules, dynamic_loader=dynloader, max_depth=max_depth) self.svm.sym_exec(contracts[0].address) self.modules = modules self.nodes = self.svm.nodes self.edges = self.svm.edges # Analysis self.calls = [] self.suicides = [] self.sstors = {} for key in self.svm.nodes: for instruction in self.nodes[key].instruction_list: op = instruction['opcode'] if op in ('CALL', 'CALLCODE', 'DELEGATECALL', 'STATICCALL'): stack = copy.deepcopy(self.svm.nodes[key].states[ instruction['address']].stack) if op in ('CALL', 'CALLCODE'): gas, to, value, meminstart, meminsz, memoutstart, memoutsz = \ get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()) if (to.type == VarType.CONCRETE): if (to.val < 5): # ignore prebuilts continue if (meminstart.type == VarType.CONCRETE and meminsz.type == VarType.CONCRETE): self.calls.append( Call( self.nodes[key], instruction['address'], op, to, gas, value, self.svm.nodes[key].states[ instruction['address']]. memory[meminstart.val:meminsz.val * 4])) else: self.calls.append( Call(self.nodes[key], instruction['address'], op, to, gas, value)) else: gas, to, meminstart, meminsz, memoutstart, memoutsz = \ get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()), get_variable(stack.pop()) self.calls.append( Call(self.nodes[key], instruction['address'], op, to, gas)) elif op == 'SSTORE': stack = copy.deepcopy(self.svm.nodes[key].states[ instruction['address']].stack) index, value = stack.pop(), stack.pop() try: self.sstors[str(index)].append( SStore(self.nodes[key], instruction['address'], value)) except KeyError: self.sstors[str(index)] = [ SStore(self.nodes[key], instruction['address'], value) ] self.sstor_analysis()