VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

The IDA Plugin framework

roy g biv
Ready Rangers Liberation Front [7]
November 2005

[Back to index] [Comments]

What is it?

Many people know about the Interactive Disassembler. It is a great tool for disassembling many different file formats for many different CPUs. It even has a debugger now, so it can be used for all kinds of reverse-engineering, unpacking, decrypting, etc. In case that was not enough functionality, it also supports plugins.


For some years, I wondered if an IDA virus could be possible. I tried in the IDC scripting language first, because there is lots of documentation for it and it is easy to program. There were some problems, though. The first problem is that IDA opens a file with full sharing, but the IDC language does not support doing that, so it is not possible to infect the file that is being examined. That leaves as an option to find other files to infect, but there is no enumeration function in the IDC language. That means that we can infect only the files that we know to exist, and that wasn't interesting to me.

Eventually, I noticed the plugins directory, but there was no documentation in IDA about how to write one. I was able to reverse-engineer the format very easily, but I had no understanding of what I was seeing, until one day when I heard about the IDA SDK. I searched on the Internet for it and found one for an old version of IDA. Since for my purposes, nothing but the version number had changed, it became very easy. Here is the description of that:

IDA Plugins are DLL files with a special extension. The extension to use depends on the operating system and CPU to support. For 32-bit Windows and Linux, and 64-bit Linux on AMD AMD64, it's "plx". For 64-bit Windows on AMD AMD64, it's "x64". For 64-bit Windows on Intel EM64T, it's "p64". For 64-bit Linux on Intel EM64T, it's "plx64".

The plugin must contain one export. This export must be called "_PLUGIN" or "PLUGIN" or it must be ordinal 1. The export points to a structure. The structure is byte-packed and it has this format:

  struct plugin_t
    int version;
    int flags;
    int (idaapi* init)(void);
    void (idaapi* term)(void);
    void (idaapi* run)(int arg);
    char *comment;
    char *help;
    char *wanted_name;
    char *wanted_hotkey;

The version is the version number of the SDK. I was told 75 for IDA 4.8. (Now is November, and I am told that IDA 4.9 has 76 for the version number) The flags are for some behaviours mostly to do with debugging.

The init function is the only necessary function. It is called by IDA when the plugin is loaded, which occurs after the file to disassemble has been opened. If the init function returns 0, then IDA will discard the plugin and not call any of the other functions. If the function returns another value, then IDA will keep the plugin and call the other functions as required. The term function is called by IDA to terminate the plugin when IDA is exiting.

The run function is called whenever the plugin is invoked.

There is also a callback mechanism with so many events that can be hooked, I cannot list them all here. None of them fitted my purpose, anyway.


When the init function is called, the file to dissasemble can be accessed, if its name is known. The problem is to find out the name. Amazingly, there seems to be no public function to do that. After much reading, I found a way to do it. It is achieved by passing the RootNode netnode to the function called [email protected](). That returns the full ASCII pathname of the file. From there, is it possible to open the file and infect it. The RootNode and [email protected] are exports from the ida.wll file. Since they are exported by ordinal only, so they are subject to change, but since the SDK version number is required to match, nothing would be gained by exporting by name.

(Now is November, and IDA 4.9 changed some things. The [email protected] was renamed to "netnode_valstr". Both RootNode and netnode_valstr are exported by name, so the ida.lib is not required anymore to build. The parameters for the netnode_valstr function are also different from previously. Now is required to pass the buffer and its length to receive the name).

What about stealth?

An obvious extension to the infection via plugin is to stealth the result. As it is right now, the changes don't show until the file is opened again, but by the time the plugin is loaded, IDA has decided where the entrypoint is, and I couldn't find a way to change that, or to hide the code. That's for someone else to discover. ;)

Greets to friendly people (A-Z)

Active - Benny - Obleak - Prototype - Ratter - Ronin - RT Fishel - sars - SPTH - The Gingerbread Man - Ultras - uNdErX - Vallez - Vecna - VirusBuster - Whitehead

rgb/29A sep/nov 2005
[email protected]
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka