IDA’s functionality can easily be extended by the use of programmable plug-ins. Plugins may be written to automate routine tasks, for example to enhance the analysis of hostile code or to add specific functionality to our disassembler. Plugins should be written in C++. They may be linked to hot keys or menu items and have full access to the IDA database and may examine or modify the program or use I/O functions. Our SDK contains
4 sample plugins
a simple “hello world” type plugin.
a sample processor extension plugin (adds 2 NEC V20 specific instructions to the 80Ă—86 processor module).
a sample pdb file loader ( as used by IDA itself ).
a sample executable decryption plugin.
a sample graphing plugin.
the source code to a 30+ processor modules!
the source code to a 20+ loaders
header files (almost 19.000 lines of heavily commented documentation to IDA’s exported interface).
import libraries for Borland C/C++ (32 & 64 bits), Microsoft Visual C++ 6 (32 & 64 bits), GNU C/C++ (32 & 64 bits), Watcom 11
if you received IDA as a download, the SDK download information can be found in the e-mail you have received.
Additional free plugins, from Ilfak’s blog:
Plugin options
The -O command line switch allows the user to pass options to the plugins. A plugin which uses options should call the get_plugin_options() function to get them.
Since there may be many plugins written by independent programmers, each options will have a prefix -O in front of the plugin name.
For example, a plugin named "decomp" should expect its parameters to be in the following format:
In this case, get_plugin_options("decomp") will return the "option1:option2:option3" part of the options string.
If there are several -O options in the command line, they will be concatenated with ':' between them.
List of plugins recognizing '-O' switch
Plugins Shipped with IDA
IDA natively is shipped with repository of plugins, that are inside your IDA folder. You do not need to install them separately, but in this section you'll find guides on how to use their basic features.
This switch is not available in the IDA Home edition.
-Odecomp:option1:option2:option3
How to write your own plugin?
Do you want to create custom plugins and wonder where to start? Check our tutorials based on the language of your choice:
Create plugins with C++ SDK
Create plugins with IDAPython
Plugin Contest
Analyzing software in general and reverse-engineering in specifically are difficult. It is challenging even with a first-class tool like IDA: quite frequently, the limitations of the tool reveal themselves. That's why IDA can be programmed in multiple ways: with the built-in scriptable language, with Python 3, and plugins in C/C++.
Plugin contest in a nutshell:
Create an innovative and useful extension of our products and win the contest!
Three cash prizes are on the stake:
The first place is 3000 USD, the second place is 2000 USD, and the third place is 1000 USD.
Who can participate: all IDA license holders.
Want to know more? Check our contest rules
Swift plugin
Demangling
The swift plugin uses libSwiftDemangle to demangle Swift names. Note that IDA already had a built-in swift demangler, but it was becoming difficult to maintain. In the long-term we hope to fully deprecate IDA's custom swift demangler in favor of libSwiftDemangle.
However, the new approach still hasn't been fully integrated into IDA, so there may be times when IDA's old swift demangler produces more desirable results.
'cfg/swift.cfg' file presents all the options
'-Oswift' command line switches can be used to enable or disable some plugin options.
List of options
Examples
Do not group functions into folders.
- <demangler_path> : use specific libSwiftDemangle library
- -d : use the built-in IDA swift demangler (legacy)
- +d : use libSwiftDemangle swift demangler
- -m : don't present metadata in nice way
- +m : present metadata in nice way
- -e : don't import enumeration types
- +e : import enumeration types
- -s : don't import structure types
- +s : import structure types
- -v : don't set variable type based on mangled names
- +v : set variable type based on mangled names
- -f : don't set function prototype based on mangled names
- +f : set function prototype based on mangled names
- -g : don't group functions in folders corresponding to modules
- +g : group functions in folders corresponding to modules
-Oswift:-g
-Oswift:/tmp/libSwiftDemangle_custom.dylib
Rust plugin
The binaries produced by the Rust compiler have some peculiarities which make them difficult to analyze, such as:
By default, Rust plugin is enabled if one of the following condition is true
- one address is named 'rust_begin_unwind'
- the string 'rustc-' can be found somewhere in the program
If the segment '.rodata' exists, the search is limited to this segment
String literal analysis
Rust plugin walks to all addresses in segment with name ending in "__const", ".rodata" or ".rdata" and creates string literals on xref
- on dref, the string literal is set up to the next dref
- on cref, Rust tries to retrieve length from nearby instructions
Arm, Risc-V and pc proc module benefit from this
To force the string literal detection:
idaapi.load_and_run_plugin("rust", 1)
Demangling name
Rust plugin also offers the possibility to configure a demangler library for rust. By default the plugin will use the librustdemangle library that is shipped with IDA. You can disable this feature in 'Edit>Plugin>Rust language helper' or specify another library to use.
See cfg/rust.cfg for the possible options
List of '-Orust' options
Example
This disable the plugin for this session of IDA.
Golang plugin
Golang binaries are by default statically linked and full of metadata therefore a lot can be gained from annotating a Golang binary's contents using recovered metadata.
Detection
The golang plugin's analysis only happens by default if the input file is detected as a Golang file. There are multiple mechanisms in place to detect that:
DWARF plugin
DWARF plugin
The DWARF plugin will search for DWARF-encoded debug information either in the input file, or a "companion" file (using a strategy similar to that of GDB), when some is found, will extract the following:
In addition, the DWARF plugin provides source-level debugging.
picture_search
picture_search is a plugin that allows you to search for, and inspect pictures that are embedded in the binary.
The key feature of the plugin is the "Search for pictures" action, available in the menu, that will scan the entire binary (or the selection if there is one) for so-called "magic" numbers of well-known image types (PNG, JPEG, ...), and present the results in a tabular fashion:
Note: at this point, pictures have not been decoded yet; the plugin has merely spotted what looks like the start of pictures. Decoding will only happen when triggering any of the following actions.
Double-clicking any row of that list will show the picture directly in IDA. Opening the context menu will reveal even more possibilities: open the picture in the OS's default viewer, save it, jump to its start address...
In addition to this very handy scanning feature, the plugin will add the "Open picture" action to the disassembly listing's context menu when the current position happens to be near data that matches the well-known image types' magic numbers.
- on : enable rust plugin for this session of IDA
- off : disable rust plugin for this session of IDA
The metadata parsed by the golang plugin falls under two main categories:
The package paths of functions and types are used to create folders. This analysis will occur upon `ev_newfile` (when a new file has been loaded) if Golang has been detected.
Actions
This action is useful to force a full search of the binary for Golang metadata. It will first attempt to parse a pclntab at the current address, if this is unsuccessful it will perform a full search of the binary for the pclntab's signature and parse it if found. In addition, it will also attempt to locate and parse the type information.
Calling Conventions
Golang has its own calling convention(s), denoted in IDA as `__golang`. In fact, Golang has two different calling conventions: a stack-based CC (abi0) and a newer register-based CC (abiinternal). The version of Golang and thus which calling convention to use will be automatically inferred from metadata structures; It is also controllable through the `force_regabi` command line option.
List of `-Ogolang` options
Command line options take precedence over config file options.
See cfg/golang.cfg for available configuration options.
Examples
forcing analysis and register-based calling convention
disabling the plugin
Dialog box
'cfg/dwarf.cfg' file presents in details all the options
List of '-Odwarf' options
- type information
- function names, prototypes, local variables
- global variables names & types
- off : disable the plugin for the current session
- import_lnnums=1 : import file name and line number into idb
-Orust:off
- if a Golang startup signature matches the entry point (PC-only)
- if the Golang plugin detects a Golang-specific segment name
- if the elf loader finds a "Go" note in the input file
- on PE files: if certain Golang symbol names or a Go build id signature is found
- function information (e.g. name, package, range) retrieved from the pclntab
- type information (e.g. name, package, layout, size) retrieved from the typelinks table
`golang:detect_and_parse` (Edit>Other)
force try to force the analysis
(no detection step needed)
off disable the plugin
no_rtypes do not import any types
rname_len2 force the reflect type name format to go1.17
and later (varint encoding: 1-10 bytes)
rname_len1 force the reflect type name format to before
go1.17 (2 bytes)
import_lnnums recover file names & line numbers from pclntab
no_func_end_from_pcval_tabs do not derive a function's end from pclntab
metadata
force_regabi[=on|=off] override calling convention version
`=off`: will force the stack-based CC
`=on`/no value: will force
the register-based CC
-Ogolang:force:force_regabi
-Ogolang:off
Global name : create global names based on DWARF informations
Functions : Create functions based on DWARF informations
Use function bounds : Uses DWARF to determine functions boundaries
Types (uncheck for speed) : Create types, needed for Apply calling
convention or Function prototype are definitive
Apply calling convention : DWARF will try and guess the calling convention
instead of using platform default calling
convention. Needed for Allow __usercall
Allow __usercall : If DWARF detects __usercall, allow to use it. If
not allowed, the default calling convention for
the platform will be used
Function prototypes are definitive: Decompiler will not try to change the
prototype if set. Use this with caution
Import file names/line numbers: Import all information
IDA Feeds
IDA Feeds
Starting with IDA 9.0, we introduced IDA Feeds (aka FLIRT Signature Manager), the tool designed to ease the application of new signatures through updatable libraries, (known as IDA FLIRT Signature Bundles), shipped alongside other IDA plugins just out-of-the-box.
What is IDA Feeds?
Ida Feeds helps you identify which signatures to apply when analyzing binary files, especially when you don't know which static libraries were linked to them. Rather than manually applying signatures, IDA Feeds automatically scans and applies many signatures in seconds. Just open the signature folder, allow IDA to scan and find the possible matches, and then bulk apply the suggested signatures.
IDA Feeds uses the , which are going to be regularly updated and released to keep you up to date with the newest recognizable signatures.
IDA Feeds configuration and setup
The proper configuration of the plugin is required to start using IDA Feeds and make it visible in the plugins list under Edit -> Plugins submenu.
Prerequisites
idalib configured properly (check and )
Downloaded the latest IDA FLIRT Signature Bundle. You can get it from our under SDK and utilities.
Install and activate your virtual environment
We recommend using IDA Feeds from within your Python virtual environment (venv). To do so, ensure you have created and activated your virtual environment before proceeding.
Linux & macOS
Create a Python virtual environment at your preferred location
Replace ~/.idapro/venv with your path.
Activate your virtual environment
Windows
Create a Python virtual environment at your preferred location
Replace .idapro\venv with your path.
Activate your virtual environment
Installing requirements/dependencies
Install requirements for Python modules from within your virtual environment.
Navigate to the plugin/ida_feeds folder within the IDA Pro installation directory and install the requirements.
Create symbolic link (optional)
Linux & OSX
Windows
After successfully performing these steps, IDA Feeds plugin should be visible in the Edit -> Plugins submenu and ready to try.
How to use IDA Feeds?
To use IDA Feeds, you need to first.
Go to the Edit -> Plugins -> IDA Feeds. IDA Feeds will open in a new Signature Tools subview.
In the Signature Tools window, click Open signatures folder and select the folder with the downloaded FLIRT signature bundle (1), or leave the preloaded signatures already provided with your IDA instance.
Select all or chosen signature files, and then click Run multi-core analysis (2).
Check the results and click Apply signatures to bulk apply (3) correct matches.
Borland RTTI descriptors plugin
Borland RTTI descriptors plugin
This plugin allows you to create/delete/view Borland RTTI descriptors.
These descriptors appear in programs written on BCC++ or Borland C++ Builder or Borland Delphi.
The plugin is available for 32 bits binaries for PE or OMF format.
Dialog box
Configuration
DYLD Shared Cache Utils
This plugin (nicknamed "dscu" for brevity) is essentially just an extension of the Mach-O loader. It allows you to manually load modules from a dyldcache that were not loaded when first opening the cache in IDA (the plugin is only activated after using the "single module" option for a dyldcache).
For a quick overview of the dscu functionality, see menu File>Load file>DYLD Shared Cache Utils.
Loading Modules
There are a few ways to manually load a module from the cache:
1) Use File>Load file>DYLD Shared Cache Utils>Load module... and choose which module to load
2) Right-click on an unmapped address in the disassembly, and select 'Load module <module name>'
3) Programatically:
Loading Sections
dscu also allows you to load a subset of a given module.
Any section from any of the dyldcache's submodules can be loaded individually. This is especially useful when analyzing Objective-C code, since often times it is convenient to only load Objective-C info from a given module without loading all of its code.
For example, if you see a pointer to a selector string that has not been loaded:
Right-click on "0x1AECFF7F9" and dscu will provide you with two options:
The UIKitCore module is huge, so perhaps you don't want to load the entire thing, but still want to clean up the disassembly. If you choose "Load UIKitCore:__objc_methname", dscu will load only these selector strings into the database:
This operation is much faster, and still provides a lot of benefit to the analysis.
- List RTTI descriptors : Displays the list of recognized RTTI
descriptors. IDA automatically recognizes
most descriptors. The list will include only
the descriptors specified by the 'RTTI type'
radiobuttons. You can also delete any
descriptor from list.
- List RTTI problems : Displays the list of problematic RTTI
descriptors. The list will include only the
descriptors specified by the 'RTTI type'
radiobuttons. You can also delete any
descriptor from list.
- Delete list of descriptors : Delete the whole list of RTTI descriptors.
- Delete list of problems : Delete the whole list of problematic RTTI
descriptors.
- Create C++ descriptor : Manually invoke creation of a C++ descriptor
at the current cursor location.
- Create Pascal descriptor : Manually invoke creation of a Pascal
descriptor at the current cursor location.
- Create Pascal or C++ descriptor : Manually invoke creation of a Pascal or
C++ descriptor at the current cursor
location. This action tries to create a
Pascal descriptor. If it fails, then it
tries to create a C++ descriptor.
- RTTI type radiobutton group : Controls which descriptors will appear in
the displayed lists.
Options are :
* Include C++
* Include Pascal
* Include both
- Create recursive : If this option is set, then IDA tries to create
descriptors recursively: if a created descriptor
refers to another unknown descriptor, then it will be
created and so on.
n = idaapi.netnode()
n.create("$ dscu")
n.supset(2, "/usr/lib/libobjc.A.dylib")
idaapi.load_and_run_plugin("dscu", 1)
ADRP X8, #0x1AECFF7F9@PAGE
ADD X1, X8, #0x1AECFF7F9@PAGEOFF ; SEL
MOV X0, X21 ; id
BL _objc_msgSend_0
Load UIKitCore:__objc_methname
Load UIKitCore
ADRP X8, #sel_alloc@PAGE ; "alloc"
ADD X1, X8, #sel_alloc@PAGEOFF ; SEL
MOV X0, X21 ; id
BL _objc_msgSend_0
node = idaapi.netnode()
node.create("$ dscu")
node.altset(3, 0x1AECFF7F9) # address can be any address in the section
idaapi.load_and_run_plugin("dscu", 2)
FLIRT Signature Bundle
FLIRT Signature Bundle
With FLIRT Signature Bundle, designed to be used with IDA Feeds (aka FLIRT Signature Manager), you can analyze thousands of signatures and bulk apply them to your binary.
The bundle contains signatures for modern languages like Golang and Rust, as well as updates for classic compilers. The latest version of the FLIRT Signature Bundle can be downloaded from My Hex-Rays portal under SDK and utilities.
Flirt Signature Bundles will be regularly updated and released independently whenever there is a new compiler, language, or library release.
Released versions
2024/09/12 FLIRT Signature Bundle
Golang
Versions: stable versions from 1.10.0 to 1.23
Operating Systems: Linux, Windows, MacOS
Architectures: arm64 (Windows, Linux, MacOS), arm (Windows, Linux, MacOS), x86 (Windows, Linux) , x86-64 (Windows, Linux)
C/C++
Windows (MSVC):
Architectures: arm, arm64, i386, amd64
Packages: ATL, CTL, MFC, Windows SDK 10, Windows SDK 11
Objective-C Analysis Plugin
The objc plugin performs Objective-C specific analysis on the database.
For an overview of what the plugin can do, see the menu options in Edit>Other>Objective-C, or the config options in objc.cfg.
Type Information
The bulk of the plugin's work is done at file load time, when it will parse all Objective-C type information embedded in the binary, and use this to create tinfo_t structures for all known classes and construct prototypes for all known methods.
This analysis can be invoked manually at any time with:
Or:
You can also disable objc analysis at load time with command line option:
The plugin will also perform Objective-C analysis during decompilation.
When a function is decompiled, the plugin will analyze any calls to objc_msgSend, and use the arguments to determine if objc_msgSend will ultimately invoke one of the methods in the current database.
If such a situation is detected, the plugin will replace the call to objc_msgSend with a call to the target method, and add an xref to the method. This is done in the hopes that continued use of the decompiler will improve call graphs for Objective-C binaries.
If the target method has type information, then the return type can be used to refine the types of local variables in the pseudocode, which in turn could lead to more method calls being detected, and so on.
You can disable objc analysis in the pseudocode with command line option:
Or uncheck the "Enable decompiler plugin for Objective-C" option in:
Debugging
objc also provides tools for dynamic analysis.
During debugging, you can analyze objc info for a specific library by right-clicking in the Modules window and selecting "Load debug info".
This operation can also be performed programmatically with:
If you prefer that objc does not perform analysis during "Load debug info", (say if DWARF information is available for a module and you prefer that), you can disable this functionality with command line option:
Or by unchecking the "Enable SIP for Objective-C" option in:
Step Into Message
The plugin also implements a "step into" debugger action for Objective-C.
If you use this action before a call to objc_msgSend, objc will try to calculate the address of method that is being invoked, and break at the method address rather than step into the objc_msgSend function itself.
You can perform this action with shortcut:
Or via the menu option:
Or programmatically with:
This action can be very useful, but you must be careful. When invoked, the action will automatically run to the address of objc_msgSend, analyze its arguments, then continue to the target method.
If there is no subsequent call to objc_msgSend in the program, you will lose control of the process. It is best to use this action only when you are sure that IP is in the vicinity of an objc_msgSend call.
The analysis involves identifying NSConcreteStackBlock instances on the stack, and creating a specialized Block_layout structure to apply to the function's stack frame.
The end result transforms the following sequence of statements:
Already this cleans up the analysis quite a lot, but more importantly this new Block_layout_BF60 structure will be applied to the prototype of __block_invoke, which can heavily improve the pseudocode.
Block analysis can be performed on the database with:
Or programmatically with:
You can also perform block analysis on a specific function:
Or with shortcut:
Or programmatically:
These actions work in both the disassembly and pseudocode windows, but note that you must refresh the pseudocode with F5 for the changes to take full effect.
Also, please note that this feature makes use of the microcode in the hexrays SDK, so you must have the decompiler in order to use it.
NSConcreteGlobalBlock
Global blocks (i.e. blocks that don't make use of local variables) are much easier to analyze, and simply involve identifying references to NSConcreteGlobalBlock in the __const segment.
Global blocks are analyzed automatically at load time, but the analysis can be performed manually at any time with:
Or:
Command Line
Here's a summary of the command-line arguments that can be passed to objc:
objc features can be enabled or disabled using '+' or '-', followed by one of the following characters:
For example, -Oobjc:+v:+l:-s will enable verbose and lazy mode, and will disable the objc SIP.
n = idaapi.netnode()
n.create("$ objc")
n.altset(1, 0xBF60, 'R') # the address can be any address within the function
idaapi.load_and_run_plugin("objc", 5)
Edit>Other>Objective-C>Re-analyze global block functions
Patfind plugin makes it possible to automatically find functions in binary files.
It relies on bit pattern definitions for typical function starts and function ends.
Those bit patterns are defined in XML files, based on Ghidra's function patterns format. A collection of bit pattern files is provided for the commonly used CPU architectures.
It is possible to add new architectures by simply adding a new XML file, just like the other XML files.
It's also possible to add, remove or change existing patterns for better matching.
Configuration
'cfg/patfind.cfg' file presents all the options
The config file also contains the documentation on how to use or change the XML pattern files.
If desired, new XML files can be added to the 'cfg/ghidra_patterns/' directory.
'-Opatfind' command line switches can be used to select the type of run differently for this session of IDA.
List of options
Examples
autorun=0 : don't automatically search for bit pattern
autorun=1 : search for bit pattern only on binary like files
autorun=2 : search for bit pattern on any input file