state.globals. However, this can become obnoxious with large amounts of interesting data, doesn't work at all for merging states, and isn't very object-oriented.
angr.SimStatePlugin. Once you've read this document, you can use the API reference for this class to quickly review the semantics of all the interfaces you should implement.
copy: it should be annotated with the
memostaticmethod and take a dict called the "memo"---these'll be important later---and returns a copy of the plugin. Short of that, you can do whatever you want. Just make sure to call the superclass initializer!
state.get_plugin(name)is also available as a more programmatic interface.
set_statemethod. You can override this state if you need to do things like propagate the state to subcomponents or extract architectural information.
self.state! That's what the super
set_stateso that if someone else tries to interact with you, no type errors will happen. Here's an example of a good use of
init_state, to map a memory region in the state. The use of an instance variable (presumably copied as part of
copy()) ensures this only happens the first time the plugin is added to a state.
self.stateis not the state itself, but rather a weak proxy to the state. You can still use this object as a normal state, but attempts to store it persistently will not work.
len(merge_conditions)== len(others) + 1, since
zip(merge_conditions, [self] + others)will correctly pair merge conditions with plugins.
selfto become the merged version of itself and all the others, with respect to the merge conditions. This involves using the if-then-else structure that claripy provides. Here is an example of constructing this merged structure by merging a bitvector instance variable called
myvar, producing a binary tree of if-then-else expressions searching for the correct condition:
claripy.ite_cases. The following code snippet is identical to the previous one:
Ifare also available from
state.solver, and these versions will perform SimActionObject unwrapping if applicable.
def merge(self, others, merge_conditions, common_ancestor=None).
merge_conditionshave been discussed in depth already.
__setstate__magic method pair. Keep in mind the following guidelines:
set_state()will be called again.
SimFile, which is a state plugin but is stored in the filesystem plugin, and is never used with
SimState.register_plugin. When you're doing this, there are a handful of rules to remember which will keep your plugins safe and happy:
.copyof any subplugins. This with the previous point will preserve object identity.
merge()routines, make sure you unwrap
common_ancestorinto the appropriate types. For example, if
PluginB, the former should do the following:
state.my_plugin, a new instance of
MyPluginwill be instanciated and registered with the state.