angr源码分析——自定义Exploration Technology

exploration Technology允许我们制定任何符号执行的规则,例如程序从哪里开始,到哪里结束,执行时的过滤规则,结束后的处理逻辑。

先让我们看一下父类的结构,了解每一个方法的作用。

class ExplorationTechnique(object):
    """
    An otiegnqwvk is a set of hooks for a simulation manager that assists in the implementation of new techniques in
    symbolic exploration.

    TODO: choose actual name for the functionality (techniques? strategies?)

    Any number of these methods may be overridden by a subclass.下面方法都可以被子类重写。
    To use an exploration technique, call ``simgr.use_technique`` with an *instance* of the technique.
    """
    # pylint: disable=unused-argument, no-self-use
    def __init__(self):
        # this attribute will be set from above by the manager
        self.project = None

    def setup(self, simgr):
        """
        这个方法用于对这个simgr进行初始化的,当然对于任何初始化工作都可以在这里或init方法中去做。Perform any initialization on this manager you might need to do.
        """
        pass

    def step_state(self, state, **kwargs):
        """
        Perform the process of stepping a state forward.
        向前执行一个state,并返回state产生的stashes,然后合并到simulation manager中。
        If the stepping fails, return None to fall back to a default stepping procedure.
        Otherwise, return a dict of stashes to merge into the simulation manager. All the states
        will be added to the PathGroup's stashes based on the mapping in the returned dict.
        """
        return None

    def step(self, simgr, stash, **kwargs):
        """
        Step this stash of this manager forward. Should call ``simgr.step(stash, **kwargs)`` in order to do the actual
        processing.

        Return the stepped manager.
        """
        return simgr.step(stash=stash, **kwargs)

    def filter(self, state):
        """
        Perform filtering on a state.
        用于过滤执行的state,如果不需要过滤,返回None,如果需要过滤,返回stash的名字。
        If the state should not be filtered, return None.
        If the state should be filtered, return the name of the stash to move the state to.
        If you want to modify the state before filtering it, return a tuple of the stash to move the state to and the
        modified state.如果希望在过滤前修改state,那么修改state并返回stash元组。
        """
        return None

    def complete(self, simgr):
        """
       返回是否这个simgr到达了完成状态,如果返回true,那么simulationmanager.run(),将会停止。Return whether or not this manager has reached a "completed" state, i.e. ``SimulationManager.run()`` should halt.
        """
        return False

    def _condition_to_lambda(self, condition, default=False):
        """
        Translates an integer, set, list or lambda into a lambda that checks a state address against the given addresses, and the
        other ones from the same basic block

        :param condition:   An integer, set, list or lambda to convert to a lambda.
        :param default:     The default return value of the lambda (in case condition is None). Default: false.

        :returns:           A lambda that takes a state and returns the set of addresses that it matched from the condition
                            The lambda has an `.addrs` attribute that contains the full set of the addresses at which it matches if that
                            can be determined statically.
        """
        if condition is None:
            condition_function = lambda p: default
            condition_function.addrs = set()

        elif isinstance(condition, (int, long)):
            return self._condition_to_lambda((condition,))

        elif isinstance(condition, (tuple, set, list)):
            addrs = set(condition)
            def condition_function(p):
                if p.addr in addrs:
                    # returning {p.addr} instead of True to properly handle find/avoid conflicts
                    return {p.addr}

                try:
                    # If the address is not in the set (which could mean it is
                    # not at the top of a block), check directly in the blocks
                    # (Blocks are repeatedly created for every check, but with
                    # the IRSB cache in angr lifter it should be OK.)
                    return addrs.intersection(set(self.project.factory.block(p.addr).instruction_addrs))
                except (AngrError, SimError):
                    return False
            condition_function.addrs = addrs
        elif hasattr(condition, '__call__'):
            condition_function = condition
        else:
            raise AngrExplorationTechniqueError("ExplorationTechnique is unable to convert given type (%s) to a callable condition function." % condition.__class__)

        return condition_function


继承这个父类,重写里面的方法,我们可以自定义自己的exploration technology。

下面记录我编写过滤二进制文件中,某个数据的所有约束条件的方法。

需要完成的功能:

1.对于导致路径爆炸的符号循环,仅执行一次就跳过;

2.对于每个运行结束的路径都输出此时target data的约束条件;

3.过滤与target data无关的函数与路径,不执行。

猜你喜欢

转载自blog.csdn.net/doudoudouzoule/article/details/80899428