LogoLogo
IDA 9.0
IDA 9.0
  • Welcome to Hex-Rays docs
    • What's new?
  • Getting Started
    • Install IDA
    • Licensing
    • Basic Usage
    • What's next?
  • User Guide
    • User Interface
      • Menu Bar
        • File
          • Load file
          • Script File
          • Script command
          • Produce output files
          • Invoke OS Shell
          • Take database snapshot
          • Save database
          • Save database as...
          • Abort IDA
          • Exit IDA
        • Edit
          • Export data
          • Undo an action
          • Redo an action
          • Clear undo history
          • Disable undo
          • Convert to instruction
          • Convert to data
          • Convert to string literal
          • Convert to array
          • Undefine a byte
          • Give Name to the Location
          • Operand types
            • Offset
            • Number
            • Perform en masse operation
            • Convert operand to character
            • Convert operand to segment
            • Complex Offset Expression
            • Convert operand to symbolic constant (enum)
            • Convert operand to stack variable
            • Change operand sign
            • Bitwise negate operand
            • User-defined operand
            • Set operand type
          • Comments
          • Functions
          • Structs
          • Segments
          • Patch core
          • Other
            • Rename Any Address
          • Plugins
        • Jump
          • Center current line in window
          • Problems List
        • Search
          • REGULAR EXPRESSION SYNTAX SUMMARY
        • View
          • Open subviews
          • Graphs
          • Message Window
          • Arrows window
          • Database snapshot manager
          • Highlighting identifiers
          • Browser options
          • Lumina options
          • Assembler level and C level types
          • C++ type details
          • Bookmarks window
          • Calculator
          • View segment registers
          • View Internal Flags
          • Hide
          • Unhide
          • Del hidden range
          • Hide all items
          • Unhide all items
          • Setup hidden items
        • Debugger
          • Debugger window
          • Process Control
            • Start process
            • Process options
            • Pause process
            • Terminate process
            • Step into
            • Step over
            • Run to cursor
            • Run until return
            • Attach to process
            • Detach from process
            • Set current ip
            • Show application screen
          • Breakpoints
          • Watches
          • Tracing
          • Source code view
            • Watch view (source level)
          • Process Memory
            • Take memory snapshot
            • Manual memory regions
            • Refresh memory
          • Thread list
          • Module list
          • Stack trace
          • Exceptions
          • Debugger options
          • Switch debugger
        • Lumina
        • Options
          • Low & High Suspicious Operand Limits
        • Windows
          • Rename a stack variable
          • Miscellanous Options
          • Environment variables
          • Reset Hidden Messages
          • Various dialog help messages
        • List of all menu options
      • Desktops
      • Command line
      • How To Use List Viewers in IDA
      • Licenses
        • Apache License for Ghidra
        • Apache License for LLVM
        • Common Public License Version 1.0
        • APPLE PUBLIC SOURCE LICENSE
        • PCRE2 LICENCE
        • GNU Lesser General Public License v2.1 for libiberty
      • Database conversion from idb to i64
    • Disassembler
      • Interactivity
      • Background Analysis
      • Graph view
        • Graphing tutorial
      • Proximity view
      • Navigation
        • Anchor
        • How to Enter a Segment Value
        • How to Enter a Number
        • How to Enter an Identifier
        • How to enter text
        • How to Enter an Address
      • Disassembly Gallery
        • Philips 51XA-G3
        • 6502 and 65C02 Disassembler
        • 6301, 6303, 6800, 6801 and 6803 Disassembler
        • 68040, Amiga
        • 6805 Disassembler
        • 6808 Disassembler
        • 6809 OS9 Flex Disassembler
        • 6809 Disassembler
        • 6811 Disassembler
        • 68HC12 Disassembler
        • 68HC16 Disassembler
        • 68k Amiga Disassembler
        • 68k Mac OS
        • 68k Palm Pilot
        • Unix COFF
        • NEC 78k0 and 78k0s Processor
        • 80196 Processor
        • 8051 Disassembler
        • Analog Devices 218x.
        • Alpha Processor – NT COFF
        • Alpha Processor – Unix ELF
        • Android ARM Executables (.elf)
        • ARC Processor
        • ARM Processor EPOC App
        • ARM Processor EPOC PE File
        • ARM Processor EPOC ROMFile
        • EPOC SIS File Handler
        • ARM Processor iOS (iPhone): Unlock
        • ARM Processor iOS (iPhone): Objective-C metadata
        • ARM Processor iOS (iPhone): Objective-C Instance variables
        • ARM Processor iOS (iPhone): Parameter Identification & Tracking (PIT)
        • ARM Processor iOS (iPhone): Start
        • ARM Processor iOS (iPhone): Switch statements
        • ARM Processor iOS (iPhone): C++ signatures
        • ARM Processor iOS (iPhone): Write
        • ARM Processor: Linux ELF
        • ARM Processor: AOF SDK
        • ARM Processor: Windows CE COFF Format
        • ARM Processor: Windows CE PE Format
        • ATMEL AVR Disassembler
        • C166 Processor
        • C166 Processor with ELF file
        • Rockwell C39
        • Microsoft .NET CLI Disassembler. VisualBasic library
        • CR16
        • Android Dalvik Executables (.dex)
        • Microsoft .NET CLI Disassembler
        • DSP56K
        • Fujitsu FR (.elf)
        • Gameboy
        • H8 300: COFF FILE Format
        • H8 300s: COFF FILE Format
        • H8 500
        • HPPA Risc Processor: HP-UX SOM
        • i51
        • i860
        • Intel i960
        • Intel IA-64 (Itanium)
        • Java Bytecode
        • Angstrem KR 1878
        • Renesas/Hitachi M16C
        • Renesas/Hitachi M32R
        • M740
        • M7700
        • M7900
        • MIPS Processor: Nintendo N64
        • MIPS R5900 Processor : Sony bin
        • MIPS Processor: Sony ELF
        • MIPS Processor: Sony PSX
        • MIPS Processor: Sony PSX
        • MIPS Processor: Unix COFF File Format
        • MIPS Processor: Unix ELF File Format
        • MIPS Processor: Windows CE PE File Format
        • MIPS Processor: Windows CE PE2 File Format
        • Panasonic MN102
        • Atmel OAK DSP
        • 80×86 Architecture: DOS Extender
        • 80×86 Architecture: Watcom Runtime
        • 80×86 Architecture: Geos APP
        • 80×86 Architecture: Geos DRV
        • 80×86 Architecture: Geos LIB
        • 80×86 Architecture: GNU COFF Format
        • 80×86 Architecture: OS/2 Linear Executable Format
        • 80×86 Architecture: Netware NLM
        • 80×86 Architecture: QNX Executable
        • 80×86 Architecture: Watcom Runtime
        • 80×86 Architecture: Windows OMF
        • 80×86 Architecture: Windows Portable Executable Format
        • 80×86 Architecture: Windows Virtual Device Driver
        • 80×86 Architecture: Windows 16 bits DLL
        • X-Box Disassembler
        • PDP 11: SAV File
        • PIC
        • PIC 12xx
        • Power PC AIF ECOFF file Format
        • Power PC Linux ELF
        • Mac OS PEF File
        • Mac OS X File
        • Windows NT PE File
        • Hitachi SH-1 Processor
        • Hitachi SH-3 Processor: Windows CE COFF format
        • Hitachi SH-3 Processor: Windows CE PE format
        • Hitachi SH-4 Processor: ELF File Format
        • Hitachi SH-4 Processor: Windows CE PE File Format
        • Super Nintendo Entertainement System (SNES)
        • SPARC Solaris COFF
        • SPARC Solaris ELF
        • SPARC Sun ELF
        • SPARC Sun ELF SO
        • ST 20C4
        • ST 7
        • ST 9
        • Toshiba TLCS 900
        • TMS 320c2 COFF
        • TMS 320c5
        • TMS 320c54
        • TMS 320c6 COFF File Format
        • TRICORE
        • SunPlus unSP
        • NEC V850
        • Z180 COFF File Format
        • Z380 COFF File Format
        • Z8
        • Z80
      • Supported processors
      • Supported file formats
        • Windmp file loader
      • Bitfields
        • Bit Fields tutorial
      • Structures tutorial
      • Union tutorial
      • Variable length structures tutorial
      • Data types, operands and constructs
      • Packed executables
    • Decompiler
      • Prerequisites
      • Quick primer
      • Exception handler
      • Introduction to Decompilation vs. Disassembly
        • Comparisons of ARM disassembly and decompilation
        • Comparisons of PowerPC disassembly and decompilation
        • Comparisons of MIPS disassembly and decompilation
        • Hex-Rays v7.4 vs. v7.3 Decompiler Comparison Page
        • Hex-Rays v7.3 vs. v7.2 Decompiler Comparison Page
        • Hex-Rays v7.2 vs. v7.1 Decompiler Comparison Page
      • Interactive operation
        • Rename
        • Set type
        • Set number representation
        • Edit indented comment
        • Edit block comment
        • Hide/unhide C statements
        • Split/unsplit expression
        • Force call type
        • Set call type
        • Add/del variadic arguments
        • Del function argument
        • Add/delete function return type
        • Jump to cross reference
        • Jump to cross reference globally
        • Generate HTML file
        • Mark/unmark as decompiled
        • Copy to assembly
        • Show/hide casts
        • Reset pointer type
        • Convert to struct *
        • Create new struct type
        • Split variable
        • Select union field
        • Jump to paired paren
        • Collapse/uncollapse item
        • Map to another variable
      • Batch operation
      • Configuration
      • Third party plugins
      • Floating point support
      • Support for intrinsic functions
      • Overlapped variables
      • gooMBA
      • Failures and troubleshooting
      • FAQ
      • Limitations
      • Tips and tricks
    • Debugger
      • Instant debugger
      • Remote debugging
        • Remote iOS Debugger
        • Android debugger
        • Dalvik debugger
        • Remote GDB Debugger
          • Remote GDB Debugger options
          • Debugging with gdbserver
          • Debugging with VMWare
          • Debugging with OpenOCD
          • Debugging with QEMU
          • External programs and GDB Debugger
          • Debugging code snippets with QEMU
        • PIN debugger
          • Building the PIN tool
          • Connecting a remote PIN tool instance from IDA
          • PIN support for MacOSX
        • Replayer debugger
        • Bochs debugger
          • Bochs Disk Image operation mode
          • Bochs IDB operation mode
          • Bochs PE operation mode
          • Bochs debugger FAQ
      • Local debugging
        • WinDbg Debugger
        • Linux debugger
        • Intel/ARM macOS debugger
      • Debugger tutorials
        • Debugging Dalvik Programs
        • IDA Win32 Local Debugging
        • IDA Linux Local Debugging
        • IDA Linux to Win64 Debugging
        • IDA Win32 to Linux Debugging
        • Debugging Mac OSX Applications with IDA Pro
        • Debugging iOS Applications using CoreDevice (iOS 17 and up)
        • Debugging iOS Applications with IDA Pro
        • Debugging Linux Applications locally
        • Debugging Linux/Windows Applications with PIN Tracer module
        • Debugging Windows Applications with IDA Bochs Plugin
        • Debugging Windows Applications with IDA WinDbg Plugin
        • Using the Bochs debugger plugin in Linux
        • Debugging Windows Kernel with VMWare and IDA WinDbg Plugin
        • Debugging Linux Kernel under VMWare using IDA GDB debugger
        • Windows Debugger Hub
        • Linux Debugger
        • Debugging a Windows executable locally and remotely
        • Debugging the XNU Kernel with IDA Pro
        • Remote debugging with IDA Pro
        • IDA Scriptable Debugger: overview
          • IDA Scriptable Debugger: scriptability
        • Debugging code snippets with QEMU debugger (a la IDA Bochs debugger)
        • Trace Replayer and managing traces
        • Using IDA Pro's tracing features
        • Working with PIN
        • Appcall
    • Creating Signatures
      • FLIRT
        • IDA F.L.I.R.T. Technology: In-Depth
        • Generate FLIRT signature file
        • Supported Compilers
          • Turbo Pascal
          • Delphi
      • Makesig
    • Creating Type Libraries
      • IDAClang
      • TILIB
    • Configuration
      • Configuration files
      • Command line switches
      • Keyboard macros
      • UI/Fonts/Themes
      • Shortcuts
      • Customizing IDA
      • CSS-based styling
    • Teams
      • IDA Teams Licenses
      • Diffing and Merging Databases with IDA Teams
      • Teams lc command reference manual
      • hv command reference manual
      • Hex-Rays Vault’s visual client user manual
    • Lumina
      • lc command reference manual
    • Plugins
      • Open Plugin Architecture
      • Plugin options
      • Plugins Shipped with IDA
        • Swift plugin
        • Golang plugin
        • Rust plugin
        • picture_search
        • Objective-C Analysis Plugin
        • DYLD Shared Cache Utils
        • Borland RTTI descriptors plugin
        • DWARF plugin
        • Patfind plugin
        • IDA Feeds
          • FLIRT Signature Bundle
      • Plugin Contest
      • How to write your own plugin?
    • Helper Tools
    • idalib
  • Developer Guide
    • C++ SDK
      • Getting Started with C++ SDK
      • C++ SDK Reference
      • Using the Decompiler SDK: Decompiler plugin
      • C++ SDK examples
      • How to create a plugin in C++?
      • C++ SDK Porting Guide from IDA 8.x to 9.0
    • IDAPython
      • Getting started with IDAPython
      • IDAPython API Reference
      • IDAPython examples
      • How to create a plugin in IDAPython?
      • IDAPython Porting Guide from IDA 8.x to 9.0
    • IDC
      • Core concepts
        • Expressions
        • Statements
        • Functions
        • Variables
        • Constants
        • Exceptions
        • Classes
        • Predefined symbols
        • loader_input_t class
        • Slices
      • IDC API Reference
        • Index of debugger related IDC functions
        • Alphabetical list of IDC functions
          • is_member_id
          • load_type
          • get_member_by_idx
          • get_ordinal_limit
          • set_selector
          • enable_tracing
          • get_prev_fixup_ea
          • del_segm
          • get_bmask_cmt
          • end_type_updating
          • Find
          • toggle_bnot
          • patch_byte
          • get_module_info
          • set_member_name
          • create_float
          • del_struc_member
          • read_dbg_memory
          • get_enum_width
          • getn_thread_name
          • del_struc
          • filelength
          • set_manual_insn
          • is_value...() functions
          • get_ip_val
          • del_extra_cmt
          • create_insn
          • op_offset_high16
          • get_cmt
          • expand_struc
          • get_idb_path
          • set_frame_size
          • get_file_ext
          • has_value
          • readshort
          • sanitize_file_name
          • get_member_flag
          • create_struct
          • ARM specific
          • set_enum_member_cmt
          • rename
          • set_ida_state
          • get_member_size
          • msg
          • qbasename
          • get_enum_member_enum
          • auto_mark_range
          • plan_to_apply_idasgn
          • set_named_type
          • op_offset
          • rename_entry
          • strlen
          • get_extra_cmt
          • get_enum_flag
          • fgetc
          • op_stkvar
          • get_last_index
          • get_field_ea
          • get_struc_id
          • select_thread
          • create_array
          • get_struc_cmt
          • set_array_string
          • set_func_attr
          • set_storage_type
          • get_struc_size
          • demangle_name
          • get_next_fixup_ea
          • get_next_bmask
          • delattr
          • gen_simple_call_chart
          • patch_qword
          • get_enum_name
          • loader_input_t.getc
          • get_debugger_event_cond
          • read_dbg_qword
          • define_local_var
          • generate_disasm_line
          • add_idc_hotkey
          • tolower
          • del_selector
          • set_debugger_event_cond
          • get_imagebase
          • gen_file
          • get_entry
          • find_custom_data_format
          • get_debug_name_ea
          • add_default_til
          • set_func_end
          • exit_process
          • delete_array
          • xtol
          • get_exception_code
          • detach_process
          • set_enum_cmt
          • get_wide_word
          • put_bookmark
          • is_loaded
          • add_enum_member
          • parse_decls
          • readstr
          • get_entry_qty
          • ord
          • sprintf
          • get_root_filename
          • get_enum_member_cmt
          • create_word
          • set_func_flags
          • loader_input_t.tell
          • create_align
          • read_dbg_dword
          • next_addr
          • get_bytes
          • batch
          • start_process
          • process_config_line
          • del_user_info
          • qmakefile
          • set_struc_name
          • print_decls
          • create_custom_data
          • del_enum_member
          • format_cdata
          • get_fixup_target_sel
          • get_item_size
          • loader_input_t.gets
          • get_last_bmask
          • Step Tracing Options
          • selector_by_name
          • get_enum_cmt
          • next_not_tail
          • prev_head
          • set_color
          • set_numbered_type
          • get_member_name
          • auto_wait
          • get_enum_member_bmask
          • fseek
          • get_segm_start
          • attach_process
          • Trace file functions
          • get_enum_member_value
          • op_stroff
          • get_next_offset
          • set_processor_type
          • get_bookmark_desc
          • create_data
          • lastattr
          • get_operand_value
          • collect_stack_trace
          • toupper
          • get_fixup_target_dis
          • set_cmt
          • add_entry
          • set_segm_addressing
          • qmake_full_path
          • get_source_linnum
          • fputc
          • resume_thread
          • get_func_attr
          • get_first_enum_member
          • add_sourcefile
          • get_first_bmask
          • read_selection_start
          • hasattr
          • get_member_cmt
          • gen_flow_graph
          • get_array_element
          • get_tinfo
          • loader_input_t
          • tinfo_errstr
          • TRUNC
          • add_segm_ex
          • Local types information and manipulation helpers
          • set_source_linnum
          • get_next_enum_member
          • loader_input_t.readbytes
          • set_array_params
          • jumpto
          • get_bookmark
          • set_enum_bf
          • prev_not_tail
          • toggle_sign
          • loader_input_t.size
          • Trace events functions
          • get_func_flags
          • get_gotea
          • set_segm_attr
          • get_item_head
          • set_default_sreg_value
          • print_insn_mnem
          • set_member_cmt
          • get_ordinal_qty
          • set_target_assembler
          • add_user_stkpnt
          • set_local_type
          • Hidden ranges
          • del_items
          • compile_idc_text
          • Dalvik debugger extension functions
          • byte_value
          • create_dword
          • is_code
          • del_func
          • get_enum
          • make_array
          • rotate_left
          • recalc_spd
          • search_path
          • CommonBits
          • get_processor_name
          • set_func_cmt
          • get_prev_bmask
          • Hashes
          • split_sreg_range
          • process_ui_action
          • set_fixup
          • get_fixup_target_type
          • create_oword
          • get_flags
          • get_func_name
          • create_strlit
          • add_struc
          • atol
          • load_debugger
          • mkdir
          • sizeof
          • get_enum_member_by_name
          • save_database
          • guess_type
          • get_segm_name
          • print_operand
          • qisabspath
          • get_member_qty
          • set_struc_cmt
          • get_fixup_target_flags
          • idadir
          • object.retrieve
          • add_auto_stkpnt
          • get_numbered_type_name
          • get_enum_member_name
          • get_next_index
          • prev_addr
          • get_name_ea
          • get_sp_delta
          • set_bmask_cmt
          • readlong
          • set_segm_name
          • get_prev_offset
          • set_segm_alignment
          • get_strlit_contents
          • forget_exception
          • get_item_end
          • add_func
          • get_name
          • Asks
          • get_spd
          • Debugger: control
          • get_wide_byte
          • plan_and_wait
          • set_enum_flag
          • RunPythonStatement
          • del_sourcefile
          • find_selector
          • get_frame_regs_size
          • op_num
          • define_exception
          • create_double
          • create_byte
          • read_selection_end
          • OpTypes
          • op_plain_offset
          • move_segm
          • get_member_id
          • set_segm_combination
          • get_current_thread
          • trim
          • Debugger: options
          • getn_thread
          • get_frame_id
          • typeinfo.print
          • to_ea
          • rebase_program
          • add_struc_member
          • get_exception_qty
          • get_first_index
          • import_type
          • set_segm_type
          • find_custom_data_type
          • get_next_seg
          • find_func_end
          • get_last_enum_member
          • getattr
          • get_frame_size
          • get_screen_ea
          • loader_input_t.read
          • set_reg_value
          • Debugger: modules
          • create_pack_real
          • writestr
          • exec_idc
          • get_enum_size
          • set_enum_name
          • create_tbyte
          • sel2para
          • atoa
          • loader_input_t.close
          • add_enum
          • ltoa
          • substr
          • del_idc_hotkey
          • Breakpoint handling functions
          • loader_input_t.seek
          • cleanup_appcall
          • object.store
          • get_type
          • qexit
          • get_debug_name
          • get_array_id
          • Can't Open File
          • suspend_process
          • process_config_directive
          • get_entry_name
          • get_last_member
          • get_struc_name
          • clear_selection
          • fclose
          • firstattr
          • create_yword
          • dbg_appcall
          • get_qword
          • patch_dword
          • begin_type_updating
          • read_dbg_byte
          • get_fpnum
          • qsleep
          • get_first_member
          • get_nsec_stamp
          • del_stkpnt
          • eval
          • savefile
          • eval_python
          • Xrefs
          • strstr
          • writeshort
          • get_sreg
          • get_segm_end
          • get_func_off_str
          • set_func_start
          • del_array_element
          • get_full_flags
          • set_exception_flags
          • rename_array
          • get_frame_args_size
          • op_flt
          • get_min_spd_ea
          • apply_type
          • get_prev_index
          • loadfile
          • retrieve_input_file_md5
          • get_wide_dword
          • patch_dbg_byte
          • Functions provided by the WinDbg debugger
          • get_original_byte
          • get_member_strid
          • call_system
          • writelong
          • get_thread_qty
          • nextattr
          • send_dbg_command
          • get_first_seg
          • get_processes
          • patch_word
          • get_manual_insn
          • ftell
          • get_entry_ordinal
          • set_array_long
          • delete_all_segments
          • TO_LONG
          • Function chunk related functions
          • Debugger: events
          • get_prev_func
          • op_seg
          • validate_idb_names
          • fprintf
          • fopen
          • strfill
          • del_fixup
          • get_bmask_name
          • inf_attr
          • is_bf
          • read_dbg_word
          • qdirname
          • get_segm_attr
          • func_contains
          • del_source_linnum
          • get_sourcefile
          • clr_database_flag
          • set_name
          • Refresh Screen
          • op_enum
          • getn_enum
          • get_db_byte
          • setattr
          • get_forced_operand
          • op_bin
          • Functions provided by the replayer debugger
          • prevattr
          • update_extra_cmt
          • get_str_type
          • op_man
          • choose_func
          • set_bmask_name
          • get_curline
          • decode_insn
          • set_segment_bounds
          • set_segm_class
          • write_dbg_memory
          • get_exception_name
          • get_enum_member
          • is_mapped
          • del_enum
          • get_frame_lvar_size
          • get_operand_type
          • set_root_filename
          • compile_idc_file
          • typeinfo.size
          • get_local_tinfo
          • get_fixup_target_off
          • is_union
          • unlink
          • get_segm_by_sel
          • set_enum_width
          • take_memory_snapshot
          • exec_python
          • get_next_func
          • get_member_offset
          • get_func_cmt
          • parse_decl
          • create_qword
          • next_head
          • suspend_thread
          • loader_input_t.getz
          • get_color
          • get_reg_value
          • load_and_run_plugin
          • set_database_flag
          • set_enum_member_name
          • set_member_type
          • get_prev_enum_member
      • IDC examples
        • Analyzing encrypted code
  • Admin Guide
    • Lumina server
    • Teams server
    • License server
      • Hex-Rays License Server Migration Guide
  • Release Notes
    • IDA 9.0
    • IDA 8.4sp2
    • IDA 8.4sp1
    • IDA 8.4
    • IDA 8.3
    • IDA 8.2sp1
    • IDA 8.2
    • IDA 8.1
    • IDA 8.0sp1
    • IDA 8.0
    • IDA 7.7sp1
    • IDA 7.7
    • IDA 7.6sp1
    • IDA 7.6
    • IDA 7.5sp3
    • IDA 7.5sp2
    • IDA 7.5sp1
    • IDA 7.5
    • IDA 7.4sp1
    • IDA 7.4
    • IDA 7.3
      • IDA 7.3 Undo: IDA can do it
    • IDA 7.2
      • IDA 7.2 The Mac Rundown
    • IDA 7.1
      • IDA 7.1 Debugger API 7.1 Porting Guide
    • IDA 7.0sp1
    • IDA 7.0
      • Internationalization (i18n)
      • Automatic discovery of string literals
      • API 7.0 Porting Guide
      • IDAPython backward compatibility
    • IDA 6.95
    • IDA 6.9
    • IDA 6.8
    • IDA 6.7
    • IDA 6.6
    • IDA 6.5
    • IDA 6.4
    • IDA 6.3
    • IDA 6.2
    • IDA 6.1
    • IDA 6.0
    • IDA 5.7
    • IDA 5.6
    • IDA 5.5
      • 5.5 Gallery
      • 5.5 Comparison
    • IDA 5.4
    • IDA 5.3
    • IDA 5.2
    • IDA 5.1
    • IDA 5.0
    • IDA 4.9SP
    • IDA 4.9
    • IDA 4.8
    • IDA 4.7
    • IDA 4.6
    • IDA 4.x
    • IDA 3.x
    • Cumulative bugfix for IDA
  • Archive
    • IDA’s Windbg plugin
    • IDA’s Bochs debugger plugin
    • IDA’s Bochs debugger plugin 2
    • DosWin32
    • Hex-Rays v1.1 vs. v1.0 Decompiler Comparison Page
    • Hex-Rays v1.2 vs. v1.1 Decompiler Comparison Page
    • Hex-Rays v1.3 vs. v1.2 Decompiler Comparison Page
    • Hex-Rays v1.6 vs. v1.5 Decompiler Comparison Page
    • Hex-Rays v1.7 vs. v1.6 Decompiler Comparison Page
    • Costly Greetings – An Adventure In Hostile Code Analysis
    • An Adventure In Hostile Code Analysis: Description
    • An Adventure In Hostile Code Analysis: Disassembly
    • Improved code flow analysis
    • Program Navigation Bar
    • IDA Home Contest
    • Pimp My IDA: vote results
    • Turning off IDA 6.x compatibility in IDAPython
    • Porting guide for IDA 7.4 turning off IDA 6.x API backwards-compatibility by default
    • Porting guide for IDA 7.4 IDAPython and Python 3
    • IDAPython and Python 3
    • Porting guide for changes in IDAPython-on-Python-3 APIs
    • Debugging iOS Applications With IDA
    • IDA Win32 to Win32 Debugging
    • IDA Win32 to Win64 Debugging
    • Legacy license server: Floating Licenses
      • Installing on Linux
      • Installing on Windows
      • Installing on OS X
    • Decompiler Installation
    • Enumerated types tutorial
  • Bug Bounty
