您的位置:

idapython在逆向工程中的多个应用

一、基本语法和用法

idapython是IDA Pro的Python API,可以通过Python脚本扩展IDA Pro的能力,进行自定义的二进制分析和逆向工程。这里我们从基本语法和用法开始介绍idapython。

首先,我们需要安装IDA Pro,然后在IDA Pro中打开一个二进制文件,选择File菜单中的"Script file"选项,或者按快捷键Alt-F7打开脚本编辑界面,就可以输入我们的idapython脚本了。

下面是一个简单的例子:


#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
一个用来测试的 idapython 脚本
"""

import idaapi

# 获取当前处在哪个地址
ea = idaapi.get_screen_ea()

# 获取该地址的指令
inst = idaapi.decode_insn(ea)

# 显示该指令的反汇编
print idaapi.generate_disasm_line(ea, inst)

这个脚本通过调用IDA Pro提供的Python API,获取当前光标所在地址的指令,并显示该指令的反汇编。我们可以将该脚本保存为.py文件,然后运行该脚本即可。

二、数据结构和算法

idapython提供了各种数据结构和算法,帮助分析二进制文件。这里我们介绍几个比较有用的数据结构和算法。

1. Operand类

Operand类表示指令的一个操作数。使用Operand可以获取操作数的类型、宽度以及值。使用示例如下:


# 获取当前光标所在地址的指令
ea = idaapi.get_screen_ea()
inst = idaapi.decode_insn(ea)

# 获取第一个操作数的类型
op_type = inst.ops[0].type

# 获取第二个操作数的值
op_value = inst.ops[1].value

2. Xrefs类

Xrefs类表示指向或被指向某个地址的引用。使用Xrefs可以获取一个地址的引用信息,包括引用该地址的地址列表,以及该地址引用其他地址的地址列表。使用示例如下:


# 获取当前光标所在地址的xrefs信息
ea = idaapi.get_screen_ea()
xrefs = idaapi.get_xreflist(ea)

# 获取引用该地址的地址列表
from_addrs = [xref.frm for xref in xrefs]

# 获取该地址引用其他地址的地址列表
to_addrs = [xref.to for xref in xrefs]

3. Disasm类

Disasm类表示二进制文件的反汇编信息。使用Disasm可以遍历整个二进制文件的反汇编信息,获取每个地址的反汇编指令以及各种操作数的信息。


# 遍历整个二进制文件的反汇编信息
for ea in idautils.Segments():
    for head in idautils.Heads(ea, idaapi.get_segm_end(ea)):
        inst = idaapi.decode_insn(head)
        disasm = idaapi.generate_disasm_line(head, inst)
        print disasm

4. Graph类

Graph类表示二进制文件的控制流图。使用Graph可以生成函数的控制流图,并进行各种操作,比如节点着色、节点添加、节点合并等等。


# 获取当前光标所在函数的控制流图
ea = idaapi.get_screen_ea()
func = idaapi.get_func(ea)
fcg = idaapi.FlowChart(func)

# 着色第一个节点
node = fcg[0]
node.color = 0xff0000

# 添加一个节点
newnode = node.split(node.is_cref_from)
newnode.color = 0xffff00

# 合并第二个节点
nextnode = newnode.succs()[0]
newnode.append(nextnode)
newnode.color = 0x00ff00

三、插件开发

除了使用idapython脚本来扩展IDA Pro的能力,我们还可以开发idapython插件来实现更复杂的功能。下面我们介绍如何开发一个idapython插件。

1. 创建Python模块

我们可以使用Python的setuptools来创建Python模块。首先,我们需要创建一个空的Python模块,然后使用setuptools来打包模块。具体步骤如下:

在命令行中执行以下命令:


mkdir myplugin
cd myplugin
touch __init__.py
nano setup.py

然后,将以下内容添加到setup.py文件中:


from setuptools import setup

setup(
    name="MyPlugin",
    version="0.1",
    description="An idapython plugin",
    packages=["myplugin"]
)

这样就创建了一个名为MyPlugin的idapython插件。

2. 添加菜单项

我们可以通过在idapython脚本中添加菜单项,来调用我们的插件。具体步骤如下:

在myplugin目录下创建一个menu.py文件,将以下内容添加到该文件中:


import idaapi

class MyPluginMenu(idaapi.action_handler_t):
    @classmethod
    def get_name(cls):
        return "myplugin:menu"

    @classmethod
    def get_label(cls):
        return "MyPlugin"

    def activate(self, ctx):
        # 在此处添加插件的代码
        print "MyPlugin activated!"

    def update(self, ctx):
        return idaapi.AST_ENABLE_ALWAYS

# 注册菜单项
action_desc = idaapi.action_desc_t(
    MyPluginMenu.get_name(),
    MyPluginMenu.get_label(),
    MyPluginMenu(),
    None,
    None,
    0
)
idaapi.register_action(action_desc)

# 添加菜单项到Edit菜单
idaapi.attach_action_to_menu(
    "Edit/Other/",
    MyPluginMenu.get_name(),
    idaapi.SETMENU_APP
)

这样就在IDA Pro的Edit菜单下添加了一个MyPlugin菜单项。

四、结合其他Python库

idapython使用Python编写,因此可以结合其他Python库来扩展其能力。这里以使用网络库requests为例介绍如何结合其他Python库。

首先,我们需要安装requests库。在命令行中执行以下命令:


pip install requests

然后,我们可以在idapython脚本中引入requests库。具体使用示例如下:


import requests

url = "http://www.baidu.com"
response = requests.get(url)

# 显示网页内容
print response.text

这样就可以使用requests库来发起HTTP请求,并获取网页的内容。

五、结语

本文介绍了idapython在逆向工程中的多个应用,包括基本语法和用法、数据结构和算法、插件开发以及结合其他Python库。希望这些内容能够对大家的逆向工程工作有所帮助。