IDAPython的常见API收录

The following conventions are used in the function descriptions: ‘ea’ is a linear address ‘success’ is 0 if a function fails, 1 otherwise ‘void’ means that function returns no meaningful value (always 0) ‘anyvalue’ means that function may return value of any type

地址·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 获取当前地址(光标所指处)
idc.here()
idc.get_screen_ea()

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

idc.get_inf_attr(INF_MAX_EA)
idc.get_inf_attr(INF_MIN_EA)
# idc.get_inf_attr()是一个很万能的函数,有许多参数,可以查看官方文档
# https://hex-rays.com/products/ida/support/idadoc/285.shtml

# 获取下一条/上一条指令地址
idc.next_head(ea)
idc.prev_head(ea)

# 获取选择区域的开始/结束地址
# 选中区域即用光标选择的范围
idc.read_selection_start()
idc.read_selection_end()

# 获取基地址
idaapi.get_imagebase()

# 检查当前地址是否合法(注意是BADaddr)
idaapi.BADADDR == myea

数据·

数据相关的主要使用ida_bytes

1
2
3
4
5
6
7
8
9
10
11
12
# 获取数据
ida_bytes.get_bytes(ea,size)
ida_bytes.get_byte(ea)
ida_bytes.get_word(ea)
ida_bytes.get_dword(ea)
ida_bytes.get_qword(ea)

# 修改数据
ida_bytes.patch_byte(ea,value)
ida_bytes.patch_word(ea,value)
ida_bytes.patch_Dword(ea,value)
ida_bytes.patch_Qword(ea,value)

反汇编·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 获取汇编语句
idc.GetDisasm(ea)
idc.generate_disasm_line(ea, flag)
# 这里的flag通常置零
# 还有GENDSM_FORCE_CODE 1 / GENDSM_MULTI_LINE 2 可选

# 获取助记符
idc.print_insn_mnem(ea)

# 获取操作数
idc.print_operand(ea, index) # index从0开始

# 获取操作数类型/值
idc.get_operand_type(ea, index)
idc.get_operand_value(ea, index)

·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 获取段名
idc.get_segm_name(ea)

# 获取段开始/结束地址
idc.get_segm_start(ea)
idc.get_segm_end(ea)

# 获取第一个段/下一个段
idc.get_first_seg()
idc.get_next_seg(ea) # 以ea为参考的下一个

# 获取所有段的地址/名
idautil.Segments()
print(' '.join(idc.get_segm_name(seg) for seg in idautils.Segments()))

函数·

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取ea处函数名
idc.get_func_name(ea)

# 获取上一个/下一个函数的地址
idc.get_prev_func(ea)
idc.get_next_func(ea)

# 获取ea处相对于函数的偏移
idc.get_func_off_str(ea) # return func_name + offset

# 获取所有函数的地址/名
idautils.Functions()
print(' '.join(idc.get_func_name(func) for func in idautils.Functions()))

# 获取函数起始/结束地址
func = idaapi.get_func(ea)
print(func.start_ea, func.end_ea)

搜索·

1
2
3
idc.find_binary(ea, flag, str) # 找到的第一个二进制数据
idc.find_data(ea, flag) # 找到的第一个数据(type)
idc.find_code(ea, flag) # 找到的第一个代码

这里解释下常用的flag

flag value function
SEARCH_UP 0 向上搜索
SEARCH_DOWN 1 向下搜索
SEARCH_NEXT 2 仅对find_binary()生效,从ea的下一个地址开始搜索
SEARCH_CASE 4 大小写敏感

一点小技巧是可以用|使用多个flag

常用脚本·

来源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 打印 IDA 函数列表
import idautils
import idc

func_addr = []
func_name = []
for i in idautils.Functions():
func_addr.append(i)
func_name.append(idc.get_func_name(i))
for i in func_addr:
print(f"{hex(i)}, ",end='')
print('')
for i in func_name:
print(f"\"{i}\", ",end='')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 批量去除花指令
import idc
import ida_bytes


def my_nop(addr, endaddr):
while addr < endaddr:
ida_bytes.patch_byte(addr, 0x90)
addr += 1


pattern = ["74 15 75 13 8D 44 24 FC 83 F0 22 3B 04 24 74 0A E8 1F 00 00 00 74 04",
"74 0A 75 08 E8 10 00 00 00 EB 04 E8",
"48 81 EC 08 03 00 00"]
for i in range(len(pattern)):
cur_addr = 0x406300
end_addr = 0x406E2C

while cur_addr < end_addr:
cur_addr = idc.find_binary(cur_addr, idc.SEARCH_DOWN, pattern[i])
print("patch address: " + hex(cur_addr)) # 打印提示信息
if cur_addr == idc.BADADDR:
break
else:
my_nop(cur_addr, cur_addr + len(pattern[i].split(' ')))
cur_addr = idc.next_head(cur_addr)