Powered by GitBook
LogoLogo

Need Help?

  • FAQs
  • Support

Community

  • Forum
  • Plugins

Resources

  • Blog
  • Download center

© 2025 Copyright Hex-Rays

On this page
  • The Goal
  • The Difficulties
  • Memory usage
  • Variability
  • Copyright
  • The idea
  • The Implementation
  • The Results

Was this helpful?

Export as PDF
  1. User Guide
  2. Creating Signatures
  3. FLIRT

IDA F.L.I.R.T. Technology: In-Depth

The Goal

One major stumbling block in the disassembly of programs written in modern high level languages is the time required to isolate library functions. This time may be considered lost because it does not bring us new knowledge : it is only a mandatory step that allows further analysis of the program and its meaningful algorithms. Unfortunately, this process has to be repeated for each and every new disassembly.

Sometimes, the knowledge of the class of a library function can considerably ease the analysis of a program. This knowledge might be extremely helpful in discarding useless information. For example, a C++ function that works with streams usually has nothing to do with the main algorithm of a program.

It is interesting to note that every high level language program uses a great number of standard library functions, sometimes even up to 95% of all the functions called are standard functions. For one well known compiler, the “Hello, world!” program contains:

        library functions       -       58
        function main()         -       1

Of course, this is an artificial example but our analysis has shown that real life programs contain, on average, 50% of library functions. This is why the user of a disassembler is forced to waste more than half of his time isolating those library functions. The analysis of an unknown program resembles the resolution of a gigantic crossword puzzle : the more letters we know, the easier it is to guess the next word. During a disassembly, more comments and meaningful names in a function means a faster understanding of its purpose. Widespread use of standard libraries such as OWL, MFC and others increase even more the contribution of the standard functions in the target program.

