0 Votes

Foreign functions interface

Last modified by WikiBot on 2025/03/20 14:16

Foreign functions interface

From version 4.0, IDA Modeler supports calls of external functions from IDA scripts.

Declaring external functions

The external functions should be declared before use. To declare an external function, execute the following script function:

(external-function
  return-type name (argtype ...)
  dll-name [entry-name])

Argument types

The types (return-type and argument types) are either the basic types

real, integer, unsigned, character, Boolean, variant, object, void

or lists

(basic-type [width] [*|out]),

where width may be 1, 2, 4, or 8 and * means that the argument is passed by reference (and therefore may denote an array of elements of the basic type), and out means that the argument is output or input/output. Supported widths are (the default one marked with #):

real: 4, 8#
integer, unsigned: 1, 2, 4#, 8 (width 8 is not supported for arrays)
character: 1#, 2
Boolean: 1, 2, 4#

Array types for return values are not yet implemented.

The type object is represented in the foreign code as a handler (unsigned long integer). The handlers may be used when executing IDA scripts from external functions. They are valid only during the external call.

The type variant is always passed by reference.

Dll and entry name

The parameter dll-name should be a string containing the dll’s filename. If the name does not contain a full path, the file is searched according to the standard Windows rules. If the dll file is in the application directory, the dll-name may be in form of "sys:appname/libname.dll". Both slash "/" and backslash "\" may be used as delimiters (the backslash should be doubled).

The dll-name is ignored if the entry-name is not a string.

The entry-name is either

  • the name of the function in DLL, or
  • the address of the entry point (such addresses may be returned by other foreign functions), or
  • 0 (in this case the entry point may be assigned later using set-external-entry

The default entry name is constructed from the function name by the following procedure:

all letters are changed to down case;
the combination "-x" is replaced with "X", if x is a letter;
the characters that are not letters or digits are replaced with "_".

We recommend using names with prefix denoting the application (or extension of application):

function name in IDA: myapp-do-something
function name in DLL: myappDoSomething

Supported link types

Both c (also called cdecl) and pascal (also called stdcall) link types are supported. There is no need to specify link type.

Passing arguments via CPU registers is not supported.

Calling of external functions

Once declared, an external function may be called from any IDA script in the same way as IDA built-in functions:

(:call func-name arg1 ...)

The number of arguments should be equal to the declared one. The argument types should be compatible. The possible conversions include

  • Instances of parameters and variables may be converted to their values;
  • Scalar arguments may be converted to vectors;
  • Any value may be converted to a string or variant.

The output argument may be only

  • An array; in this case the elements of the array may be modified by the external function;
  • An instance of a parameter or an element of an array-valued parameter; the external function will modify the parameter value.

The keyword :call may be omitted in script commands (but not in script expressions).

Indirect call of external functions

The definition of an external function consists of two parts, the interface (description of parameters and return value) and the entry point. Normally these two parts are used together, but not always.

If the entry point is variable (e.g., returned by some other external function), it is more convenient to supply the interface and entry point separately:

(:call indirect func-name entry arg1 ...)

To change the entry point of an external function, use

(:call set-external-entry func-name entry)

The following function returns the entry point of an external function:

(:call external-entry func-name)