ida python scripts 重加载:

idaapi.require("module_name")

参考:Loading your own modules from your IDAPython scripts with idaapi.require().

正常来说直接

from idaapi import *

就行,会直接加载所有 ida 的 API。

地址

idc.set_name(ea, name, flags=0) # 设置地址处的名字
ida_idaapi.BADADDR # 不存在的错误地址

获取屏幕光标所在处的地址

ida_kernwin.get_screen_ea()

程序的最小/最大地址

ida_ida.inf_get_min_ea() # 最小地址
ida_ida.inf_get_max_ea() # 最大地址

程序基址

ida_nalt.get_imagebase()

选择的一块地址中的起始/结束地址

idc.read_selection_start()
idc.read_selection_end()

获取某地址上的值

ida_bytes.get_wide_byte(addr)
ida_bytes.get_wide_word(addr)
ida_bytes.get_wide_dword(addr)
ida_bytes.get_qword(addr)

Patch 地址上的值

ida_bytes.patch_byte(addr,value)
ida_bytes.patch_word(addr,value)
ida_bytes.patch_dword(addr,value)
ida_bytes.patch_qword(addr,value)

汇编

取某地址处的汇编

idc.GetDisasm(addr)
ida_lines.generate_disasm_line(addr, flag)
idc.next_head(ea) # 获取下一行汇编
idc.prev_head(ea) # 获取上一行汇编

如果参数的地址在指令中间的话,会返回从头开始的指令(而不是从该地址反汇编)

第二个函数似乎更高级?

获取指令

ida_ua.print_insn_mnem(addr)

获取操作数

ida_ua.print_operand(addr, index)

第一个参数是汇编指令的地址,第二个参数是第几个操作数。生成的数据包含颜色代码

获取操作数类型

idc.get_operand_type(addr, index)

返回值是一个数字

获取操作数的值

idc.get_operand_value(addr, index)

idautils.Segments() # 获取所有段

返回值是一个包含所有段起始位置的地址的 list

idc.get_segm_name(addr)  # 段的名称
idc.get_segm_start(addr) # 段的起始地址
idc.get_segm_end(addr)   # 段的结束地址
idc.get_first_seg()      # 获取第一个段的地址
idc.get_next_seg(addr)   # 获取下一个段的地址,参数是当前段的地址

打印所有段

for seg in idautils.Segments():
    segname  = idc.get_segm_name(seg)
    segstart = idc.get_segm_start(seg)
    segend   = idc.get_segm_end(seg)
    print("Name={} start={} end={}".format(segname,hex(segstart),hex(segend)))

函数

idautils.Functions() # 函数列表,值是函数的起始地址
ida_funcs.get_func_name(addr) # 获取函数名(不好看)
ida_funcs.get_func_cmt(ea, repeatable) # 获取函数注释
ida_funcs.choose_func(title) # 弹出对话框让用户选择函数,title 是对话框标题,返回函数地址
ida_funcs.get_func_off_str(addr) # 获取当前地址在函数中的偏移
ida_funcs.find_func_end(addr) # 寻找函数返回值,没有返回 -1

获取地址所在的函数

func = ida_funcs.get_func(current_ea)
func.start_ea # 起始地址
func.end_ea   # 结束地址

设置函数始末地址

ida_funcs.set_func_start(ea, newstart)
ida_funcs.set_func_end(ea, newend)

ea 为函数中的任意地址

函数内 block 的遍历

f_blocks = ida_gdl.FlowChart(ida_funcs.get_func(addr), flags=ida_gdl.FC_PREDS)
for block in f_blocks:
    print(hex(block.start_ea))

反编译

反编译函数

cfunc = ida_hexrays.decompile(func)

这样直接打印 cfunc 会得到反编译出的函数内容。

那该怎么获取一行呢?

参考资料