前言IDA Python是一个用Python语言编写的插件,它为IDA Pro提供了可扩展性和自动化脚本反对。应用IDA Python,能够以更快、更简略的形式实现反汇编和逆向工程工作。
1、指标疾速理解和开始应用idapython。
2、开发环境和工具清单mac零碎IDA Pro7.0
3、罕用APIidaapi模块:该模块提供了许多外围的IDA API,包含:
idaapi.get_func(ea):获取给定地址处的函数对象idaapi.get_segm_by_name(name):获取指定名称的段对象idaapi.get_screen_ea():获取以后屏幕上显示的地址idaapi.get_func_name(ea):获取给定地址处的函数名idaapi.get_name_ea_simple(name):获取具备给定名称的地址idaapi.asktext(defval, prompt):显示一个文本框,期待用户输出文本idaapi.get_func_offset(ea):获取指定地址绝对于函数起始地址的偏移量idaapi.get_segment_name(ea):获取指定地址所在的段名称idaapi.idc模块:该模块提供了一些旧版IDA API的Python封装,包含:
idc.GetDisasm(ea):获取给定地址处的反汇编指令idc.Jump(ea):跳转到指定地址idc.SetColor(ea, what, color):设置给定地址的色彩idc.MakeCode(ea):将给定地址处的字节转换为指令idc.MakeName(ea, name):将给定地址处的符号名称更改为给定名称idc.get_inf_attr(idc.INF_MIN_EA):获取载入程序的最小的无效地址idc.get_inf_attr(idc.INF_MAX_EA):获取载入程序的最大的无效地址idc.print_insn_mnem(ea):获取给定地址处的助记符idc.prev_head(ea):获取给定地址的上一条指令的地址idc.print_operand(ea,index):获取给定地址中的操作数idc.PatchByte(ea, 0x90):批改给定地址的第一个字节idc.PatchWord(ea, 0x9090):批改给定地址的前两个字节idc.PatchDword(ea, 0x90909090):批改给定地址的前四个字节idc.PatchQword(ea,0x9090909090909090):批改给定地址的前八个字节idautils模块:该模块提供了一些罕用的IDA辅助函数,包含:
idautils.Functions():返回以后程序中所有函数的迭代器idautils.Segments():返回以后程序中所有段的迭代器idautils.Strings():返回以后程序中所有字符串的迭代器idautils.XrefsFrom(ea):返回指向给定地址的所有穿插援用的迭代器idautils.Heads(ea,ea):获取指定地址段的汇编指令4、应用示例移除SVC指令:须要被移除的汇编指令如下:
MOV X0, #0x1FMOV X1, #0MOV X2, #0MOV X3, #0MOV W16, #0x1ASVC 0x80idapython脚本如下:
import idautilsimport idc# 获取二进制文件的起始地址和完结地址start_addr = idc.get_inf_attr(idc.INF_MIN_EA)end_addr = idc.get_inf_attr(idc.INF_MAX_EA)print("Start")# 遍历二进制文件中的所有指令for addr in idautils.Heads(start_addr, end_addr): # 判断以后指令是否为svc指令 mnem = idc.print_insn_mnem(addr) if mnem == "SVC": # 判断svc指令的前五行是否是mov指令 prev1_addr = idc.prev_head(addr) prev2_addr = idc.prev_head(prev1_addr) prev3_addr = idc.prev_head(prev2_addr) prev4_addr = idc.prev_head(prev3_addr) prev5_addr = idc.prev_head(prev4_addr) if ( idc.print_insn_mnem(prev1_addr) == "MOV" and idc.print_operand(prev1_addr, 0) == "W16" and idc.print_operand(prev1_addr, 1) == "#0x1A" and idc.print_insn_mnem(prev2_addr) == "MOV" and idc.print_operand(prev2_addr, 0) == "X3" and idc.print_operand(prev2_addr, 1) == "#0" and idc.print_insn_mnem(prev3_addr) == "MOV" and idc.print_operand(prev3_addr, 0) == "X2" and idc.print_operand(prev3_addr, 1) == "#0" and idc.print_insn_mnem(prev4_addr) == "MOV" and idc.print_operand(prev4_addr, 0) == "X1" and idc.print_operand(prev4_addr, 1) == "#0" and idc.print_insn_mnem(prev5_addr) == "MOV" and idc.print_operand(prev5_addr, 0) == "X0" and idc.print_operand(prev5_addr, 1) == "#0x1F" ): print '查找到一条MOV指令' # 将相干指令设为nop idc.PatchDword(addr, 0xd503201f) # nop idc.PatchDword(prev1_addr, 0xd503201f) # nop idc.PatchDword(prev2_addr, 0xd503201f) # nop idc.PatchDword(prev3_addr, 0xd503201f) # nop idc.PatchDword(prev4_addr, 0xd503201f) # nop idc.PatchDword(prev5_addr, 0xd503201f) # nopprint("End")执行前:按下图操作执行上边的脚本
...