A middle sized program for Win32, written in C++, using modern technologies (e.g., AppExpert or a similar wizard) calls anything from 1000 to 2500 library functions.

To assist IDA users we attempted to create an algorithm to recognize the standard library functions. We wanted to achieve a practical, usable result and therefore accepted some limitations

  • we only consider programs written in C/C++

  • we do not attempt to achieve perfect function recognition : this is theoretically impossible. Moreover the recognition of some functions may lead to undesirable consequences. For example, the recognition of the following function

                    push    bp
                    mov     bp, sp
                    xor     ax, ax
                    pop     bp
                    ret
          

    would lead to many misidentifications. It is worth noting that in modern C++ libraries one can find a lot of functions that are absolutely identical byte-to-byte but have different names.

  • we only recognize and identify functions located in the code segment, we ignore the data segment.

  • when a function has been sucessfully identified, we assign it a name and an eventual comment. We do not aim to provide information about the function arguments or about the behaviour of the function.

and we imposed the following constraints upon ourselves

  • we try to avoid false positives completely. We consider that a false positive (a function wrongly identified) is worse than a false negative (a function not identified). Ideally, there should be no false positive at all.

  • the recognition of the functions must require a minimum of processor and memory resources.

  • because of the polyvalent architecture of IDA – it supports tens of very different processors – the identification algorithm must be platform-independent, i.e. it must work with the programs compiled for any processor.

  • the main() function should be identified and properly labelled as the library’ startup-code is of no interest.

