Getting Started with C++ SDK

Getting started with C++ SDK

IN PROGRESS

Intro

The IDA C++ SDK provides set of tools to interact with IDA Pro's disassembler, allowing you to navigate, analyze, and manipulate various elements such as functions, instructions, and data. This guide is designed to accelerate your learning curve with the IDA C++ SDK and kickstart your development journey, assuming you are already familiar with IDA Pro and its basic usage.

How This Guide is Structured

First, check Basics for core concepts and commonly used variables. Next, explore our Code Snippets to see examples of commonly used functions. Once you're comfortable with these, you can delve into more complex Examples that showcase advanced usage of the SDK.

C++ SDK Installation

You can download the latest C++ SDK Zip file from our Download Center in My Hex-Rays portal. The SDK package includes in the top-level directory a README file with instructions on how to install it on your local machine and additional README files in other directories for processor modules templates, loaders and so on.

Basics

Common Types and Constants

One of the most extensivly used type is ea_t, commonly used to represent an effective address (EA) within a binary.

Common header files and namespaces

The IDA C++ SDK is organized into header files containing various classes and functions. Below is a short desription of commonly used IDA SDK header files:

  • pro.h: This is the first header included in the IDA project. It defines the most common types, functions, and data. It also contains compiler- and platform-related definitions.

  • ida.hpp: In this file the 'inf' structure is defined: it keeps all parameters of the disassembled file.

  • idp.hpp: The 'main' header file for IDP modules. Contains definition of the interface to IDP modules. The interface consists of 2 structures: processor_t - description of processor asm_t - description of assembler Each IDP has one processor_t and several asm_t structures.

  • loader.hpp: Definitions of IDP, LDR, and PLUGIN module interfaces. This file also contains:

    • functions to load files into the database

    • functions to generate output files

    • high level functions to work with the database (open, save, close)

  • ua.hpp: Functions that deal with the disassembling of program instructions. Disassembly of an instruction is made in three steps:

    • analysis

    • emulation

    • conversion to text

  • kernwin.hpp: Defines the interface between the kernel and the UI. Some string processing functions are also kept in this header.

  • idd.hpp: Debugger plugin API for debugger module writers. Contains definition of the interface to IDD modules.

  • bytes.hpp: Functions and definitions used to describe and manipulate each byte of the disassembled program. Information about the byte includes associated features (comments, names, references, etc), data types (dword, qword, string literal, etc), instruction operands, status (mapped, loaded, patched, etc), among others.

  • netnode.hpp: Functions that provide the lowest level public interface to the database. Modules can use this to keep some private information in the database. A description of the concept is available in the header file itself.

  • allins.hpp: List of instructions available from all processor modules.

  • auto.hpp: Auto-analysis related functions.

  • compress.hpp: Data compression functions.

  • config.hpp: Functions that deal with configuration options and files.

  • dbg.hpp: Contains functions to control the debugging of a process.

  • diskio.hpp: File I/O functions for IDA. You should not use standard C file I/O functions in modules. Use functions from this header, pro.h, and fpro.h instead.

  • entry.hpp: Functions that deal with entry points to the program being disassembled.

  • enum.hpp: Enumeration type management (assembly level types).

  • err.h: Thread safe functions that deal with error codes.

  • expr.hpp: Functions that deal with C-like expressions, external languages, and the built-in IDC language.

  • fixup.hpp: Functions that deal with fixup (relocation) information.

  • fpro.h: System independent counterparts of file I/O functions. These functions do check errors but never exit even if an error occurs. They return extended error code in qerrno variable. NOTE: You must use these functions instead of the C standard I/O functions.

  • frame.hpp: Routines to manipulate function stack frames, stack variables, register variables and local labels.

  • funcs.hpp: Routines for working with functions within the disassembled program. This file also contains routines for working with library signatures (e.g. FLIRT).

  • gdl.hpp: Low level graph drawing operations.

  • graph.hpp: Graph view management.

  • help.h: Help subsystem. This subsystem is not used in IDP files. We put it just in case.

  • ieee.h: IEEE floating point functions.

  • intel.hpp: Header file from the IBM PC module. For information only. It will not compile because it contains references to internal files!

  • lex.hpp: Tools for parsing C-like input.

  • lines.hpp: High level functions that deal with the generation of the disassembled text lines.

  • nalt.hpp: Definitions of various information kept in netnodes. These functions should not be used directly since they are very low level.

  • moves.hpp: Functions and classes related to location history.

  • name.hpp: Functions that deal with names (setting, deleting, getting, validating, etc).

  • offset.hpp: Functions that deal with offsets.

  • problems.hpp: Functions that deal with the list of problems.

  • prodir.h: Low level functions to find files in the file system. It is better to use enumerate_files2() from diskio.hpp.

  • pronet.h: Network related functions.

  • range.hpp: Contains the definition of the 'range_t' class. This is a base class used by many parts of IDA, such as the 'segment_t' and 'segreg_range_t' (segment register) classes.

  • registry.hpp: Registry related functions. IDA uses the registry to store global configuration options that must persist after IDA has been closed.

  • segment.hpp: Functions that deal with program segmentation.

  • segregs.hpp: Functions that deal with the segment registers. If your processor doesn't use segment registers, then you don't need this file.

  • strlist.hpp: Functions that deal with the strings list.

  • struct.hpp: Structure type management (assembly level types).

  • typeinf.hpp: Describes the type information records in IDA.

  • xref.hpp: Functions that deal with cross-references.

