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 (初级) 企业库提供了一个很强大的验证应用程序模 ...
随机推荐
- loj6157 A ^ BProblem (并查集)
设s[x][i]表示从根到x的异或和在第i位上的值(0/1),(a,b,i)表示a到b的异或和在第i位上的值那么就有(a,b,i)=(s[a][i]^s[b][i]^s[lca][i]^s[lca][ ...
- Docker中如何删除image(镜像)
原文地址:http://yaxin-cn.github.io/Docker/how-to-delete-a-docker-image.html docker中删除images的命令是docker rm ...
- 浏览器直接显示html代码,不解析代码
在某些时候,我们可能因为某些特殊的原因,不想让浏览器解析html代码. 1,把代码放到js中,如下 <script type='text/html' style='display:block'& ...
- (转)git stash使用
使用情形 综合下网上的介绍和资料,git stash(git储藏)可用于以下情形: 发现有一个类是多余的,想删掉它又担心以后需要查看它的代码,想保存它但又不想增加一个脏的提交.这时就可以考虑git s ...
- 测试利器 Postman
一.安装 官网:https://www.getpostman.com/ Postman是一个Chrome的一个插件工具,我们可以通过Chrome的应用商店进行进行搜索并安装,安装完成会在桌面上显示一个 ...
- anaconda的安装教程和使用方法
一.anaconda安装方法: 1.下载: anaconda官方下载地址:https://www.anaconda.com/download/ 2.安装: 可以自己指定路劲,也可以选择默认安装,最后记 ...
- glob.glob 匹配文件
glob.glob以列表形式返回匹配的文件路径 只有一个参数:文件的匹配规则 e.g. >>>res_home = '/vip_data_center/test_envs/train ...
- Qt ------ excel 操作
写 excel // step1:连接控件 QAxObject* excel = new QAxObject(this); excel->setControl("Excel.Appli ...
- 递归思维判断数组a[N]是否为一个递增数组
递归的方法:记录当前最大的,并且判断当前的是否比这个还大,大则继续,否则返回false结束: bool fun( int a[], int n ) { ) { return true; } ) { ] ...
- gometalinter代码质量检查分析工具(golang)
GitHub地址:https://github.com/alecthomas/gometalinter gometalinter安装和使用 1.安装 go get github.com/alectho ...