소스 정보
- 저장소
- buzzer-re/Rikugan
- 최근 소스 활동
- 2026년 3월 4일 18:39
- 감지된 SKILL.md 언어
- 영어
- 스타
- 671
- 포크
- 78
설치 방법
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
소스 파일 검토
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
메뉴
기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.
설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/buzzer-re/Rikugan --skill ida-scripting명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SKILL.md 표시 중
| name | IDA Scripting |
| description | Write and execute IDAPython scripts — full API reference included |
| tags | ["scripting","ida","python","automation"] |
| author | Rikugan |
| 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:
udt = ida_typeinf.udt_type_data_t()
fname, ftype, byte_off fields:
udm = ida_typeinf.udm_t()
udm.name = fname
udm. = ftype
udm.offset = byte_off *
udt.push_back(udm)
tif = ida_typeinf.tinfo_t()
tif.create_udt(udt, ida_typeinf.BTF_STRUCT)
tif.set_named_type(, name, ida_typeinf.NTF_REPLACE)
tif
auxv_tif = make_struct(, [
(, make_int_type(, ), ),
(, make_int_type(, ), ),
])
char_ptr = make_ptr_type(make_int_type())
char_pp = make_ptr_type(char_ptr)
u8_arr = make_array_type(make_int_type(), )
make_struct(, [
(, char_pp, ),
(, u8_arr, ),
])
() -> ida_typeinf.tinfo_t:
t = ida_typeinf.tinfo_t()
t.get_named_type(, name):
ValueError()
t
ida_typeinf.apply_tinfo(ea, auxv_tif, ida_typeinf.TINFO_DEFINITE)
t = ida_typeinf.tinfo_t()
t.get_named_type(, ):
()
:
()
ida_typeinf.apply_cdecl(, ea, )
edt = ida_typeinf.enum_type_data_t()
vname, vval [(, ), (, )]:
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(, , 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
ida_bytes.patch_bytes(ea, b"\x90" * 5) # NOP sled
ida_bytes.patch_dword(ea, 0)
ea = ida_kernwin.get_screen_ea()
ida_kernwin.jumpto(target_ea)
ida_kernwin.msg("Info message\n")
name = ida_kernwin.ask_str("default", 0, "Enter name:")
choice = ida_kernwin.ask_yn(1, "Sure?")
ida_kernwin.show_wait_box("Processing...")
# ... work ...
ida_kernwin.hide_wait_box()
func = ida_funcs.get_func(ea)
fc = ida_gdl.FlowChart(func)
for block in fc:
print(f"Block {hex(block.start_ea)}-{hex(block.end_ea)}")
for succ in block.succs():
print(f" -> {hex(succ.start_ea)}")
# Find all callers of a function
target = ida_name.get_name_ea(idaapi.BADADDR, "malloc")
if target != idaapi.BADADDR:
for ref in idautils.CodeRefsTo(target, False):
func = ida_funcs.get_func(ref)
if func:
print(f"Called from {idc.get_func_name(func.start_ea)} @ {hex(ref)}")
# Batch decompile
for func_ea in idautils.Functions():
try:
cfunc = ida_hexrays.decompile(func_ea)
text = "\n".join(ida_lines.tag_remove(l.line) for l in cfunc.get_pseudocode())
except ida_hexrays.DecompilationFailure:
pass
# Persistent storage via netnodes
node = ida_netnode.netnode("$my_data", 0, True)
node.hashset("key", "value")
val = node.hashstr("key")
BADADDR = 0xFFFFFFFF (32-bit) or 0xFFFFFFFFFFFFFFFF (64-bit) — always compare against it.ida_hexrays.decompile() can raise DecompilationFailure — always wrap in try/except.ida_struct/ida_enum — use ida_typeinf with udt_type_data_t/udm_t/enum_type_data_t/edm_t.udm_t.offset is in BITS, not bytes — always multiply byte offset by 8.tinfo_t(BT_INT32) constructor — call t.create_simple_type(BT_INT32) explicitly; the single-arg constructor is unreliable across IDA versions.NTF_REPLACE to set_named_type() when redefining a type; omitting it may silently fail on re-runs.t.get_named_type(None, name) and t.dstr() to confirm the type registered correctly.get_named_type() not by raw tinfo_t.ida_bytes.get_strlit_contents() returns bytes, not str — decode with .decode('utf-8', errors='replace').SOC 직업 분류 기준