Extending IDC and IDAPython
In the blog post going to demonstrate how to extend both IDC and IDAPython to add new functions.
Extending IDC
Every IDC variable is represented by an idc_value_t object in the SDK. The IDC variable type is stored in the idc_value->vtype field and have one of the following values:
- VT_LONG: Used to store 32bit signed numbers (or 64bit numbers if __EA64__ is set). Use idc_value->set_long() to set a value and idc_value->num to read it.
- VT_STR2: Used to store arbitrary strings. Use idc_value->set_string() to set a value, idc_value->c_str() to get a C string or idc_value->qstr() to get a qstring instance.
- VT_INT64: Used to store 64bit signed numbers. Use idc_value->i64 to read the value and idc_value->set_int64() to set a value
- VT_OBJ: Used to represent objects. Such idc variable is created via the VarObject() and attributes are managed by VarSetAttr() / VarGetAttr()
- VT_PVOID: Use to store arbitrary untyped values. Use idc_value->pvoid to read this value and idc_value->set_pvoid() to set it
- Writing the IDC function callback
- Registering the function
Writing the callback
The callback is defined as:typedef error_t idaapi idc_func_t(idc_value_t *argv,idc_value_t *r);
The argv array is initialized by the IDC interpreter and contains the passed arguments and the r argument is set by the callback to return values to the IDC interpreter.
Registering an IDC function
The IDC function callback can be registered with the IDC interpreter using this function:Where:bool set_idc_func(const char *name, idc_func_t *fp, const char *args);
- name: designates the IDC function name to be added
- fp: IDC function callback (written in the previous step)
- args: A zero terminated character array containing the expected arguments types (VT_xxx). For example, an IDC function that expects two numbers and one string as arguments have the following args value: {VT_LONG, VT_LONG, VT_STR2, 0}
Example
For the sake of demonstration, let us add getenv() to IDC:static const char idc_getenv_args[] = { VT_STR2, 0 }; static const char idc_getenv_name[] = "getenv"; static error_t idaapi idc_getenv(idc_value_t *argv, idc_value_t *res) { char *env = getenv(argv[0].c_str()); res->set_string(env == NULL ? "" : env); return eOk; } int idaapi init() { set_idc_func(idc_getenv_name, idc_getenv, idc_getenv_args ); return PLUGIN_KEEP; } void idaapi term(void) { // Unregister set_idc_func(idc_getenv_name, NULL, NULL); }
Extending IDAPython
It is possible to extend IDAPython in two ways:- Modifying the source code of IDAPython
- Writing a plugin to extend Python scripting
While the former method requires basic knowledge of SWIG, both methods require some understanding of the Python C API.
In this article, we will use the second method because it is more practical and does not require modification to IDAPython itself.
- Initializing the Python C API
- Writing the callback(s)
- Registering the function(s)
Writing the callback
Let us wrap the following function:which is used to retrieve the predifined comment of a given instruction.// ints.hpp idaman ssize_t ida_export get_predef_insn_cmt( const insn_t &cmd, char *buf, size_t bufsize);
We want to expose it as the following Python function:
def get_predef_insn_cmt(ea): """Return instruction comments @param ea: Instruction ea @return: None on failure or a string containing the instruction comment """ pass

The IDA Pro book
Comments
cool! most useful for wrapping some of the decompiler's functionality :)
Posted by: dennis | June 25, 2010 09:59 AM
Yes you are right, the decompiler is just one example.
Posted by: Elias Bachaalany
|
June 28, 2010 12:46 PM
just curious if you ever considered having support for php or javascript as well?
Posted by: Dave | June 30, 2010 11:07 PM
Hello Dave,
Javascript: we already have an extlang for it. Please check Ilfak's post here: http://hexblog.com/2009/08/javascript_for_ida_pro.html. Note that we are not updating it because we finally settled with IDC and Python.
As for PHP, if I am not wrong, I once saw a PHP extlang for IDA Pro (or maybe not). Nonetheless, SWIG supports PHP so it should not be too difficult to write something functional in a short amount of time.
Posted by: Elias Bachaalany
|
July 1, 2010 07:31 AM
IDACharp
http://bbs.pediy.com/showthread.php?t=112418
Posted by: nnhy
|
July 10, 2010 07:44 PM