| ||||||||||||||||
|
The IDA Plugin framework
by roy g biv
The IDA Plugin framework
roy g biv / 29A
Former DOS/Win16 virus writer, author of several virus families, including
Ginger (see Coderz #1 zine for terrible buggy example, contact me for better
sources ;), and Virus Bulletin 9/95 for a description of what they called
Rainbow. Co-author of world's first virus using circular partition trick
(Orsam, coded with Prototype in 1993). Designer of world's first XMS swapping
virus (John Galt, coded by RT Fishel in 1995, only 30 bytes stub, the rest is
swapped out). Author of world's first virus using Thread Local Storage for
replication (Shrug, see Virus Bulletin 6/02 for a description, but they call
it Chiton), world's first virus using Visual Basic 5/6 language extensions for
replication (OU812), world's first Native executable virus (Chthon), world's
first virus using process co-operation to prevent termination (Gemini, see
Virus Bulletin 9/02 for a description), world's first virus using polymorphic
SMTP headers (JunkMail, see Virus Bulletin 11/02 for a description), world's
first viruses that can convert any data files to infectable objects (Pretext),
world's first 32/64-bit parasitic EPO .NET virus (Croissant, see Virus
Bulletin 11/04 for a description, but they call it Impanate), world's first
virus using self-executing HTML (JunkHTMaiL, see Virus Bulletin 7/03 for a
description), world's first virus for Win64 on Intel Itanium (Shrug, see Virus
Bulletin 6/04 for a description, but they call it Rugrat), world's first virus
for Win64 on AMD AMD64 (Shrug), world's first cross-infecting virus for Intel
IA32 and AMD AMD64 (Shrug), world's first viruses that infect Office
applications and script files using the same code (Macaroni), and world's
first viruses that can infect both VBS and JScript using the same code (ACDC).
Author of various retrovirus articles (eg see Vlad #7 for the strings that
make your code invisible to TBScan). Went to sleep for a number of years.
This is my ninth virus for Win32. It is the world's first IDA plugin virus.
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.
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.
GetModuleFileName
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 _netnode_value@4(). That returns the full ASCII pathname of the file.
From there, is it possible to open the file and infect it. The RootNode and
_netnode_value@4 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 _netnode_value@4 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
iam_rgb@hotmail.com
| ||||||||||||||||