def did_execute_instruction_callback(self, state, old_pc, new_pc, instruction): #Get the address we are looking for with self.manticore.locked_context() as context: pathsObject = context['paths'] #Check if we just executed the address we are looking for pathsEndingHere = []#Contains at most one element except if we have been requested to evaluate the same path twice for i in range(0,pathsObject.pathsLen): if (pathsObject.paths[i].pathLen-1 == state.context['PCCounter'] and old_pc == pathsObject.lastAddresses[i]): pathsEndingHere.append(i) with self.manticore.locked_context() as context: targets = context['targets'] for i in pathsEndingHere: out = "Possible targets ["+str(i)+"]"+"]: " out = hex(old_pc)+ "->" #Calculate possible successors of the instruction at the target address for concreteNewPC in state.solve_n(new_pc, nsolves=5):#TODO: Other value for nsolves? Check if conditional branch. 1 if unconditional. Maybe add constraint that next value can not equal first? for pathId in pathsEndingHere: if pathId not in targets.keys(): targets[pathId] = set() targets[pathId].add(hex(concreteNewPC)) #Log our results! out += ",".join([str(i) for i in targets[i]]) logger.debug(out) # Put the results in the global context so that they can be accessed later with self.manticore.locked_context() as context: context['targets'] = targets
def will_execute_instruction_callback(self, state, pc, instruction): with self.manticore.locked_context() as context: pathsObject = context['paths'] # Update PCCounter if 'PCCounter' not in state.context: state.context['PCCounter'] = 0 state.context['pathIDs'] = range( pathsObject.pathsLen) # All paths start with the first instruction of the binary else: state.context['PCCounter'] += 1 # Check if RIP of the state is matching a path, else abandon it newPathIDS = [] PCCounter = state.context['PCCounter'] keeping = [] for pathID in state.context['pathIDs']: if PCCounter >= pathsObject.paths[pathID].pathLen: continue if pathsObject.paths[pathID].path[PCCounter] == state.cpu.RIP: newPathIDS.append(pathID) keeping.append(str(pathID)) state.context['pathIDs'] = newPathIDS logger.debug("keeping: " + ",".join(keeping)) if (not state.context['pathIDs']): # No path includes the state state logger.debug("Abandoning state with RIP=" + hex(state.cpu.RIP) + " PCCounter=" + str(PCCounter)) state.abandon()
def did_execute_instruction_callback(self, state, old_pc, new_pc, instruction): #Extract jump targets #Get the address we are looking for with self.manticore.locked_context() as context: address = context['instructionAddress'] #Check if we just executed the address we are looking for if (old_pc == address): logger.info("Calculating possible targets") out=hex(old_pc)+ "->" with self.manticore.locked_context() as context: targets = context['targets'] #Calculate possible succeessor of the instruction at the target address for i in state.solve_n(new_pc, nsolves=5): targets.add(hex(i)) #Put them in the global context so that they can be accessed later with self.manticore.locked_context() as context: context['targets'] = targets #Log our results! out += ",".join(targets) logger.debug(out)
def run(self): while True: logger.info("Waiting for connection..") self.connection.connect() logger.info("Connection received!") # Work loop while True: try: request = self.connection.getWork() except socketClosedException: #Client closed socket logger.info("Client disconnected") break except Exception as inst: print("Exception:" + str(inst)) break milliseconds = round(time.monotonic() * 1000) #Get time in milliseconds request = request.split("\n") program = request[0] paths = formatPaths(request[1:]) logger.info("Program: " + program) logger.info("Number of paths received: " + str(paths.pathsLen)) args = ["+" * 20] * 3 targets = symbolicExecutor.executeDirected(program, paths, args=args) response = formatResponse(paths, targets) milliseconds = round(time.monotonic() * 1000) - milliseconds logger.info("Symbolic execution took: " + str(milliseconds) + " ms") logger.debug("Sending: " + response) self.connection.sendAnswer(response)
def executeDirected(program, pathsObject, args=[]): workplace_url = "/tmp/mcore_tmp" m = Manticore(program, argv=args, workspace_url=workplace_url, pure_symbolic=False) consts = config.get_group("core") consts.__setattr__("procs", 1) #Store variables in global context to ensure that we can communicate them to the callback function with m.locked_context() as context: context['paths'] = pathsObject context['targets'] = dict() #Register hook to have each executed instruction's RIP logged m.add_hook(None, log_rip) m.register_plugin(DirectedExtractorPlugin()) #Output the set of paths for i in pathsObject.paths: l = [hex(j) for j in i.path] logger.debug(",".join(l)) #Execute the directed symbolic execution m.run() #Obtain the dictionary of control flow edges from Manticore with m.locked_context() as context: targets = context['targets'] #Output results logger.debug("--Results Sorted by Pathlen--") sortedPaths = sorted(pathsObject.paths, key=lambda x: x.pathLen, reverse=False) for i in range(pathsObject.pathsLen): pathID = sortedPaths[i].pathID if pathID in targets.keys(): logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "] ending with " + hex( pathsObject.lastAddresses[pathID]) + " has the following successors " + ",".join([str(i) for i in targets[pathID]])) else: logger.debug("Path " + str(pathID) + "[len=" + str(sortedPaths[i].pathLen) + "]" + " is infeasible") return targets
def log_rip(state): logger.debug(hex(state.cpu.RIP))