=============== FunctionMonitor =============== The ``FunctionMonitor`` plugin notifies other plugins of function calls and returns. Suppose that you are writing a plugin that needs to monitor calls to a function that starts at address ``0x400120`` in a process called ``my.exe``. Your plugin also wants to monitor all returns from that function. Proceed as follows: 1. Create a new plugin. You can use the ``Example`` plugin as a template. 2. Obtain the instance of the ``FunctionMonitor`` plugin in the ``initialize()`` method of the plugin. 3. Register a handler for the ``onCall`` signal provided by ``FunctionMonitor``. 4. In the call handler, check the current program counter to determine if this is a function that you want to process further or not. You can also use information about callers and callees provided by the signal to make this decision. 5. In the call handler, register a return handler, if necessary. 6. Do not forget to add ``my.exe`` to the configuration of ``ProcessExecutionDetector`` in ``s2e-config.lua``. The following part shows the code that implements the steps explained above. .. code-block:: cpp // 1. Write a new analysis plugin (e.g., based on the Example plugin) void Example::initialize() { // 2. Get an instance of the FunctionMonitor plugin FunctionMonitor *monitor = s2e()->getPlugin(); // 3. Get a notification when a function is called monitor->onCall.connect(sigc::mem_fun(*this, &Example::onCall)); } To monitor the function located at ``0x400120``, write the following handlers: .. code-block:: cpp void Example::onCall(S2EExecutionState *state, const ModuleDescriptorConstPtr &source, const ModuleDescriptorConstPtr &dest, uint64_t callerPc, uint64_t calleePc, const FunctionMonitor::ReturnSignalPtr &returnSignal) { // Filter out functions we don't care about if (state->regs()->getPc() != 0x400120) { return; } // If you do not want to track returns, do not connect a return signal. // Here, we pass the program counter to the return handler to identify the function // from which execution returns. returnSignal->connect( sigc::bind(sigc::mem_fun(*this, &Example::onRet), 0x400120)); } void Example::onRet(S2EExecutionState *state, const ModuleDescriptorConstPtr &source, const ModuleDescriptorConstPtr &dest, uint64_t returnSite, uint64_t functionPc) { getDebugStream(state) << "Execution returned from function " << hexval(functionPc) << "\n"; } Call/return handlers are paired: whenever the return instruction is executed and the stack pointer corresponds to the one at the call instruction, the return handler tied to that call is executed. You can pass as many parameters as you want to your call or return handlers. For this, you can use the ``fsigc++`` ``bind`` feature. .. note:: You can also instrument functions from Lua code using the ``LuaFunctionInstrumentation`` `plugin <../Howtos/LuaInstrumentation.rst>`__.