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 (初级) 企业库提供了一个很强大的验证应用程序模 ...
随机推荐
- 10张图带你深入理解Docker容器和镜像
http://dockone.io/article/783 [编者的话]本文用图文并茂的方式介绍了容器.镜像的区别和Docker每个命令后面的技术细节,能够很好的帮助读者深入理解Docker. Doc ...
- ubuntu 百度云
下载链接:https://pan.baidu.com/s/1HBu5T3PZ8JsS93PgOKnUYw提取密码:6J1A 在终端中输入命令: sudo dpkg -i bcloud_3..1_all ...
- MVC之 自定义过滤器(ActionFilterAttribute)
一.自定义Filter 自定义Filter需要继承ActionFilterAttribute抽象类,重写其中需要的方法,来看下ActionFilterAttribute类的方法签名. //表示所有操作 ...
- python面向对象中的一些特殊__方法__
1. __doc__ 表示类的描述信息 class Foo: """ 描述类信息""" def func(self): pass print ...
- RabbitMQ入门-队列
先建工程 下一步,输入坐标 下一步,输入工程名 先看一下最终目录 修改pom文件 <?xml version="1.0" encoding="UTF-8" ...
- JavaBean+Servlet 开发时,JavaBean 编写问题
在开发 JavaBean 时,遇见一个问题: ***** 表单字段为空,提交时出现 nullPointerException 异常: 表单字段不为空,提交正常. 使用 JavaBean ,JSP页 ...
- (数字三角形)POJ1163 The Triangle
The Triangle Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 59698 Accepted: 35792 De ...
- (set)MG loves gold hdu6019
MG loves gold Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- Vue(基础五)_vue中用ref和给dom添加事件的特殊情况
一.前言 这篇文章涉及的主要内容有: 1.ref绑定在标签上是获取DOM对象 2.ref绑定在子组件上获取的是子组件对象 3.案列:自动获取input焦点 二.主要内容 1.基础内容: ref 被用来 ...
- apache thrift分析
thrift是一个用来实现跨语言的远程调用(RPC Remote Procedure Call)的软件框架.根据接口定义语言(IDL Interface definition lanuage) 并借助 ...