欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

IDApython插件编写及脚本批量分析教程

程序员文章站 2022-03-18 21:49:28
...

0x00 前言

本文主要介绍了在IDA中编写IDApython插件的框架,还有利用IDApython脚本批量分析二进制文件的方法。

0x01 IDApython插件编写

介绍

在IDA中有很多插件供逆向分析人员使用,插件可以实现对二进制文件的自动化分析。通过插件的使用,可以大大提高分析的效率和准确率。同时,IDA也提供了IDApython的编程接口,让我们可以编写自己的插件脚本,实现自定义的插件功能。

IDApython主要有三个模块(这个我忘记在哪里看的了,之前摘的笔记,侵删):

  1. idc:兼容IDA Pro中idc函数的模块;
  2. idautils:逆向分析中常用的一个模块,大多数处理方法都是需要依托于这个模块;
  3. idaapi:该模块允许使用者通过类的形式,访问更多底层的数据;

框架

插件的代码可以分为两部分,这两个部分在IDA安装目录下pluginspython文件夹中:

  • plugins目录下的插件类,用于实例化插件对象,以及作为插件调用的入口,用来调用自定义的插件模块中的功能代码;
  • 另一个是在python目录中定义的插件模块,实现了自定义的插件的功能;

代码

文件结构为:

  • IDA Pro安装目录
    • plugins
      • listFuncPlugin.py
    • python
      • listFunc
        • __init__.py
        • listFuncImpl.py

让我们从示例代码来理解,假设我们要实现一个列举出二进制文件中所有函数名的插件,在plugins文件夹中创建文件listFuncPlugin.py,在python文件夹下,创建一个文件夹叫listFunc,在listFunc文件夹下,创建__init__.pylistFuncImpl.py

首先看一下插件类listFuncPlugin.py的代码。在该文件中,需要实现插件类ListFunc,以及一个PLUGIN_ENTRY函数,该函数用于生成一个插件实例对象。在插件类中,除了定义插件的名称,快捷键等信息,还需要实现三个方法:

  • init()方法:初始化操作,比如打印提示信息,导入功能模块;
  • run()方法:插件的入口函数,调用功能模块的函数;
  • term()方法:结束时调用的方法;
# -*- coding:utf-8 -*-

# ======= import =======
import idautils
import idaapi
import idc
from datetime import datetime


class ListFunc(idaapi.plugin_t):  # 继承 idaapi.plugin_t
    """
    插件类
    """
    flags = idaapi.PLUGIN_UNL
    comment = "List all functions in this binary file."

    wanted_name = "listfunc"  # 插件的名称,在IDA界面导航栏中显示 Edit->Plugins->myplugin
    wanted_hotkey = "Alt-F6"  # 插件的快捷键
    help = "Coming soon..."

    def init(self): 
        """
        初始化方法
        """
        idaapi.msg(">>> My plugin starts. {0}\n".format(datetime.now()))
        
        # 导入python目录下的功能模块
        idaapi.require("listFunc")
        idaapi.require("listFunc.listFuncImpl")

        return idaapi.PLUGIN_OK  # return PLUGIN_KEEP
    
    def run(self, arg):
        listFunc.listFuncImpl.main()  # 注意这里的调用方式是从python中模块的文件夹开始
    
    def term(self):
        idaapi.msg(">>> My plugin ends. {0}\n".format(datetime.now()))


def PLUGIN_ENTRY():
    """
    实例化插件对象
    """
    return ListFunc()

接下来在python文件夹的listFunc目录中,先创建__init__.py文件,因为IDApython是Python2.7,所以添加该文件表明该目录是一个模块,如果没有这个文件的话,在运行插件的时候会报错:No module named xxx

然后编写目录下的listFuncImpl.py,这里的main()方法就是在插件类中run()方法调用的函数。

# -*- coding:utf-8 -*-

# ======= import =======
import idautils
import idaapi
import idc
from datetime import datetime


def main():
    for i, func in enumerate(idautils.Functions()):
        func_name = idc.GetFunctionName(func)  # 函数名
        print("{0} function name is: {1}".format(i, func_name))

if __name__ == '__main__':
    main()

到这里,插件的实现就完成了,接下来只需要用IDA打开二进制文件以后,按下插件的快捷键,就能执行自定义的插件了。

0x02 脚本批量分析

介绍

既然我们可以用IDApython编写的脚本对二进制文件进行自动化分析,那么,在实际情况中,我们可能会遇到需要分析很多个二进制文件的情况。在这个应用场景下,就需要用IDA提供的命令行接口来调用IDApython脚本,进行二进制文件的批量分析处理。

思路

思路就是,先用python编写一个调用脚本,在该脚本中,利用python的命令行接口,调用IDApython的分析程序,对遍历得到的二进制文件进行分析处理。

代码

还是一样,通过代码来理解如何使用哈。假设我们这里实现的是一个对很多二进制文件进行分析,得到二进制文件中的函数名。

首先是分析脚本,analysis.py,这个脚本就和0x01中的功能模块脚本一样,这里不再赘述,需要注意的是,由于分析脚本是被调用的,所以要在文件末尾添加if __name__=='__main__',从而能够调用该文件中的分析方法。

然后就是调用脚本,run.py

# -*- coding:utf-8 -*-

# =======Import =======
import os
import subprocess


dir_path = "D://transfer/"  # 原始数据的文件夹
ida64_path = "D://ProgramFiles/IDA/ida64.exe"  # ida64的路径
ana_file = "D://listFunc/listFuncImpl.py"  # 分析文件的路径

def run():
    for root, dirs, files in os.walk(dir_path):
        for file_name in files:
            file_path = os.path.join(root, file_name)
            cmd = "{0} -LD:/mylog.log -c -A -S{1} {2}".format(ida64_path, ana_file, file_path)
            p = subprocess.Popen(cmd)
            p.wait()


if __name__ == "__main__":
    run()    

-L表示输出的日志路径,-c表示对二进制文件进行反汇编,-A表示自动模式,IDA不会提示一些信息,会自动处理,-S后面的路径是分析脚本的路径
其中,-L-S与后面的路径之间是没有空格的。

比如,cmdD://ProgramFiles/IDA/ida64.exe -LD:/mylog.log -c -A -SD://listFunc/listFuncImpl.py D://transfer/m64-O0\aes-x86_64.o

调试的小技巧: 由于我们是通过命令接口进行调试的,这样有一个很不方便的地方就是,如果分析脚本中出错了,很难拿到报错信息。这里我提供两个思路,第一个就是在run.py中代码所示的那样,将运行结果输出到log文件中。还有一种思路就是在分析脚本中,使用python中的traceback模块捕获信息。

0x03 后记

明天晚上就要回学校了,下午写了这篇最近一直想总结,但是没时间做的内容。在这边实习了大半年,学到了很多知识。组里的氛围真的很好,师兄师姐和导师都很nice! 在这边也意识到,科研没有自己想象中的那么理想,不过真正的英雄主义就是认清科研的本质并热爱她?希望自己研究生能在专业方面做出点成绩吧。好好努力,好好耍哈哈哈!

烦心的毕设快要结束了,红公保庇我能顺利毕业吧!还有两三个月就要毕业了,我的马鸭!高中毕业典礼的场景还历历在目,不瞒你说我是最经受不住分别的人了。接下来应该会写一篇大学四年的总结吧。


0x04 参考资料

  1. 倚天屠龙(一):妙用IDA Pro–利用IDAPython编写调试插件
  2. flare-ida
  3. IDAPyhon 脚本批量分析程序