The Difficulties

Memory usage

The main obstacle to recognition and identification is the sheer quantity of functions and the size of the memory they occupy. If we evaluate the size of the memory occupied by all _versions_ of all libraries produced by all compiler _vendors_ for memory _models_, we easily fall into the tens of gigabytes range.

Matters get even worse if we try to take OWL, MFC, MFC and similar libraries into account. The storage needed is huge. At this time, personal computers’ users can’t afford to set aside hundreds of Megabytes of disk space for a simple utility disassembler. Therefore, we had to find an algorithm that diminishes the size of the information needed to recognize standard library functions. Of course, the number of functions that should be recognized dictates the need for an efficient recognition algorithm : a simple brute force search is not an option.

Variability

An additional difficulty arises from the presence of _variant_ bytes in the program. Some bytes are corrected (fixed up) at load time, others become constants at link time, but most of the variant bytes originate from references to external names. In that case the compiler does not know the addresses of the called functions and leaves these bytes equal to zeroes. This so called “fixup information” is usually written to a table in the output file (sometimes called “relocation table” or “relocation information”). The example below

B8 0000s                             mov     ax, seg _OVRGROUP_
9A 00000000se                        call    _farmalloc
26: 3B 1E 0000e                      cmp     bx, word ptr es:__ovrbuffer
  

