Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
In IDC there are the following statements: expression; (expression-statement) if (expression) statement if (expression) statement else statement for ( expr1; expr2; expr3 ) statement while (expression) statement do statement while (expression); break; continue; return <expr>; return; the same as 'return 0;' { statements... } try statement catch ( var ) statement throw <expr>; ; (empty statement) Please note that the 'switch' statement is not supported.
IDC language is a C-like language. It has the same lexical tokens as C does: character set, constants, identifiers, keywords, etc. However, since it is a scripting language, there are no pointers, and all variable types can be handled by the interpreter. Any variable may hold any value; variables are declared without specifying their type;
auto myvar;
An IDC program consists of function declarations. By default, execution starts from a function named 'main'.
Select a topic to read:
IDC is an IDA native, embedded scripting language semantically similar to C/C++.
With IDC, you can write simple scripts for automating repetitive tasks and extending out-of-the-box IDA functionality (for example, for getting the list of all functions or marked positions) without creating more complex plugins with C++ SDK or IDAPython.
In the IDC expressions you can use almost all C operations except:
are defined more or less like in C, with some minor differences.
There are four type conversion operations:
However, explicit type conversions are rarely required because all type conversions are made automatically:
If any of the long operands is 64bit, the other operand is converted to 64bit too.
There is one notable exception concerning type conversions: if one operand is a string and the other is zero (0), then a string operation is performed. Zero is converted to an empty string in this case.
The & operator is used to take a reference to a variable. References themselves cannot be modified once created. Any assignment to them will modify the target variable. For example:
References to references are immediately resolved:
Since all non-object arguments are passed to functions by value, references are a good way to pass arguments by reference.
IDC Getting Started
Learn core concepts of IDC.
IDC Reference
Check the list of all IDC functions with details
IDC Examples
Explore ready-to-use samples.
Any runtime error generates an exception. Exceptions terminate the execution. It is possible to catch an exception instead of terminating the execution: auto e; try { ... some statements that cause a runtime error... } catch ( e ) { // e holds the exception information // it is an instance of the exception class } The try/catch blocks can be nested. If the current function has no try/catch blocks, the calling function will be examined, and so on, until we find a try/catch block or exit the main function. If no try/catch block is found, an unhandled exception is reported.
It is also possible to throw an exception explicitly. Any object can be thrown. For example:
will throw value '5'.
There are two kinds of variables in IDC:
A variable can contain:
LONG: a 32-bit signed long integer (64-bit in 64-bit version of IDA)
INT64: a 64-bit signed long integer
STR: a character string
FLOAT: a floating point number (extra precision, up to 25 decimal digits)
OBJECT: an object with attributes and methods (a concept very close to C++ class) more
REF: a reference to another variable
FUNC: a function reference
A local variable is declared this way:
Global variables are declared like this:
Global variables can be redefined many times. IDA will silently ignore subsequent declarations. Please note that global variables cannot be initialized at the declaration time.
All C and C++ keywords are reserved and cannot be used as a variable name.
While it is possible to declare a variable anywhere in the function body, all variables are initialized at the function entry and all of them are destroyed only at the exit. So, a variable declared in a loop body will not be reinitialized at each loop iteration, unless explicitly specified with an assignment operator.
If a variable or function name cannot be recognized, IDA tries to resolve them using the names from the disassembled application. In it succeeds, the name is replaced by its value in the disassembly listing. For example:
will print 413060. If the label denotes a structure, it is possible to refer to its fields:
will print 413064. Please note that IDA does not try to read the data but just returns the address of the structure field. The field address can also be calculated using the get_field_ea function.
NOTE: The processor register names can be used in the IDC scripts when the debugger is active. Reading from such a variable return the corresponding register value. Writing to such a variable modifies the register value in the debugged process. Such variables are accessible only when the application is in the suspended mode.
NOTE: another way to emulate global scope variables is to use array functions and create global persistent arrays.
The loader_input_t class can read from input files. It has the following methods:
Instances of this class can be created by calling the open_loader_input function.
See other IDC classes.
The following symbols are predefined in the IDC preprocessor:
These symbols are also defined when parsing C header files.
Classes can be declared the following way:
Inside the class, method functions are declared without the 'static' keyword. The method with the name of the class is the class constructor. For example:
Inside the class methods, the 'this' variable can be used to refer to the current object.
Only one constructor per class is allowed.
Class instances are created like this:
And object attributes (or fields) are accessed like this:
A new attribute is created upon assigning to it:
The following special method names exist:
Simple class inheritance is support. Derived classed are declared like this:
Here we declare the 'derived' class that is derived from the 'base' class. For derived classes, the base class constructor can be called explicitly:
If the base class constructor is not called explicitly, IDA will call it implicitly, without any arguments.
It is possible to call base class methods using full names:
The 'this' argument must be passed explicitly in this case.
When there are no more references to an object, it is automatically destroyed. We use a simple reference count algorithm to track the object use. Circularly dependent objects are not detected: they are never destroyed.
The following built-in object classes exist:
The slice operator can be applied IDC objects are strings.
For strings, the slice operator denotes a substring:
Any indexes that are out of bounds are silently adjusted to correct values. If i1 >= i2, empty string is returned. Negative indexes are used to denote positions counting from the end of the string.
String slices can be used on the right side of an assignment. For example:
will replace 2 characters at the beginning of the string by "abc".
For objects, the slice operator denotes a subset of attributes. It can be used to emulate arrays:
x[i1:i2] denotes all attributes with numeric values between i1 and i2 (i2 is excluded).
Any non-numeric attributes are ignored by the slice operator.
An IDC function always returns a value. There are 2 kinds of functions:
functions
user-defined functions A user-defined function is declared this way: static func(arg1,arg2,arg3) { ... } It is not necessary to specify the parameter types because all necessary type conversions are performed automatically.
By default all function arguments are passed by value, except:
If the function to call does not exist, IDA tries to resolve the name using the debugged program labels. If it succeeds, an is performed.
Accessing an unexisting attribute generates an exception, which can be .
Human readable form of the typeinfo can be obtained by calling the method. The type size can be calculated using the method.
: class to read files.
The following constants can be used in IDC:
Toggle the bitwise not operator for the operand (for the explanations of 'ea' and 'n' please see ())
success toggle_bnot(long ea, int n);
Convert the current item to a floating point (4 bytes) ea - linear address returns: 1-ok, 0-failure This is a convenience macro, see also create_data() function
#define create_float(ea) create_data(ea, FF_FLOAT, 4, BADADDR)
success end_type_updating(long utp);
The following conventions are used in the function descriptions:
Convert operand to a high offset High offset is the upper 16bits of an offset. This type is used by PPC, MIPS, and other RISC processors. (for the explanations of 'ea' and 'n' please see ()) target - the full value (all 32bits) of the offset
success op_offset_high16(long ea, int n, long target);
get type of a member id - structure type ID member_offset - member offset. The offset can be any offset in the member. For example, is a member is 4 bytes long and starts at offset 2, then 2, 3, 4, 5 denote the same structure member. returns: -1 if bad structure type ID is passed or no such member in the structure otherwise returns type of the member, see bit definitions above. If the member type is a structure then function get_member_strid() should be used to get the structure type id.
long get_member_flag(long id, long member_offset);
Convert operand to a complex offset expression This is a more powerful version of op_plain_offset() function. It allows to explicitly specify the reference type (off8, off16, etc) and the expression target with a possible target delta. The complex expressions are represented by IDA in the following form:
If the target is not present, then it will be calculated using target = operand_value - tdelta + base The target must be present for LOW.. and HIGH.. reference types ea - linear address of the instruction/data n - number of operand to convert (the same as in op_plain_offset) reftype - one of REF_... constants target - an explicitly specified expression target. if you don't want to specify it, use -1. Please note that LOW... and HIGH... reference type require the target. base - the offset base (a linear address) tdelta - a displacement from the target which will be displayed in the expression.
success op_offset(long ea, int n, long reftype, long target, long base, long tdelta);
#define REF_OFF8 0 // 8bit full offset #define REF_OFF16 1 // 16bit full offset #define REF_OFF32 2 // 32bit full offset #define REF_LOW8 3 // low 8bits of 16bit offset #define REF_LOW16 4 // low 16bits of 32bit offset #define REF_HIGH8 5 // high 8bits of 16bit offset #define REF_HIGH16 6 // high 16bits of 32bit offset #define V695_REF_VHIGH 7 // obsolete #define V695_REF_VLOW 8 // obsolete #define REF_OFF64 9 // 64bit full offset // note: processor modules or plugins may register additional // custom reference types (for example, REF_HIGHA16 is // used by MIPS, SPARC, PPC, ALPHA, TRICORE, etc.) #define REFINFO_RVA 0x10 // based reference (rva) #define REFINFO_PASTEND 0x20 // reference past an item // it may point to an nonexistitng address // do not destroy alignment dirs #define REFINFO_NOBASE 0x80 // offset base is a number // implies that base have be any value // nb: base xrefs are created only if base // points to the middle of a segment #define REFINFO_SUBTRACT 0x0100 // the reference value is subtracted from // the base value instead of (as usual) // being added to it #define REFINFO_SIGNEDOP 0x0200 // the operand value is sign-extended (only // supported for REF_OFF8/16/32/64) #define REFINFO_NO_ZEROS 0x0400 ///< an opval of 0 will be considered invalid #define REFINFO_NO_ONES 0x0800 ///< an opval of ~0 will be considered invalid
get index of last structure type none returns: -1 if no structure type is defined index of last structure type. See get_first_struc_idx() for the explanation of structure indices and IDs.
long get_last_struc_idx();
Convert operand to a stack variable (for the explanations of 'ea' and 'n' please see op_bin())
success op_stkvar(long ea, int n);
prints 413064. The "_errtable.errnocode" expression is essentially a shortcut for:
get_field_ea(get_name_ea_simple("_errtable"), "errnocode")