Over the time that I used IDA, I’ve vaguely always heard of the fact that IDA has a batch mode, but never really paid much attention to it. And that’s to my own peril.
A week ago a colleague of mine mentioned batch mode again, and this time, I listened. I’m glad I did.
IDA’s batch mode is increasingly useful, certainly when approaching large targets, but not just that. If the target has many dynamically linked components, or even components which are obfuscated (think funny file extensions which are actually binary, files which need to be XOR’ed before they are recognizable, and files which are outright packed), then running IDA on every one of those files becomes a pretty good idea.
Of course, not just IDA, but your entire toolkit – post-processing scripts, bug-hunting scripts, malware identification scripts, and so on. The main power of IDA’s batch mode is not in the fact that you can produce tons of IDBs at the stroke of a command, but that you can run your scripts in your toolkit against those tons of binaries.
Let me grab this short paragraph from the IDA Pro Book:
Windows versions of IDA do not require a console in order to execute, making them very easy to incorporate into virtually any type of automation script or wrapper program. When run in batch mode, the GUI versions of IDA (idag.exe and idag64.exe) do not display any graphical components. Running the Windows console versions (idaw.exe and idaw64.exe) generates a full console display that closes automatically when the batch processing is complete. The console display can be suppressed by redirecting output to a null device (NUL for cmd.exe, /dev/null in cygwin) …
By the way, if you haven’t read IDA Pro Book, go grab yourself a copy. The second edition is a worthy improvement over the first, which was already good. Highly recommended.
Back to IDA’s batch mode. Here’s what the Windows console versions look like, if you haven’t seen it before:
Command to fire up IDA in batch mode against test.exe
IDA’s start up screen (oh nostalgia)
IDA doing it’s (usual) automated analysis
I’ve found that the text interface (idaw.exe) is better for this kind of batch processing because it uses less system resources. I personally find it faster, though I did not do any formal bench-marking.
Given that I’m not looking at the thing (hey, it’s batch mode), faster is better for me. Feel free to use the GUI version if that suits your fancy.
Batch mode: -B
The key here is that this will run IDA against your file, and this can be easily scripted (batch file, python, ruby, etc) to execute against many files, or even entire directories. The argument to IDA is the
The problem, however, is that this just runs IDA’s auto-analysis, and produces a pretty IDB. It doesn’t let you run your scripts.
Autonomous mode: -A
IDA supports (mainly) two types of scripts, and I’m betting your toolkit comprises mainly of these two types of scripts. They’re your IDC and IDAPython scripts.
To use IDA in batch mode and run using either of these scripts requires a slightly different option. That would be the
-A option is designed to be used with the
-S script option. IDA uses the extension of the script to determine which extension language will runt he script.
Hence to use your IDC or IDAPython scripts, do:
idaw.exe -A -S<script-name> <file-name>
Note: idaw.exe is for Windows. Substitute that with the choice of IDA you want to run.
The IDA versions are as follows:
idaq: (All platforms: start graphical interface) idag: (Windows: start graphical interface) idaw: (Windows: start text interface) idal: (Linux/Mac: start text interface)
Ensuring analysis is complete
The IDA API exposes a function
autoWait() that ensures that IDA is done with all the analysis tasks. This also means that without calling this function first, your script will run before everything is finished, which may or may not be the best idea.
Thus, calling the function would safeguard against this.
A trivial example of how to use this, if it’s not already obvious, is as follows:
idaapi.autoWait() print('My script is now running...')
Closing IDA after your script is done
However, the immediate problem you’ll encounter is that autonomous mode, unlike batch mode, simply suppresses dialogs and any interactivity that IDA may create. Hence it’s like batch mode, but not quite. Because IDA doesn’t close after it’s done (with or without your script being run). Hence, your script needs to be responsible for closing IDA. This can be carried out using the
Exit() function in IDC.
In IDAPython, you may use
idc.Exit(0) to close IDA (and save the database). In IDC, simply use
Perhaps you may be thinking: So now I have to divide my scripts into “auto” scripts (that run in this kind of batch mode environments), and “normal” scripts which are used in my day-to-day interactive use of IDA.
Well, a simple solution would be to have an init script of sorts set a global variable in IDA stored as a net-node (persistent storage within the IDB), then run all your scripts in “batch”, and then remove that global variable (and the net-node). Then all that is necessary is to have a function in all your scripts check for the presence of that global variable, and if it exists, call idc.Exit() once it’s done.
Many other solutions are possible. That’s just mine. I’ll write up a bit more on net-nodes in the future if anybody finds that useful. But really, they’re not hard to use at all.
Other command line options
For more information about the command line options that IDA supports, you may refer to the Hex-Rays page here.