IDA Domain API

repository·main·Indexed 43 days ago

https://github.com/hexrayssa/ida-domain

An open-source Python API providing domain-focused abstractions for reverse engineering tasks in IDA Pro. Built on top of the IDA Python SDK, it treats functions, types, and cross-references as first-class citizens. Requires IDA Pro 9.1.0 or later and Python 3.10 or higher. Supports both standalone library mode and IDA GUI mode.

Tokens
46.1K
Snippets
140
Records
201
Agent score
54%

What's inside IDA Domain

  1. What is the IDA Domain API?

    main

    The IDA Domain API is an open-source Python API designed to provide domain-focused abstractions for reverse engineering tasks in IDA. It treats core concepts like functions, types, and cross-references (xrefs) as first-class citizens to make scripting more natural and consistent.

    Key Characteristics:

    • Complementary to IDA Python SDK: It sits on top of the existing SDK. You can use both side-by-side, combining the Domain API's simplicity with the SDK's full flexibility.
    • Pure Python: No compilation is required, and it works with modern Python versions.
    • Independently Versioned: You can upgrade or pin versions independently of IDA itself.
    • Compatibility Requirement: Requires IDA Pro 9.1.0 or later.
  2. Understand the IDA Domain API mental model

    main

    The IDA Domain API (ida_domain) is a Pythonic interface designed to replace the low-level IDA Python SDK. It shifts from a global-state model to a Dependency Injection model.

    Key Concepts

    • Explicit Dependencies: Unlike the old SDK which relies on implicit global state, every Domain API function requires a db: Database handle as its first argument. This allows for better testability (via mocking) and the potential for parallel database processing.
    • Organized Namespaces: Functionality is grouped into logical namespaces (e.g., db.functions, db.bytes, db.xrefs) rather than being scattered across various idaapi, idc, and idautils modules.
    • Type-Safe Enums: Use Domain API enums (e.g., FunctionFlags.THUNK) instead of the old SDK constants (e.g., idaapi.FUNC_THUNK).
    • Function Objects: While the old API often returned raw addresses (ea), the Domain API frequently returns rich objects (like function objects) that contain the address as a property (e.g., f.start_ea).
    # Before (implicit global state)
    def get_functions():
        for ea in idautils.Functions():
            f = idaapi.get_func(ea)
            yield f
    
    # After (explicit dependency injection)
    def get_functions(db: Database):
        for f in db.functions.get_all():
            yield f
  3. Use IDA Domain alongside the IDA Python SDK

    main

    The IDA Domain API is designed to be fully compatible with the standard IDA Python SDK. You can use ida_domain for high-level domain analysis and fall back to native ida_ modules (like ida_funcs, ida_name, etc.) when you need specific low-level SDK functionality. This allows you to use IDA Domain objects (like a function object) and pass their attributes (like start_ea) directly into SDK functions.

    import ida_domain
    import ida_funcs
    
    db = ida_domain.Database()
    db.open('/path/to/your/database.idb')
    
    # Iterate using ida_domain and call IDA Python SDK functions
    for i, func in enumerate(db.functions.get_all()):
        print(ida_funcs.get_func_name(func.start_ea))
  4. How to access IDA Domain entities

    main

    The IDA Domain API is structured hierarchically. You must first open a Database instance. Once the database is open, all other domain entities (such as functions, segments, entries, etc.) are accessible as properties of that database handle.

    Core entities available via the database handle include:

    • functions: Function analysis and manipulation
    • segments: Memory segment operations
    • entries: Entry point management
    • flowchart: Control flow graph operations
    • instructions: Instruction-level analysis
    • types: Type information and management
    • xrefs: Xref analysis
    • names: Symbol name management
    • comments: Comment management
    • strings: String detection and analysis
    • bytes: Raw byte manipulation
    • operands: Operand analysis
    • heads: Address head management
    • hooks: Event handling
    • signature_files: FLIRT signature file operations
    db = Database()
    db.open('/path/to/your/database.idb')
    
    # Access entities through the database handle
    functions = db.functions.get_all()
    segments = db.segments.get_all()
    entries = db.entries.get_all()
  5. Using IDA Domain alongside the IDA Python SDK

    main
    The IDA Domain API is designed to complement, not replace, the standard IDA Python SDK. You can use both libraries together in the same script or plugin. This allows you to use the high-level, domain-oriented abstractions of ida-domain while still accessing low-level SDK features via the standard idaapi or idapython modules when necessary.
  6. Using IDA Domain in plugins and its limitations

    main

    The ida-domain package can be used both inside and outside of the IDA environment.

    • Inside IDA: When running within an IDA plugin or the IDA Python console, the API works with the currently opened IDB (IDA Database).
    • Outside IDA: It can be used transparently in external scripts, provided the IDA environment is correctly configured/registered.
  7. Run IDA Domain in IDA GUI Mode

    main

    When running scripts from within the IDA GUI (e.g., via the IDA console), you do not need to provide a file path. Call Database.open() with no arguments to obtain a handle to the currently active database.

    from ida_domain import Database
    # Get handle to the currently open database
    db = Database.open()
  8. Use the `ida_domain.xrefs` module for cross-references

    main
    The ida_domain.xrefs module provides an interface for interacting with cross-references (Xrefs) within an IDA Pro database. This allows you to navigate and analyze how different parts of the binary (such as functions, data, or instructions) reference one another.
  9. Migrate entry point enumeration to EntryInfo

    main

    The Domain API replaces tuple-based entry enumeration with db.entries.get_all(), which yields EntryInfo dataclass objects. Use the properties of EntryInfo instead of manual unpacking.

    EntryInfo fields:

    • ordinal: export ordinal number
    • address: address of entry point
    • name: entry point name
    • forwarder_name: forwarder name (or empty string)

    Use entry.has_forwarder() to check for forwarders.

    # After migration
    def extract_exports(db: Database):
        for entry in db.entries.get_all():
            if entry.has_forwarder():
                yield Export(entry.forwarder_name), entry.address
            else:
                yield Export(entry.name), entry.address
  10. Map IDA Python SDK calls to IDA Domain API

    main

    When migrating from the low-level SDK to the Domain API, use the following mappings for common operations:

    Database Properties

    Old APINew API
    ida_nalt.retrieve_input_file_md5()db.md5
    ida_nalt.retrieve_input_file_sha256()db.sha256
    idaapi.get_imagebase()db.base_address
    ida_loader.get_file_type_name()db.format
    idaapi.get_inf_structure().procnamedb.architecture
    idaapi.get_inf_structure().is_64bit()db.bitness == 64

    Function Operations (db.functions)

    Old APINew API
    idautils.Functions()db.functions.get_all()
    idautils.Functions(start, end)db.functions.get_between(start, end)
    idaapi.get_func(ea)db.functions.get_at(ea)
    idaapi.get_func_name(ea)db.functions.get_name(f)
    f.flags & idaapi.FUNC_THUNKdb.functions.get_flags(f) & FunctionFlags.THUNK

    Byte Operations (db.bytes)

    Old APINew API
    idc.get_bytes(ea, count)db.bytes.get_bytes_at(ea, count)
    idc.is_loaded(ea)db.bytes.is_value_initialized_at(ea)
    ida_bytes.bin_search()db.bytes.find_binary_sequence(seq, start, end)

    Segment Operations (db.segments)

    Old APINew API
    idaapi.get_segm_qty()db.segments.get_all()
    idaapi.getseg(ea)db.segments.get_at(ea)
    idc.get_segm_end(ea)db.segments.get_at(ea).end_ea

    Instruction Operations (db.instructions)

    Old APINew API
    idautils.DecodeInstruction(head)db.instructions.get_at(head)
    insn.get_canon_mnem()db.instructions.get_mnemonic(insn)
    idc.GetDisasm(ea)db.instructions.get_disassembly(insn)
    idaapi.is_ret_insn(insn)db.instructions.breaks_sequential_flow(insn)

    Cross-Reference Operations (db.xrefs)

    Old APINew API
    idautils.CodeRefsTo(ea, True)db.xrefs.code_refs_to_ea(ea)
    idautils.CodeRefsFrom(ea, False)db.xrefs.code_refs_from_ea(ea, flow=False)
    idautils.DataRefsFrom(ea)db.xrefs.data_refs_from_ea(ea)
  11. Access LLM-friendly documentation via llms.txt

    main

    The project provides documentation in a format optimized for Large Language Models (LLMs) following the llmstxt.org convention. This allows AI coding agents and LLMs to ingest the project's documentation more efficiently.

    You can access these files at:

    • /llms.txt: A concise version of the documentation.
    • /llms-full.txt: A comprehensive version containing the full documentation.