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...
Loading...
Loading...
Loading...
Loading...
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.
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.
In IDC there are the following statements:
; (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 ; return; the same as 'return 0;' { statements... } throw ; ; (empty statement)
Please note that the 'switch' statement is not supported.
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)
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:
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.
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.
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:
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 function.
NOTE: another way to emulate global scope variables is to use functions and create global persistent arrays.
In the IDC expressions you can use almost all C operations except:
Constants 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.
The following constants can be used in IDC:
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:
Accessing an unexisting attribute generates an exception, which can be caught.
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:
Human readable form of the typeinfo can be obtained by calling the print() method. The type size can be calculated using the size() method.
loader_input_t: class to read files.
Any runtime error generates an exception. Exceptions terminate the execution. It is possible to catch an exception instead of terminating the execution:
See the details of classes.
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'.
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.
tinfo_code_t load_type( long flags, long ordinal, string name, string type, string fields="", string cmt="", string fldcmts="", long sclass=0); #define LOADTYPE_USEORD 0x01 // use ordinal to set type, otherwise set type by name #define LOADTYPE_REPLACE 0x02 // overwrite the existing type #define LOADTYPE_DEFAULT (LOADTYPE_USEORD|LOADTYPE_REPLACE)
Check the overview of all IDC functions with detailed descriptions.
The following conventions are used in the function descriptions:
success end_type_updating(long utp);
Toggle the bitwise not operator for the operand (for the explanations of 'ea' and 'n' please see op_bin())
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)
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 () should be used to get the structure type id.
long get_member_flag(long id, long member_offset);
Convert operand to a stack variable (for the explanations of 'ea' and 'n' please see ())
success op_stkvar(long ea, int n);
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:
prints 413064. The "_errtable.errnocode" expression is essentially a shortcut for:
get_field_ea(get_name_ea_simple("_errtable"), "errnocode")