contains variant bytes. The linker will try to resolve external references, replacing zeroes with the addresses of called functions, but some bytes will stay untouched : references to dynamic libraries or bytes containing absolute address in the program. These references can be resolved only at load time by the system loader. It will try to resolve all external references and replace zeroes with absolute addresses. When the system loader cannot resolve an external referenceI, as it is the case when the program refers to an unknown DLL, the program will simply not run.

Optimizations introduced by some linkers will also complicate the matter because constant bytes will sometim es be changed. For example:

               0000: 9A........        call    far ptr xxx

             is replaced by

               0000: 90                nop
               0001: 0E                push    cs
               0002: E8....            call    near ptr xxx

  

The program will execute as usual, but the replacement introduced by the linker effectively prohibits byte-to-byte comparison with a function template. The presence of variant bytes in a program makes the use of simple checksums for recognition impossible. If functions did not contain variant bytes, the CRC of the first N Bytes would be enough to identify and select a group of functions in a hash table. The use of such tables would greatly decrease the size of the information required for identification : the name of a function, its length and checksum would suffice.

We have already mentionned the fact that the recognition of all standard library functions was not possible or even desirable. One additional proof is the fact that some identical functions do exactly the same thing but are called in a different manner. For example, the functions strcmp() and fstrcmp() are identical in large memory models.

