Undo: IDA can do it
The undo feature covers the information that is stored in the database files (.idb or .i64). Undo does not handle the things stored in other places, like the operating system registry, external files, information stored in memory, etc. Also it is impossible to undo debugger events, for natural reasons.
Apart from that our undo feature can revert the entire IDA database to the state that was present before a user action. For example, IDA usually needs some guidance from the user in order to analyze binary files. Imagine that the user presses C at the entry point and this lets IDA to discover all functions in the input file, analyze, and annotate them. If the user waits for the analysis to finish and then presses Ctrl-Z, the entire analysis will be rolled back and the database will return to its initial state. But do not worry, we implemented the redo command too, so it is just one more keypress (Ctrl-Y) to recover the analysis results.
This comes with a price: undo history has to be stored in memory and is lost if you exit IDA. It is also reset if you open another file or database. You can observe the memory consumed by undo and manipulate the undo history via a corresponding subview available in View-Open subviews menu.
During analysis huge amounts of undo data may be produced. It may be hundreds of megabytes or even gigabytes. In order to avoid consuming all RAM and thrashing the computer, IDA has a hard limit on the amount of undo data. The default value is a rather conservative 100MB; you can change it by editing the ida.cfg file. Once the limit is reached, IDA will remove a few oldest undo entries. It will continue to append undo data to the last undo entry. Once the last undo entry becomes bigger than the limit, the entire undo history is cleared.
However, as soon as the user performs a new action, IDA will resume collecting the undo data, and the new action will be undoable (unless it too generates too much undo data).
You can elect to disable undo during the initial analysis. This speeds up analysis and undo will be automatically re-enabled as soon as the analysis finishes.
Another price to pay is the complexity. Not only IDA has more complex logic and using undo may potentially corrupt the database, but also third party plugins have to be aware of the undo feature. For example, if a plugin remembers that there was a function named, say, “strcpy”, and cached its address in a local static variable, after undo the function may disappear or change its name, which will make the cached address incorrect.
Some user actions are not undoable. Most debugger related actions are like this. For example, starting a debugger or resuming the debugged application are not undoable.
We tested the undo feature extensively but since it affects the core logic of IDA, bugs that corrupt the database cannot be excluded. Overall our database engine is (was?) very robust and we rarely receive reports about corrupted databases but if you encounter anything wrong, please file a bug report. All our users will benefit from early fixed bugs.
Below are technical details for plugin writers:
- In order to reduce the complexity and make the undo feature more predictable, when the user invokes undo, the kernel will not generate any events. This means that plugins cannot rely on the standard events (e.g. ‘func_added’) to detect changes and take the necessary actions. We decided to disable all events because if we enable them, plugins may react and modify the database in unforeseeable ways, thus making undo impossible.
- There are just two events that occur during undo: ev_replaying_undo and ev_ending_undo. Plugins should listen to ev_ending_undo and reset their internal state. The simplest approach is to assume that the database has completely changed and to re-read information from the database to the memory.
- Plugins in general should not cache and reuse pointers to kernel objects (like func_t, segment_t). These pointers may change between plugins invocations.
- UI actions or menu items registered by third party plugins will be undoable by default, there is no need to do anything. However, it does not make sense for some actions to be undoable. For example, an action that does not modify the database (just displays some info on the screen) or an action that only creates some output files on the disk do not need to be undoable. However, IDA may still create undo points for them. To prevent useless undo points you can use the ADF_NO_UNDO bit in the action description.
- To keep things simple for plugin writers, we do not provide low-level implementation details at this time. If it turns out that plugins need more detailed undo info, we will publish it later.