All functions usable in the modules are marked by the "ida_export" keyword.

Here are the most common namespaces to start with:

idc: This namespace provides access to IDC scripting functions via C++ SDK. It is often used for common tasks like setting comments or modifying bytes.

idati: This namespace is used for interacting with type information, such as function signatures and type definitions.

idaapi: This namespace contains core classes and functions for interacting with IDA's API, including functions for handling UI elements, plugins, and database access.

idamisc: This namespace includes utility functions for various tasks, such as working with the address space and disassembly.

Code Snippets

Here are common functions and examples grouped by topics:

Part 1: Addresses and Names

Get the Current Address

ea_t ea = get_screen_ea();  // Get the current address
printf("Current address: %llx\n", ea);

Jump to the address

jumpto(0x401000);  // Jump to address 0x401000

Get the Minimum and Maximum Address in IDB

ea_t min_ea = get_inf_attr(INF_MIN_EA);
ea_t max_ea = get_inf_attr(INF_MAX_EA);

List All Instruction Addresses

for (ea_t ea = get_segm_by_name("CODE"); ea != BADADDR; ea = get_next_head(ea, badaddr)) {
    printf("Instruction address: %llx\n", ea);
}

Get the Name Associated with a Given Address

const char* name = get_name(0x100000da0);
printf("Name: %s\n", name);

Get the Address Associated with a Given Name

ea_t address = get_name_ea(0, "_main");
printf("Address: %llx\n", address);

Part 2: Reading and Writing Data

Reading Bytes and Words

u8 byte_value = get_byte(0x401000);  // Read a byte at address 0x401000
u16 word_value = get_word(0x401002);  // Read a word (2 bytes) at address 0x401002
u32 dword_value = get_dword(0x401004);  // Read a double word (4 bytes) at address 0x401004

printf("Byte: %x, Word: %x, Dword: %x\n", byte_value, word_value, dword_value);

Writing Bytes and Words

patch_byte(0x401000, 0x90);  // Write a byte (0x90) at address 0x401000
patch_word(0x401002, 0x9090);  // Write a word (0x9090) at address 0x401002
patch_dword(0x401004, 0x90909090);  // Write a double word (0x90909090) at address 0x401004

Part 3: Comments

Add a Regular or Repeatable Comment

set_cmt(0x401000, "This is a comment", false);  // Add a regular comment at address 0x401000
set_cmt(0x401000, "This is a repeatable comment", true);  // Add a repeatable comment at address 0x401000

Get a Regular Comment

const char* comment = get_cmt(0x401000, false);  // Get a regular comment at address 0x401000
printf("Comment: %s\n", comment);

Part 4: Segments

Get a Segment Name

const char* seg_name = get_segm_name(ea);
printf("Segment name: %s\n", seg_name);

Iterate Through All Segments

for (seg_t* seg = get_first_seg(); seg != nullptr; seg = get_next_seg(seg)) {
    printf("Segment name: %s\n", get_segm_name(seg->start_ea));
}

Part 5: Functions

Create and Delete Function

add_func(0x401000, 0x401050);  // Create a function starting at 0x401000 and ending at 0x401050
del_func(0x401000);  // Delete the function at 0x401000

Get the Name of the Function

const char* func_name = get_func_name(0x401000);
printf("Function name: %s\n", func_name);

Iterate Through All Functions

for (func_t* func = get_first_func(); func != nullptr; func = get_next_func(func)) {
    printf("Function address: %llx, name: %s\n", func->start_ea, get_func_name(func->start_ea));
}

Part 6: Navigating Cross-References (Xrefs)

List Cross-References to an Address

for (xref_t* xref = get_first_xref_to(0x401000); xref != nullptr; xref = get_next_xref_to(xref)) {
    printf("Xref to 0x401000 from %llx\n", xref->from);
}

List Cross-References from an Address

for (xref_t* xref = get_first_xref_from(0x401000); xref != nullptr; xref = get_next_xref_from(xref)) {
    printf("Xref from 0x401000 to %llx\n", xref->to);
}

Part 7: UI

Set Background Color of a Function

set_color(0x401000, CIC_ITEM, 0x007fff);  // Set background color for the function starting at address 0x401000

Display a Custom Dialog

msg("This is a custom message dialog. Good luck with learning the IDA C++ SDK!\n");

Complex Script Examples

If you’re comfortable with the basics, explore advanced examples included in the SDK itself. These examples often leverage multiple modules to accomplish more sophisticated tasks.

What’s Next?

Explore our tutorial on how to create your first custom plugin in IDA using C++.

Last updated