IDAPython
Use modern ida_* modules. Avoid legacy idc module.
Module Router
| Task |
Module |
Key Items |
| Bytes/memory |
ida_bytes |
get_bytes, patch_bytes, get_flags, create_* |
| Functions |
ida_funcs |
func_t, get_func, add_func, get_func_name |
| Names |
ida_name |
set_name, get_name, demangle_name |
| Types |
ida_typeinf |
tinfo_t, apply_tinfo, parse_decl |
| Decompiler |
ida_hexrays |
decompile, cfunc_t, lvar_t, ctree visitor |
| Segments |
ida_segment |
segment_t, getseg, add_segm |
| Xrefs |
ida_xref |
xrefblk_t, add_cref, add_dref |
| Instructions |
ida_ua |
insn_t, op_t, decode_insn |
| Stack frames |
ida_frame |
get_frame, define_stkvar |
| Iteration |
idautils |
Functions(), Heads(), XrefsTo(), Strings() |
| UI/dialogs |
ida_kernwin |
msg, ask_*, jumpto, Choose |
| Database info |
ida_ida |
inf_get_*, inf_is_64bit() |
| Analysis |
ida_auto |
auto_wait, plan_and_wait |
| Flow graphs |
ida_gdl |
FlowChart, BasicBlock |
| Register tracking |
ida_regfinder |
find_reg_value, reg_value_info_t |
Core Patterns
Iterate functions
for ea in idautils.Functions():
name = ida_funcs.get_func_name(ea)
func = ida_funcs.get_func(ea)
Iterate instructions in function
for head in idautils.FuncItems(func_ea):
insn = ida_ua.insn_t()
if ida_ua.decode_insn(insn, head):
print(f"{head:#x}: {insn.itype}")
Cross-references
for xref in idautils.XrefsTo(ea):
print(f"{xref.frm:#x} -> {xref.to:#x} type={xref.type}")
Read/write bytes
data = ida_bytes.get_bytes(ea, size)
ida_bytes.patch_bytes(ea, b"\x90\x90")
Names
name = ida_name.get_name(ea)
ida_name.set_name(ea, "new_name", ida_name.SN_NOCHECK)
Decompile function
cfunc = ida_hexrays.decompile(ea)
if cfunc:
print(cfunc) # pseudocode
for lvar in cfunc.lvars:
print(f"{lvar.name}: {lvar.type()}")
Walk ctree (decompiled AST)
class MyVisitor(ida_hexrays.ctree_visitor_t):
def visit_expr(self, e):
if e.op == ida_hexrays.cot_call:
print(f"Call at {e.ea:#x}")
return 0
cfunc = ida_hexrays.decompile(ea)
MyVisitor().apply_to(cfunc.body, None)
Apply type
tif = ida_typeinf.tinfo_t()
if ida_typeinf.parse_decl(tif, None, "int (*)(char *, int)", 0):
ida_typeinf.apply_tinfo(ea, tif, ida_typeinf.TINFO_DEFINITE)
Create structure
udt = ida_typeinf.udt_type_data_t()
m = ida_typeinf.udm_t()
m.name = "field1"
m.type = ida_typeinf.tinfo_t(ida_typeinf.BTF_INT32)
m.offset = 0
m.size = 4
udt.push_back(m)
tif = ida_typeinf.tinfo_t()
tif.create_udt(udt, ida_typeinf.BTF_STRUCT)
tif.set_named_type(ida_typeinf.get_idati(), "MyStruct")
Strings list
for s in idautils.Strings():
print(f"{s.ea:#x}: {str(s)}")
Wait for analysis
ida_auto.auto_wait() # Block until autoanalysis completes
Key Constants
| Constant |
Value/Use |
BADADDR |
Invalid address sentinel |
ida_name.SN_NOCHECK |
Skip name validation |
ida_typeinf.TINFO_DEFINITE |
Force type application |
o_reg, o_mem, o_imm, o_displ, o_near |
Operand types |
dt_byte, dt_word, dt_dword, dt_qword |
Data types |
fl_CF, fl_CN, fl_JF, fl_JN, fl_F |
Code xref types |
dr_R, dr_W, dr_O |
Data xref types |
Critical Rules
- NEVER convert hex/decimal manually — use
int_convert MCP tool
- Wait for analysis: Call
ida_auto.auto_wait() before reading results
- Thread safety: IDA SDK calls must run on main thread (use
@idasync)
- 64-bit addresses: Always assume
ea_t can be 64-bit
Anti-Patterns
| Avoid |
Do Instead |
idc.* functions |
Use ida_* modules |
| Hardcoded addresses |
Use names, patterns, or xrefs |
| Manual hex conversion |
Use int_convert tool |
| Blocking main thread |
Use execute_sync() for long ops |
| Guessing at types |
Derive from disassembly/decompilation |
Detailed API Reference
For comprehensive documentation on any module, read docs/<module>.md:
- High-use:
ida_bytes, ida_funcs, ida_hexrays, ida_typeinf, ida_name, idautils
- Medium-use:
ida_segment, ida_xref, ida_ua, ida_frame, ida_kernwin
- Specialized:
ida_dbg (debugger), ida_nalt (netnode storage), ida_regfinder (register tracking)
Full RST sources from hex-rays.com available at docs/<module>.rst.
1---2name: idapython3description: IDA Pro Python scripting for reverse engineering. Use when writing IDAPython scripts, analyzing binaries, working with IDA's API for disassembly, decompilation (Hex-Rays), type systems, cross-references, functions, segments, or any IDA database manipulation. Covers ida_* modules (50+), idautils iterators, and common patterns.4---5
6# IDAPython
7
8Use modern `ida_*` modules. Avoid legacy `idc` module.
9
10## Module Router
11
12| Task | Module | Key Items |
13|------|--------|-----------|
14| Bytes/memory | `ida_bytes` | `get_bytes`, `patch_bytes`, `get_flags`, `create_*` |
15| Functions | `ida_funcs` | `func_t`, `get_func`, `add_func`, `get_func_name` |
16| Names | `ida_name` | `set_name`, `get_name`, `demangle_name` |
17| Types | `ida_typeinf` | `tinfo_t`, `apply_tinfo`, `parse_decl` |
18| Decompiler | `ida_hexrays` | `decompile`, `cfunc_t`, `lvar_t`, ctree visitor |
19| Segments | `ida_segment` | `segment_t`, `getseg`, `add_segm` |
20| Xrefs | `ida_xref` | `xrefblk_t`, `add_cref`, `add_dref` |
21| Instructions | `ida_ua` | `insn_t`, `op_t`, `decode_insn` |
22| Stack frames | `ida_frame` | `get_frame`, `define_stkvar` |
23| Iteration | `idautils` | `Functions()`, `Heads()`, `XrefsTo()`, `Strings()` |
24| UI/dialogs | `ida_kernwin` | `msg`, `ask_*`, `jumpto`, `Choose` |
25| Database info | `ida_ida` | `inf_get_*`, `inf_is_64bit()` |
26| Analysis | `ida_auto` | `auto_wait`, `plan_and_wait` |
27| Flow graphs | `ida_gdl` | `FlowChart`, `BasicBlock` |
28| Register tracking | `ida_regfinder` | `find_reg_value`, `reg_value_info_t` |
29
30## Core Patterns
31
32### Iterate functions
33```python
34for ea in idautils.Functions():
35 name = ida_funcs.get_func_name(ea)
36 func = ida_funcs.get_func(ea)
37```
38
39### Iterate instructions in function
40```python
41for head in idautils.FuncItems(func_ea):
42 insn = ida_ua.insn_t()
43 if ida_ua.decode_insn(insn, head):
44 print(f"{head:#x}: {insn.itype}")
45```
46
47### Cross-references
48```python
49for xref in idautils.XrefsTo(ea):
50 print(f"{xref.frm:#x} -> {xref.to:#x} type={xref.type}")
51```
52
53### Read/write bytes
54```python
55data = ida_bytes.get_bytes(ea, size)
56ida_bytes.patch_bytes(ea, b"\x90\x90")
57```
58
59### Names
60```python
61name = ida_name.get_name(ea)
62ida_name.set_name(ea, "new_name", ida_name.SN_NOCHECK)
63```
64
65### Decompile function
66```python
67cfunc = ida_hexrays.decompile(ea)
68if cfunc:
69 print(cfunc) # pseudocode
70 for lvar in cfunc.lvars:
71 print(f"{lvar.name}: {lvar.type()}")
72```
73
74### Walk ctree (decompiled AST)
75```python
76class MyVisitor(ida_hexrays.ctree_visitor_t):
77 def visit_expr(self, e):
78 if e.op == ida_hexrays.cot_call:
79 print(f"Call at {e.ea:#x}")
80 return 0
81
82cfunc = ida_hexrays.decompile(ea)
83MyVisitor().apply_to(cfunc.body, None)
84```
85
86### Apply type
87```python
88tif = ida_typeinf.tinfo_t()
89if ida_typeinf.parse_decl(tif, None, "int (*)(char *, int)", 0):
90 ida_typeinf.apply_tinfo(ea, tif, ida_typeinf.TINFO_DEFINITE)
91```
92
93### Create structure
94```python
95udt = ida_typeinf.udt_type_data_t()
96m = ida_typeinf.udm_t()
97m.name = "field1"
98m.type = ida_typeinf.tinfo_t(ida_typeinf.BTF_INT32)
99m.offset = 0
100m.size = 4
101udt.push_back(m)
102tif = ida_typeinf.tinfo_t()
103tif.create_udt(udt, ida_typeinf.BTF_STRUCT)
104tif.set_named_type(ida_typeinf.get_idati(), "MyStruct")
105```
106
107### Strings list
108```python
109for s in idautils.Strings():
110 print(f"{s.ea:#x}: {str(s)}")
111```
112
113### Wait for analysis
114```python
115ida_auto.auto_wait() # Block until autoanalysis completes
116```
117
118## Key Constants
119
120| Constant | Value/Use |
121|----------|-----------|
122| `BADADDR` | Invalid address sentinel |
123| `ida_name.SN_NOCHECK` | Skip name validation |
124| `ida_typeinf.TINFO_DEFINITE` | Force type application |
125| `o_reg`, `o_mem`, `o_imm`, `o_displ`, `o_near` | Operand types |
126| `dt_byte`, `dt_word`, `dt_dword`, `dt_qword` | Data types |
127| `fl_CF`, `fl_CN`, `fl_JF`, `fl_JN`, `fl_F` | Code xref types |
128| `dr_R`, `dr_W`, `dr_O` | Data xref types |
129
130## Critical Rules
131
1321. **NEVER convert hex/decimal manually** — use `int_convert` MCP tool
1332. **Wait for analysis**: Call `ida_auto.auto_wait()` before reading results
1343. **Thread safety**: IDA SDK calls must run on main thread (use `@idasync`)
1354. **64-bit addresses**: Always assume `ea_t` can be 64-bit
136
137## Anti-Patterns
138
139| Avoid | Do Instead |
140|-------|------------|
141| `idc.*` functions | Use `ida_*` modules |
142| Hardcoded addresses | Use names, patterns, or xrefs |
143| Manual hex conversion | Use `int_convert` tool |
144| Blocking main thread | Use `execute_sync()` for long ops |
145| Guessing at types | Derive from disassembly/decompilation |
146
147## Detailed API Reference
148
149For comprehensive documentation on any module, read `docs/<module>.md`:
150- **High-use**: `ida_bytes`, `ida_funcs`, `ida_hexrays`, `ida_typeinf`, `ida_name`, `idautils`
151- **Medium-use**: `ida_segment`, `ida_xref`, `ida_ua`, `ida_frame`, `ida_kernwin`
152- **Specialized**: `ida_dbg` (debugger), `ida_nalt` (netnode storage), `ida_regfinder` (register tracking)
153
154Full RST sources from hex-rays.com available at `docs/<module>.rst`.