We face a dilemna here : we do not want to discard these functions from the recgnition process since they are not trivial and their labelling would help the user but, we are unable to distinguish them.

And there is more : consider this

                call    xxx
                ret
        or
                jmp     xxx
  

At first sight, these pieces of code are not interesting. The problem is that they are present, sometimes in significant number, in standard libraries. The libraries for the Borland C++ v1.5 OS/2 compiler contains 20 calls of this type, in important functions such as read(), write(), etc.

Plain comparison of these functions yields nothing. The only way to distinguish those functions is to discover what other function they call. Generally, all short functions (consisting merely of 2-3 instructions) are difficult to recognize and the probability of wrong recognition is very high. However not recognizing them is undesirable, as it can lead to cascade failures : if we do not recognize the function tolower(), we may fail to recognize strlwr() which refers to tolower().

Copyright

Finally, there is an obvious copyright problem: standard libraries may simply not be distributed with a disassembler.

The idea

To address those issues, we created a database of all the functions from all libraries we wanted to recognize. IDA now checks, at each byte of the program being disassembled, whether this byte can mark the start of a standard library function.

The information required by the recognition algorithm is kept in a signature file. Each function is represented by a pattern. Patterns are first 32 bytes of a function where all variant bytes are marked.

For example:

558BEC0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver
558BEC1E078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk
558BEC1EB41AC55604CD211F5DC3.................................... _setdta
558BEC1EB42FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A _findfirst
  

