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 (初级) 企业库提供了一个很强大的验证应用程序模 ...
随机推荐
- 51nod1079 poj2891 中国剩余定理与其扩展
题目链接:http://www.51nod.com/Challenge/Problem.html#!#problemId=1079 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K. ...
- 牛客寒假算法基础集训营3处女座和小姐姐(三) (数位dp)
链接:https://ac.nowcoder.com/acm/contest/329/G来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言52428 ...
- CodeForces - 95B(DFS)
题目链接:http://codeforces.com/problemset/problem/95/B 题目大意:给你一个正整数n (1 ≤ n ≤ 10100000),求不大小于它的超级幸运数字(超级 ...
- 洛谷P1712 区间
题意:给你n个区间,从中选择m个,使得它们有交,且最长与最短区间的差值最小. 解:这道题我想了好多的,nlog²n错的,nlogn错的,最后终于想出nlogn的了...... 把区间按照长度排序,然后 ...
- python实现发送邮件
一 使用SMTP模块发送邮件 import smtplib from email.mime.text import MIMEText from email.header import Header m ...
- JS重点整理之JS原型链彻底搞清楚
对象 要清楚原型链,首先要弄清楚对象: 普通对象 最普通的对象:有__proto__属性(指向其原型链),没有prototype属性. 原型对象(person.prototype 原型对象还有cons ...
- 高级组件——文件选择器JFileChooser
1.创建文件选择器 JFileChooser 2.设置选择模式 setFileSelectionMode(int mode) JFileChooser.FILES_ONLY 只能选择文件(默认) JF ...
- 把菜单栏变成万能工具箱,让你的 Mac 更酷炫
文章来源:知乎 文章收录于:风云社区 www.scoee.com,提供上千款各类mac软件下载 为了彰显存在感,各路 Mac 应用都喜欢在菜单栏上安置一个图标:其中有的只是用来召唤主界面,也有一些应用 ...
- 有时候eclipse 导入maven项目 启动的时候回出现这样一个问题
严重: A child container failed during start java.util.concurrent.ExecutionException: org.apache.catali ...
- java.lang.UnsatisfiedLinkError: org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
在 windows 上运行 MapReduce 时报如下异常 Exception in thread "main" java.lang.UnsatisfiedLinkError: ...