IDAPython手册

IDAPython 手册(翻译by y0n)

介绍

这是一本关于IDAPython的手册,我最初写它是作为自己参考的,在我通常使用IDAPython(忘记了)我想在某处能找到函数的例子。自从我开始这本书以来,我多次使用它作为快速参考来理解语法或者查看一些例子代码。

如果你跟随我的博客,你可能会注意到一些熟悉的面孔–很多脚本,我在下面贴出了一些在线实验的结果。

多年来,我收到许多电子邮件,问对于IDAPython什么是最好的学习指南?通常我会给他们指出Ero Carrera介绍的idapython或在idapython的公共的repo示例脚本。它们是学习的极好来源,但它们并没有涉及到我遇到的一些常见问题。我想写一本书,涵盖了这些问题。我觉得对于学习idapython的人或者想快速参考学习例子和代码片段的人是有价值的。作为电子书,它不会是静态的。我计划在未来定期更新它。

如果您遇到任何问题,错别字或有疑问,请发邮件给我。

更新

版本:1.0

免责声明

这本书不是为初学逆向工程的人设计的。它也不能作为一本介绍IDA的书。如果你是刚开始接触IDA,我建议你买Chris Eagles的IDA Pro。这本书是优秀的且值得花钱的。

购买这本书有两个先决条件,你应该能很轻松的阅读汇编在一个你想工程的背景下并且知道你所使用的IDA。如果你碰到一个问题,问自己“如何使用IDAPython自动化完成一个任务?”那么这本书可能适合你。如果你已经有一些IDAPython编程,在这种情况下这本书不适合你。这本书适合初学IDAPython的人,它将作为一个手册方便查找例子,常用函数,但是有经验的你已经有了自己的一些脚本参考。

应该说,我的背景是恶意代码逆向工程,本书不涉及编译器概念,如静态分析中使用的基本块或其他学术概念。原因是,当逆向工程恶意软件时,我很少使用这些概念。偶尔我也用它们去混淆代码基本够用,我觉得他们会对初学者来说是有价值的。读了这本书之后,读者会感觉轻松并挖掘自己idapython文档。最后一个免责声明,IDA调试器的功能不包括在内。

规定

IDA的输出窗口(命令行接口)用于示例和输出。为了简洁起见,有些示例不包含当前地址对变量的赋值。通常表示为EA= here()。所有的代码都可以剪切和粘贴到命令行或IDA的脚本命令的选项shift-f2。从头到尾阅读是本书推荐的方法。有许多例子并不是一行一行解释的,因为它假定读者理解前面例子中的代码。不同的作者调用IDAPython的方式不同,有时候被调用为idc.SegName(ea) 或者SegName(ea)。在这本书中,我们将使用第一个风格。我发现这个约定更容易阅读和调试。有时使用这个约定时,会抛出一个错误,如下所示:

Python>DataRefsTo(here())

<generator object refs at 0x05247828>

Python>idautils.DataRefsTo(here())

Traceback (most recent call last):

File "<string>", line 1, in <module>

NameError: name 'idautils' is not defined

Python>import idautils # manual importing of module

Python>idautils.DataRefsTo(here())

<generator object refs at 0x06A398C8>

如果这种情况发生则需要在显示前包含模块。

IDAPython背景

IDAPython创建于2004年。这是GergelyErdelyi和Ero Carrera的共同努力。他们的目标是结合强大的python与自动化分析的IDA的类C脚本语言IDC。IDAPython由三个独立模块组成。第一个是idc,它是封装IDA的IDC函数的兼容性模块。第二个模块是idautils,这是IDA里的一个高级实用函数。第三个模块是idaapi,它允许访问更多低级数据,这些数据能够被类使用通过IDA。

基础

在挖掘得太深之前,我们应该定义一些关键字,并检查IDA的反汇编输出的结构。我们可以使用下面的代码行作为示例。

Python>ea = idc.ScreenEA()

Python>print "0x%x %s" % (ea, ea)

0x12529 75049

Python>ea = here()

Python>print "0x%x %s" % (ea, ea)

0x12529 75049

Python>hex(MinEA())

0x401000

Python>hex(MaxEA())

0x437000

获取表示段名的字符串我们会使用idc.SegName(ea)ea是一个段地址。打印一个反汇编的字符串可以用idc.GetDisasm(ea)。值得注意的是函数的拼写。获取助记符或者指令名称,我们可以调用idc.GetMnem(ea)。获取操作数的助记符我们可以调用idc.GetOpnd(ealong n)。第一个参数是地址,第二个long n是操作数索引。第一个操作数是0和第二个是1。

在某些情况下,验证一个地址是否存在是很重要的。idaapi.BADADDRBADADDR可以用来检验有效地址。

Python>idaapi.BADADDR

4294967295

Python>hex(idaapi.BADADDR)

0xffffffffL

Python>if BADADDR != here(): print "valid address"

valid address


Segments(段)

打印一行作用不大。IDAPython的强大来自于遍历所有的指令,交叉引用地址和搜索代码或数据。后面两部分将在后面更详细地描述。遍历所有段将是一个不错的开始的位置。

Python>for seg in idautils.Segments():

print idc.SegName(seg), idc.SegStart(seg), idc.SegEnd(seg)

HEADER 65536 66208

.idata 66208 66636

.text 66636 212000

.data 212000 217088

.edata 217088 217184

INIT 217184 219872

.reloc 219872 225696

GAP 225696 229376

idautils.Segments()返回一个遍历类型对象,我们可以循环这个对象通过使用一个for循环。列表中的每个项都是段的起始地址。如果我们把它作为作为一个参数去调用idc.SegName(ea),地址可以被用来获取名称。开始和结束的段可以通过调用idc.SegStart(ea)或idc.SegEnd(ea)获得。地址或ea需要位于段的开始或结束的范围内。如果我们不想遍历所有段,但想找到下一段我们可以使用idc.NextSeg(ea)。地址可以是段范围内的任何我们希望找到的下一段的地址。如果有机会我们想要通过名称获取一个段的开始地址,我们可以使用idc.SegByName(segname)。



-------------

英文文档:http://download.csdn.net/download/u011337769/9942105

翻译完整版:http://download.csdn.net/download/u011337769/10051859

*第一次翻译,仅参考,如有错误欢迎交流学习~


猜你喜欢

转载自blog.csdn.net/u011337769/article/details/77428914