IDAPython教程(三)
在过去两个部分中,我们已经讨论了使用IDAPython让逆向工程更容易一些。这一部分我们来看一下条件断点。
当在IDA中调试时,分析者经常会遇到希望可以在一个特殊的地址中断下来的情况,但这只有在一些特定的情况能够触发。
一个典型的例子:只有在特殊的参数传递进去的时候,才能断到一个特殊的函数的调用处。另外一个实例:我希望我的分析虚拟机加载一个特定的链接库时能够产生中断。
今天,我们来看看如何用IDAPython来解决这个特殊的问题。
背景
在进行分析时经常会逆向DLL。在这类实例中,这些文件通常都是被其他可执行文件加载的。解决这个问题的一个方案是确保调试器在每个链接库加载时都能中断下来,然后DLL或者驱动最后加载完的时候才能停下来。
但事实上这种方法其实是很低效的。通常需要分析者人工停止和开始:继续执行,判断哪些最近使用的链接库和驱动是想要断下来的。
其实简单的运行一条命令,然后坐着等待感兴趣的文件被加载进来,会让分析工作变得更简单。
条件断点
在这个特殊的例子中,我们将会使用’dd.dll’文件。这个特殊的文件在运行时被提取之后会执行一个利用过程注入到其他进程中。为了在IDA中运行这个动态链接库,我将会加载可执行文件rundll32.exe将其关联到system32目录,这样能够将dd.dll文件作为参数传进来,就像下面这张图能够看到的。然后rundll32.exe可以让用户通过给定的导出名,加载一个特定的DLL。在这个特定的样本中,我对DLL的导出函数’Setting’比较感兴趣。我在IDA中填入了下面这些参数:
下一个步骤是,在DLL被可执行文件加载进来之后找到正确的地方设置断点。 为了达到这个目的,我先在调试器中勾选了‘Suspend on library load/unload’选项。当暂停在第一个DLL实例被加载进来之后,我们可以看到断点设在了NtMapViewOfSection函数调用的后一句。
接下来我在0x7C91ADFB 地址处下了一个断点。 在我的代码中,我调用add_bpt() 和enable_bpt() 函数来创建和生效断点。
'''
ntdll.dll:7C91ADF1 push 0FFFFFFFFh
ntdll.dll:7C91ADF3 push dword ptr [ebp-20h]
ntdll.dll:7C91ADF6 call near ptr ntdll_NtMapViewOfSection
ntdll.dll:7C91ADFB mov edi, eax
''' address = 0x7C91ADFB # Just after NtMapViewOfSection
add_bpt(address, 0, BPT_SOFT)
enable_bpt(address, True)
在这个步骤,我已经在0x7C91ADFB 处设置了断点,每次DLL加载进来的时候调试器都会中断下来。为了确保只有在’dd.dll’加载进来的时候才会中断,我们必须使用条件断点。分析者可以使用代码来判断条件断点是否真的被触发(不管用IDC或者Python都行)。如果代码返回值为True,断点会被触发,否则,断点将会被忽略。 我们首选Python作为编程语言。 然后我们将Python代码存储到变量中,然后将这个变量传递给SetBptCnd()函数,这个函数会将这个代码作为条件设置到断点上。 这个条件设置之后,我们让调试器继续运行,然后等待调试器暂停事件触发。伪代码如下所示:
address = 0x7C91ADFB # Just after NtMapViewOfSection
RunPlugin("python", 3) # Python default programming
StartDebugger("","",""); dll = "dd.dll"
condition = """
for m in Modules():
if "%s".lower() in m.name.lower():
print "Breaking on", m.name.lower()
del_bpt(%d)
return True
return False
""" % (dll, address) add_bpt(address, 0, BPT_SOFT)
enable_bpt(address, True)
SetBptCnd(address, condition) continue_process()
GetDebuggerEvent(WFNE_SUSP, -1)
现实中使用的条件代码如下所示:
for m in Modules():
if "dd.dll".lower() in m.name.lower():
print "Breaking on", m.name.lower()
del_bpt(0x7C91ADFB)
return True
return False
这个代码会反复的查找’dd.dll’是否被加载进来。 如果是,会打印调试信息,最开始的断点被删除掉了,返回的布尔值为True时,断点就会被触发。我们运行程序,IDA窗口中输出如下信息:
下面这个步骤,我们会对导出函数’Setting’设置断点然后运行程序直到断点触发。为了自动完成这个步骤,我们可以使用下面的代码:
def get_names(base, size, desired_name):
current_address = base
while current_address <= base+size:
current_address = NextHead(current_address)
print hex(current_address)
if desired_name in Name(current_address):
return current_address
for m in Modules():
if 'dd.dll' in m.name.lower():
base = m.base
size = m.size
analyze_area(base, base+size)
setting = get_names(base, size, "Setting")
if setting:
add_bpt(setting, 0, BPT_SOFT)
enable_bpt(setting, True)
continue_process()
GetDebuggerEvent(WFNE_SUSP, -1)
这段代码反复的在加载的模块中查找’dd.dll’。找到之后,分析包含DLL的代码。 然后在这段代码中寻找’Setting’函数。一旦找到,就在这个地址设置断点,让调试器继续执行,等待断点触发。执行程序,我们可以看到正如我们预期的那样断点在我们想要的地址上中断下来。
结论:
设置条件断点看起来是一个非常小的技术点, 但是能够节省分析者大量的时间。一个很小的代码片段能够代替我们完成一次次手动的寻找我们想要的断点这么繁琐的工作。我们又一次借助 IDAPython的力量来简化我们的逆向工作,帮助我们节省了大量的时间和精力。
*原文:Paloalto 东二门陈冠希/编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)
IDAPython教程(三)的更多相关文章
- CRL快速开发框架系列教程三(更新数据)
本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...
- 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)
前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...
- 无废话ExtJs 入门教程三[窗体:Window组件]
无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...
- CocoStudio教程三:认识并利用CocoStudio的果实 运行2.2.1版本
原文:CocoStudio教程三:认识并利用CocoStudio的果实 原文用的老版,用2.21搞起来好像有些问题,然后自己摸索了下,有的都是乱找的方法,只求能运行... 1,原文的CCJsonRea ...
- Android Studio系列教程三--快捷键
Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...
- Laravel教程 三:视图变量传递和Blade
Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...
- NGUI系列教程三
接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...
- 中文翻译:pjsip教程(三)之ICE stream transport的使用
1:pjsip教程(一)之PJNATH简介 2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介 3:pjsip教程(三)之ICE ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (高级)
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (高级) 企业库验证应用程序模块之配置文件模式: ...
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (初级)
原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (初级) 企业库提供了一个很强大的验证应用程序模 ...
随机推荐
- [HEOI2014]平衡(整数划分数)
下课了,露露.花花和萱萱在课桌上用正三棱柱教具和尺子摆起了一个“跷跷板”. 这个“跷跷板”的结构是这样的:底部是一个侧面平行于地平面的正三棱柱教具,上面 摆着一个尺子,尺子上摆着若干个相同的橡皮.尺子 ...
- 编译安装Nginx和PHP(带编译mysql)
应用场景:目前常见的LNMP架构中很多服务都采用nginx+fastcgi+php来提供服务. 测试环境:Centos 7.2 / Nginx 1.12.0 / PHP 5.6 配置步骤: 1. 下载 ...
- linux(fedora) 第二课
vi 文件名(一般模式 编辑模式 命令模式) 一般模式 (不可编辑 按 a,i,o可以切换为编辑模式): 1.删除n行:按下想删除的行数+dd 编辑模式(编辑模式 可以浏览,查找,编辑 按‘:” 可以 ...
- hdu 4300 Clairewd’s message(扩展kmp)
Problem Description Clairewd is a member of FBI. After several years concealing in BUPT, she interce ...
- Codeforces Round #487 (Div. 2) C - A Mist of Florescence
C - A Mist of Florescence 把50*50的矩形拆成4块 #include<bits/stdc++.h> using namespace std; ],b[]; ][ ...
- J2EE--常见面试题总结 -- ( 一)
StringBuilder和StringBuffer的区别: String 字符串常量 不可变 使用字符串拼接时是不同的2个空间 StringBuffer 字符串变量 可变 ...
- MyBatis深入浅出--入门
mybatis概述 mybatis简介 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. ...
- JDK和CGLIB动态代理区别
背景:虽然自己了解这两种代理的区别,但是面试时候还是答的很模糊,需要好好总结. 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/de ...
- org.apache.poi 读取数字问题
默认呢,POI读取单元格内容为数字的话,自动搞成Dubbo类型的,比如这样: String value1 = row.getCell(0).getNumericCellValue()+"&q ...
- JDBC动态查询MySQL中的表(按条件筛选)
动态查询实现按条件筛选.PreparedStatement 准备语句指定要查询的表头列,.setString()通过赋值指定行,.executeQuery()执行语句 在数据库test里先创建表sch ...