IDApython教程(五)
我们继续IDAPython让生活更美好序列,这一部分我们解决逆向工程师日常遇到的问题:提取执行的内嵌代码。
恶意软件会用各种方式存储内嵌可执行代码,有些恶意软件将内嵌代码加到文件附加段,包括PE资源区段,或者存放在恶意软件的缓冲区中。
当遇到这个情况,恶意软件分析者可以有几个选择:
可以动态运行样本在写入和提取的后面下断点或者如果文件存储在资源段,可以使用一些工具比如CFFExplorer 提取资源数据,在IDA中可以高亮选取可疑的二进制数据,然后右键保存想要的提取的数据。
虽然这几个方法都可行,但是都有一些限制。而自动化提取内嵌代码可以节省分析者大量的时间。为了实现这个目的,我们会用到IDAPython的第三方链接库组件‘pefile’。而这里也会带来一些挑战:
1. 我们必须在IDA环境中用PIP安装第三方python链接库
2. 已经标识出了内嵌代码
3. 需要计算要提取的可执行代码的大小
让我们一次性的解决这些问题吧。
在IDA PRO中加入第三方PYTHON链接库
在IDA中用PIP安装第三方python链接库之后,如何让其生效是一个有趣的挑战。而如果不修改的话是没有办法加载第三方链接库的,比如pefile的IDAPython解释中会出现如下错误。
为了修正这个错误,我们必须将PIP的‘site-packages’目录加到PYTHON的环境变量中。可以使用如下代码实现:
import sys
print sys.path Result:
['/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python27.zip', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin', '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac', '<Truncated>']
而这里为了包含PIP安装链接库,我们可以简单的将‘site-packages’目录加到pefile包含声明数组中。但是这个方案不太好,因为这需要分析者人工识别‘site-packages’目录,但是我没要找到跨平台的解决方案。加入相关代码之后,我们就能够加载pefile链接库了。
需要内嵌代码
为了找到恶意软件包含的所有内嵌代码,我们基于MZ头的已知字符串对二进制进行搜索。分析者请确认已经勾选了‘Load resources’选项这样才能够读取到作为资源存储的所有数据。另外的,如果内嵌文件包含在附加段中,为了在IDA中能够看到数据一定要勾选’Manual load’选项。
现在我们已经有了IDA中加载的必要信息了,现在我们可以开始在PE32文件中搜索数据了。我们有好几种方法可以实现,但我选择搜索所有MZ头中都会包含的静态信息,如下所示:
为了找到IDA中所有的字符串事件,我们可以使用循环调用FindBinary()函数来寻找二进制字符串的每一次实例。代码如下:
def find_string_occurrences(string):
results = []
base = idaapi.get_imagebase() + 1024
while True:
ea = FindBinary(base, SEARCH_NEXT|SEARCH_DOWN|SEARCH_CASE, '"%s"' % string)
if ea != 0xFFFFFFFF:
base = ea+1
else:
break
results.append(ea)
return results
当在PE32文件中寻找MZ头字符串标识时,我们需要验证‘MZ’字符存在于MZ头的开始处。由于我们之前找的字符串在静态偏移是固定的,我们只需要简单的确定‘MZ’的已知偏移就可以了。
def find_embedded_exes():
results = []
exes = find_string_occurrences("!This program cannot be run in DOS mode.")
if len(exes) > 1:
for exe in exes:
m = Byte(exe-77)
z = Byte(exe-76)
if m == ord("M") and z == ord("Z"):
mz_start = exe-77
print "[*] Identified embedded executable at the following offset: 0x%x" % mz_start
results.append(mz_start)
return results
将上面的代码组合到一起,来找到IDA中所有的内嵌代码。
确定可执行代码的大小
为了确定找到的内嵌代码的大小,我们将使用前面提到的python第三方pefile链接库。这个链接库可以解析各种可执行文件头,这样我们就能够计算PE文件的大小了。为了实现这个目的,我们会在可选头中加入’SizeOfHeaders’参数,连同每个段的’SizeOfRawData’字段。下面的代码会读出标识出的内嵌代码的前1024字节,用pefile解析这些数据,计算各个段的大小。
def calculate_exe_size(begin):
buff = ""
for c in range(0, 1024):
buff += chr(Byte(begin+c))
pe = pefile.PE(data=buff)
total_size = 0
# Add total size of headers
total_size += pe.OPTIONAL_HEADER.SizeOfHeaders
# Iterate through each section and add section size
for section in pe.sections:
total_size += section.SizeOfRawData
return total_size
最后,我们可以使用这些大小值来提取可执行代码数据然后写入我们选择的文件中。
def extract_exe(name, begin, size):
buff = ""
for c in range(0, size):
buff += chr(Byte(begin+c))
f = open(name, 'wb')
f.write(buff)
f.close()
结论
将这些组合到一起,我们将会得到下面的脚本。
https://github.com/pan-unit42/public_tools/blob/master/ida_scripts/idapython_pt5.py
在恶意样本中运行这个例子,将会得到下面的结果:
正如我们看到的,我们能够在IDA中自动提取PE文件了。通过一些小修改,这个实现能够应用到其他类型的文件中。我希望这个教程能够让逆向工程师知道IDAPython能够实现很多难以置信的功能。
*原文地址:Paloaltonetworks,东二门陈冠希/编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)
IDApython教程(五)的更多相关文章
- CRL快速开发框架系列教程五(使用缓存)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- C#微信公众号开发系列教程五(接收事件推送与消息排重)
微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...
- 无废话ExtJs 入门教程五[文本框:TextField]
无废话ExtJs 入门教程五[文本框:TextField] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个文本框.如下所示代码区的第42行位置,items: ...
- Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程五--Gradle命令详解与导入第三方包 2015 年 01 月 05 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://s ...
- Laravel教程 五:MVC的基本流程
Laravel教程 五:MVC的基本流程 此文章为原创文章,未经同意,禁止转载. Controller 期间受到很多私事影响,终于还是要好好写写laravel的教程了. 上一篇我们说了数据库和Eloq ...
- WCF入门教程五[WCF的通信模式]
一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...
- NGUI系列教程五(角色信息跟随)
在一些网络游戏中,我们常常可以看到角色的上方显示着角色的名称,等级,血量等信息.它们可以跟随角色移动,并且可以显示和隐藏.今天我们就来学习一下这些功能的实现方法.1. 新建unity工 程,导入NGU ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(五) Data Access Application Block 企业库数据库访问模块通过抽象工厂模式,允许用户 ...
- 无废话WCF入门教程五[WCF的通信模式]
一.概述 WCF在通信过程中有三种模式:请求与答复.单向.双工通信.以下我们一一介绍. 二.请求与答复模式 描述: 客户端发送请求,然后一直等待服务端的响应(异步调用除外),期间处于假死状态,直到服务 ...
- Swift中文教程(五)--对象和类
原文:Swift中文教程(五)--对象和类 Class 类 在Swift中可以用class关键字后跟类名创建一个类.在类里,一个属性的声明写法同一个常量或变量的声明写法一样,除非这个属性是在类的上下文 ...
随机推荐
- [WC2018]州区划分(FWT)
题目描述 题解 这道题的思路感觉很妙. 题目中有一个很奇怪的不合法条件,貌似和后面做题没有什么关系,所以我们先得搞掉它. 也就是判断一个点集是否合法,也就是判断这个点集是否存在欧拉回路. 如果存在欧拉 ...
- [HNOI2015]菜肴制作(拓扑排序)
知名美食家小 A被邀请至ATM 大酒店,为其品评菜肴. ATM 酒店为小 A 准备了 N 道菜肴,酒店按照为菜肴预估的质量从高到低给予1到N的顺序编号,预估质量最高的菜肴编号为1. 由于菜肴之间口味搭 ...
- hdu 1978 How many ways(记忆化搜索)
这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下:1.机器人一开始在棋盘的起始点并有起始点所标有的能量.2.机器人只能向右或者向下走,并 ...
- 牛客小白月赛12 F 华华开始学信息学 (分块+树状数组)
链接:https://ac.nowcoder.com/acm/contest/392/F来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 32768K,其他语言65536K ...
- Python3 与 C# 基础语法对比(String专栏)
Code:https://github.com/lotapp/BaseCode 多图旧排版:https://www.cnblogs.com/dunitian/p/9119986.html 在线编程 ...
- 搭建高可用的Redis服务,需要注意这些方面!
搭建高可用的Redis服务,需要注意这些方面! HorstXu 占小狼的博客 今天 ◎作者 | HorstXu www.cnblogs.com/xuning/p/8464625.html 基于内存的R ...
- Django 子程序
在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,在其他工程项目中需要用到某个特定功能模块时,可以将该 ...
- Keyboard Hook API函数 参数说明
来源:https://www.cnblogs.com/grenet/archive/2010/12/07/1898840.html 1.Keyboard的HOOK函数分为两种,WH_KEYBOARD_ ...
- win32-api: 让 static 控件中的水平横行,垂直居中。
CreateWindowEx(....., SS_CENTER | SS_CENTERIMAGE); SS_CENTER 能让文字水平居中. SS_CENTERIMAGE 能让文字垂直居中. htt ...
- codeblocks: 使用动态链接库(pcre)的配置
说明:在c/c++程序中使用动态链接库, 编译后需要相关的dll文件(如:libpcre-1.dll,libpcreposix-0.dll)才能正常的运行. 2014-06-27