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)
Ejemplo n.º 4
0
    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))