with one click
ida-scripting
Write and execute IDAPython scripts — full API reference included
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Write and execute IDAPython scripts — full API reference included
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Next-generation 0day discovery & exploit development — comprehensive code analysis, allocator vulnerabilities, compiler-induced bugs, SIMD/vector issues, JIT vulnerabilities, custom allocator attacks, ASLR/kASLR bypass, UAF, OOB, RCE with exploit generation, privilege escalation, backdoor establishment
Next-generation 0day discovery — novel overflow patterns, allocator exploits, compiler-induced bugs, bounds-check bypass, SIMD/vector overflows, JIT vulns, custom allocator attacks, ASLR/kASLR bypass, UAF, OOB, RCE with weaponized exploit generation, privilege escalation, backdoor establishment
Container escape vulnerability discovery — Docker, Kubernetes, container runtime exploitation, namespace isolation bypass, privilege escalation through container boundaries
Crypto implementation analysis — weak algorithms, side-channels, key management flaws, padding oracles, random generation failures, implementation bugs
IoT device security analysis — firmware extraction, RTOS exploits, hardware interfaces, protocol vulnerabilities, side-channel attacks, update mechanism exploitation
Industrial control system security — Modbus, DNP3, IEC 104, Ethernet/IP, PLC exploitation, control logic manipulation, sensor/actuator attacks, ICS protocol analysis
| name | IDA Scripting |
| description | Write and execute IDAPython scripts — full API reference included |
| tags | ["scripting","ida","python","automation"] |
| author | Spectra |
| version | 1 |
Task: Help the user write IDAPython scripts. You have execute_python which runs code with all ida_* modules, idaapi, idautils, and idc pre-loaded.
print() for all output — it's captured and returned to you.None / BADADDR returns (e.g., ida_funcs.get_func() returns None if no function).ida_auto.auto_wait() after bulk modifications to let auto-analysis settle.ida_hexrays.mark_cfunc_dirty(ea) before re-decompiling a function you've modified.ida_struct and ida_enum — use ida_typeinf for all type operations.The execute_python tool provides:
idaapi, idautils, idc — high-level wrappersida_funcs, ida_name, ida_bytes, ida_segment, ida_typeinf, ida_nalt, ida_xref, ida_kernwin, ida_hexrays, ida_lines, ida_search, ida_ida, ida_entry, ida_frame, ida_auto, ida_gdl, ida_netnode — low-level modulesBADADDR is available via idaapi.BADADDRval = ida_bytes.get_byte(ea) # uint8
val = ida_bytes.get_dword(ea) # uint32
val = ida_bytes.get_qword(ea) # uint64
raw = ida_bytes.get_bytes(ea, size) # bytes
s = ida_bytes.get_strlit_contents(ea, -1, ida_nalt.STRTYPE_C)
for func_ea in idautils.Functions():
name = idc.get_func_name(func_ea)
func = ida_funcs.get_func(ea) # func_t or None
# func.start_ea, func.end_ea, func.flags
idc.add_func(ea) # create function
ida_name.set_name(ea, "new_name", ida_name.SN_CHECK)
cfunc = ida_hexrays.decompile(ea) # cfuncptr_t
pseudocode = cfunc.get_pseudocode() # simpleline_t vector
for line in pseudocode:
print(ida_lines.tag_remove(line.line))
# Local variables
for lvar in cfunc.get_lvars():
print(f"{lvar.name}: {lvar.type()}")
# CTree visitor
class MyVisitor(ida_hexrays.ctree_visitor_t):
def __init__(self):
super().__init__(ida_hexrays.CV_FAST)
def visit_expr(self, expr):
if expr.op == ida_hexrays.cot_call:
print(f"Call at {hex(expr.ea)}")
return 0
visitor = MyVisitor()
visitor.apply_to(cfunc.body, None)
for xref in idautils.XrefsTo(ea):
print(f"from {hex(xref.frm)}, type={xref.type}")
for xref in idautils.XrefsFrom(ea):
print(f"to {hex(xref.to)}")
for ref in idautils.CodeRefsTo(ea, False): # False = no flow
print(hex(ref))
for ref in idautils.DataRefsTo(ea):
print(hex(ref))
Critical: udm_t.offset is in BITS, not bytes. udm_t.size is also in BITS.
import ida_typeinf
# Helper: make a simple integer tinfo_t
def make_int_type(byte_size: int, signed: bool = False) -> ida_typeinf.tinfo_t:
bt_map = {
(1, False): ida_typeinf.BT_INT8,
(1, True): ida_typeinf.BT_INT8,
(2, False): ida_typeinf.BT_INT16,
(2, True): ida_typeinf.BT_INT16,
(4, False): ida_typeinf.BT_INT32,
(4, True): ida_typeinf.BT_INT32,
(8, False): ida_typeinf.BT_INT64,
(8, True): ida_typeinf.BT_INT64,
}
t = ida_typeinf.tinfo_t()
t.create_simple_type(bt_map[(byte_size, signed)])
return t
# Helper: make a pointer type
def make_ptr_type(inner: ida_typeinf.tinfo_t) -> ida_typeinf.tinfo_t:
pd = ida_typeinf.ptr_type_data_t()
pd.obj_type = inner
t = ida_typeinf.tinfo_t()
t.create_ptr(pd)
return t
# Helper: make an array type
def make_array_type(elem: ida_typeinf.tinfo_t, count: int) -> ida_typeinf.tinfo_t:
ad = ida_typeinf.array_type_data_t()
ad.elem_type = elem
ad.nelems = count
t = ida_typeinf.tinfo_t()
t.create_array(ad)
return t
# Build struct — offsets in BITS
def make_struct(name: str, fields: list) -> ida_typeinf.tinfo_t:
"""fields = [(name, tinfo_t, byte_offset), ...]"""
udt = ida_typeinf.udt_type_data_t()
for fname, ftype, byte_off in fields:
udm = ida_typeinf.udm_t()
udm.name = fname
udm.type = ftype
udm.offset = byte_off * 8 # ← BITS, not bytes
udt.push_back(udm)
tif = ida_typeinf.tinfo_t()
tif.create_udt(udt, ida_typeinf.BTF_STRUCT)
tif.set_named_type(None, name, ida_typeinf.NTF_REPLACE)
return tif
# Example: struct Elf32_auxv_entry { uint32_t a_type; uint32_t a_val; }
auxv_tif = make_struct("Elf32_auxv_entry", [
("a_type", make_int_type(4, False), 0),
("a_val", make_int_type(4, False), 4),
])
# Example: struct with pointer and array fields
char_ptr = make_ptr_type(make_int_type(1)) # char*
char_pp = make_ptr_type(char_ptr) # char**
u8_arr = make_array_type(make_int_type(1), 16) # uint8_t[16]
make_struct("StartupInfo", [
("argv", char_pp, 0),
("buf", u8_arr, 8),
])
# Reference a previously defined struct by name
def get_named_type(name: str) -> ida_typeinf.tinfo_t:
t = ida_typeinf.tinfo_t()
if not t.get_named_type(None, name):
raise ValueError(f"Type '{name}' not found in type library")
return t
# Apply type to address
ida_typeinf.apply_tinfo(ea, auxv_tif, ida_typeinf.TINFO_DEFINITE)
# Validate after creation
t = ida_typeinf.tinfo_t()
if t.get_named_type(None, "Elf32_auxv_entry"):
print(f"OK: {t.dstr()}, size={t.get_size()} bytes")
else:
print("ERROR: type not registered")
# Simpler alternative for well-known C types: parse C declaration directly
# Works well for types IDA already knows; avoid for custom typedefs
ida_typeinf.apply_cdecl(None, ea, "int __cdecl func(int a, char *b)")
# Create enum
edt = ida_typeinf.enum_type_data_t()
for vname, vval in [("VAL_A", 0), ("VAL_B", 1)]:
edm = ida_typeinf.edm_t()
edm.name = vname; edm.value = vval
edt.push_back(edm)
tif_enum = ida_typeinf.tinfo_t()
tif_enum.create_enum(edt)
tif_enum.set_named_type(None, "MyEnum", ida_typeinf.NTF_REPLACE)
for seg_ea in idautils.Segments():
seg = ida_segment.getseg(seg_ea)
print(f"{ida_segment.get_segm_name(seg)}: {hex(seg.start_ea)}-{hex(seg.end_ea)}")
for s in idautils.Strings():
refs = list(idautils.DataRefsTo(s.ea))
print(f"'{s}' @ {hex(s.ea)}, refs={len(refs)}")
for ea, name in idautils.Names():
print(f"{hex(ea)}: {name}")
ida_name.set_name(ea, "my_label", ida_name.SN_CHECK)
idc.set_cmt(ea, "note", 0) # 0=regular, 1=repeatable
idc.set_func_cmt(ea, "description", 0)
# IDA 9+
ea = ida_bytes.find_bytes(start_ea, "48 8B ?? ?? 90", 0)
# Pattern search loop
ea = start_ea
while ea != idaapi.BADADDR:
ea = ida_search.find_binary(ea, idaapi.BADADDR, "E8 ?? ?? ?? ??", 16,
ida_search.SEARCH_DOWN | ida_search.SEARCH_NEXT)
if ea != idaapi.BADADDR:
print(hex(ea))
ida_bytes.patch_byte(ea, 0x90) # NOP