where variant bytes are displayed as “..” Several functions start with the same byte sequence. Therefore a tree structure seems particularly well suited to the storage of those functions :

558BEC
      0EFF7604..........59595DC3558BEC0EFF7604..........59595DC3 _registerbgidriver
      1E
        078A66048A460E8B5E108B4E0AD1E9D1E980E1C0024E0C8A6E0A8A76 _biosdisk
        B4
          1AC55604CD211F5DC3                                       _setdta
          2FCD210653B41A8B5606CD21B44E8B4E088B5604CD219C5993B41A   _findfirst

Sequences of bytes are kept in the nodes of the tree. In this example, the root of the tree contains the sequence “558BEC”, three subtrees stem from the root, respectively starting with bytes 0E, 1E, B4. The subtree starting with B4 gives birth to two subtrees. Each subtree ends with leaves . The information about the function is kept in that (only the name is visible in the above example).

The tree data structure simultaneously achieves two goals :

  • Memory requirements are decreased since we store bytes common to several functions in tree nodes. This saving is, of course, proportional to the number of functions starting with the same bytes.

  • It is well suited to fast fast pattern matching. The number of comparisons required to match a specific location within a program to all functions in a signature file grows logarithmically with the number of functions.

It would not be very wise to take a decision based on the first 32 bytes of a function alone. As already suggested, modern real-world libraries contain several functions starting with the same bytes:

558BEC
      56
        1E
          B8....8ED8
                   33C050FF7608FF7606..........83C406
                                                      8BF083FEFF
                    0. _chmod   (20 5F33)
                    1. _access  (18 9A62)
  

When two functions have the same first 32 bytes, they are stored in the same leaf of the tree. To resolve that situation, we calculate the CRC16 of the bytes starting from position 33 until till the first variant byte. The CRC is stored in the signature file. The number of bytes used to calculate that CRC also needs to be saved, as it differs from function to function. In the above example, the CRC16 is calculated on 20 bytes for the _chmod (bytes 33..52) function and 18 _access function.

There is, of course, a possibility that the first variant byte will be at the 33d position. The length of the sequence of bytes used to calculate the CRC16 is then equal to zero. In practice, this happens rarely and this algorithm gives very low number of false recognitions.

Sometimes functions have the same initial 32-byte pattern and the same CRC16, as in the example below

05B8FFFFEB278A4606B4008BD8B8....8EC0
          0. _tolower (03 41CB) (000C:00)
          1. _toupper (03 41CB) (000C:FF)
  

We are unlucky: only 3 bytes were used to calculate the CRC16 and they were the same for both functions. In this case we will try to find a position at which all functions in a leaf have different bytes. (in our example this position is 32+3+000C)

But even this method does not allow to recognize all functions. Here is another example:

