写点什么

【iOS 逆向与安全】利用 IDAPython 插件提高反汇编和逆向工程效率

作者:小陈
  • 2023-03-27
    中国香港
  • 本文字数:2140 字

    阅读完需:约 7 分钟

前言

IDA Python 是一个用 Python 语言编写的插件,它为 IDA Pro 提供了可扩展性和自动化脚本支持。使用 IDA Python,可以以更快、更简单的方式完成反汇编和逆向工程任务。



1、目标

快速了解和开始使用 idapython。


2、开发环境和工具清单

  • mac 系统

  • IDA Pro7.0


3、常用 API

idaapi 模块:该模块提供了许多核心的 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 0x80
复制代码

idapython 脚本如下:

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")
复制代码

执行前:



按下图操作执行上边的脚本




执行后效果如下:



总结

这篇文章小牛试刀的介绍如何在 IDA 中使用 IDAPython 插件,这只是一部分应用场景,期待大家继续探索更多用法。


提示:阅读此文档的过程中遇到任何问题,请关住工众好【移动端Android和iOS开发技术分享】或+99 君羊【812546729



发布于: 刚刚阅读数: 3
用户头像

小陈

关注

和昨天不一样 2019-03-12 加入

公众号:移动端Android和iOS开发技术分享

评论

发布
暂无评论
【iOS逆向与安全】利用IDAPython插件提高反汇编和逆向工程效率_安全_小陈_InfoQ写作社区