... (partial tree is shown here)
                0D8A049850E8....83C402880446803C0075EE8BC7:
                  0. _strupr (04 D19F) (REF 0011: _toupper)
                  1. _strlwr (04 D19F) (REF 0011: _tolower)
  

These functions are identical at non-variant bytes and differ only by the functions they call. In this example the only way to distinguish functions is to examine the name referenced from the instruction at offset 11.

The last method has a disadvantage: proper recognition of functions _strupr() and _strlwr() depends on the recognition of functions _toupper() and _tolower(). It means that in the case of failure because of the absence of reference to _toupper() or _tolower() we should defer recognition and repeat it later, after finding _tolower() or _toupper(). This has an impact on the general design of the algorithm : we need a second pass to resolve those deferred recognitions. Luckily, subsequent passes are only applied to a few locations in the program.

Finally, one can find functions that are identical in non-variant bytes, refer to the same names but are called differently. Those functions have the same implementation but different names. Surprisingly, this is a frequent situation in standard libraries, especially in C++ libraries.

We call this situation a _collision_ which occurs when functions attached to a leaf cannot be distinguished from each other by using the described methods. A classical example is:

558BEC1EB441C55606CD211F720433C0EB0450E8....5DCB................
   0. _remove (00 0000)
   1. _unlink (00 0000)

   or
8BDC36834702FAE9....8BDC36834702F6E9............................
   0. @iostream@$vsn            (00 0000)
   1. @iostream_withassign@$vsn (00 0000)
  

Artificial Intelligence is the only way to resolve those cases. Since our goal was efficiency and speed, we decided to leave artificial intelligence for the future developments of the algorithm.

The Implementation

In IDA version 3.6, the practical implementation of the algorithm matches the above description almost perfectly. We have limited ourselves to the C and C++ language but it will be, without doubt, possible to write pre-processors for other libraries in the future.

A separate signature file is provided for each compiler. This segregation decreases the probability of cross-compiler identification collisions. A special signature file, called startup signature file is applied to the entry point of the disassembled program to determine the generating compiler. Once it has been identified, we know which signature file should be used for the rest of the disassembly. Our algorithm successfully discerns the startup modules of most popular compilers on the market.

Since we store all functions’ signatures for one compiler in one signature file, it is not necessary to discriminate the memory models (small,compact, medium, large, huge) of the libraries and/or versions of the compilers.

We use special startup-signatures for every format of disassembled file. The signature exe.sig is used for programs running under MS DOS, lx.sig or ne.sig – for OS/2, etc.

To decrease a probability of false recognition of short functions, we must absolutely remember any reference to an external name if such a reference exists. It may decrease, to some degree, the probability of the recognition of the function in general but we believe that such an approach is justified. It is better not to recognize than to recognize wrongly. Short functions (shorter than 4 bytes) that do no contain references to external names are not used in the creation of a signature file and no attempt is made to recognize such functions.

The functions from <ctype.h> are short and refer to the array of types of the symbols, therefore we decided to consider the references to this array as an exception : we calculate the CRC16 of the array of the types of the symbols and store it in the signature file.

Without artificial intelligence, the collisions are solved by natural intelligence. The human creator of a signature file chooses the functions to include and to discard from the signature file. This choice is very easy and is practically implemented by the edition of a text file.

The patterns of the functions are not stored in a signature file under their original form (i.e., they do not look like the example figures). In place of the patterns, we store the arrays of bits determining the changing bytes and the values of the individual bytes are stored. Therefore the signature file contains no byte from the original libraries, except for the names of the functions. The creation of a signature file involves in 2 stages: the preprocessing of the libraries and the creation of a signature file. In the first stage the program ‘parselib’ is used. It preprocesses *.obj and *.lib files to produce a pattern-file. The pattern-file contains the patterns of the functions, their names, their CRC16 and all other information necessary to create the signature file. At the second stage the ‘sigmake’ program builds the signature file from the pattern-file.

This division into 2 stages allows sigmake utility to be independent of the format of the input file. Therefore it will be possible to write other preprocessors for files differing from *.obj and *.lib in future.

We decided to compress (using the InfoZip algorithm) the created signature files to decrease the disk space necessary for their storage.

For the sake of user’s convenience we attempted to recognize the main() function as often as it was possible. The algorithm for identifying this function differs from compiler to compiler and from program to program. (DOS/OS2/Windows/GUI/Console…).

This algorithm is written, as a text string, in a signature file. Unfortunately we have not yet been able to automate the creation of this algorithm.

The Results

As it turns out the signature files compress well; they may be compressed by a factor bigger than 2. The reason of this compressibility is that about 95% of a signature file are function names. (Example: the signature file for MFC 2.x was 2.5MB before compression, 700Kb after. It contains 33634 function names; an average of 21 bytes is stored per function. Generally, the ratio of the size of a library size to the size of a signature file varies from 100 to 500.

The percentage of properly recognized functions is very high. Our algorithm recognized all but one function of the “Hello World” program. The unrecognized function consists of only one instruction:

        jmp     off_1234
  

We were especially pleased with the fact that there was no false recognition. However it does not mean that they will not occur in the future. It should be noted that the algorithm only works with functions.

Data is sometimes located in the code segment and therefore we need to mark some names as “data names”, not as “function names”. It is not easy to examine all names in a modern large library and mark all data names.

The implementation of these data names is planned, some time in the future.

Last updated 9 months ago

Was this helpful?