在过去两个部分中,我们已经讨论了使用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教程(三)的更多相关文章

  1. CRL快速开发框架系列教程三(更新数据)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  2. 手把手教从零开始在GitHub上使用Hexo搭建博客教程(三)-使用Travis自动部署Hexo(1)

    前言 前面两篇文章介绍了在github上使用hexo搭建博客的基本环境和hexo相关参数设置等. 基于目前,博客基本上是可以完美运行了. 但是,有一点是不太好,就是源码同步问题,如果在不同的电脑上写文 ...

  3. 无废话ExtJs 入门教程三[窗体:Window组件]

    无废话ExtJs 入门教程三[窗体:Window组件] extjs技术交流,欢迎加群(201926085) 1.代码如下: 1 <!DOCTYPE html PUBLIC "-//W3 ...

  4. CocoStudio教程三:认识并利用CocoStudio的果实 运行2.2.1版本

    原文:CocoStudio教程三:认识并利用CocoStudio的果实 原文用的老版,用2.21搞起来好像有些问题,然后自己摸索了下,有的都是乱找的方法,只求能运行... 1,原文的CCJsonRea ...

  5. Android Studio系列教程三--快捷键

    Android Studio系列教程三--快捷键 2014 年 12 月 09 日 DevTools 本文为个人原创,欢迎转载,但请务必在明显位置注明出处!http://stormzhang.com/ ...

  6. Laravel教程 三:视图变量传递和Blade

    Laravel教程 三:视图变量传递和Blade 此文章为原创文章,未经同意,禁止转载. Blade 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上一 ...

  7. NGUI系列教程三

    接下来我们再来看Progress Bar和Slider,对比参数我们可以发现,Progress Bar和slider的明显区别在于slider多一个Thumb选项,这里的Thumb就是我们拖动的时候点 ...

  8. 中文翻译:pjsip教程(三)之ICE stream transport的使用

    1:pjsip教程(一)之PJNATH简介 2:pjsip教程(二)之ICE穿越打洞:Interactive Connectivity Establishment简介 3:pjsip教程(三)之ICE ...

  9. 黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (高级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (高级) 企业库验证应用程序模块之配置文件模式: ...

  10. 黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (初级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(三) Validation Application Block (初级) 企业库提供了一个很强大的验证应用程序模 ...

随机推荐

  1. 关于一些没做出来的SBCF题

    这里是一些我SB没做出来的CF水题. 其实这些题思维量还不错,所以写在这里常来看看…… 不一定每题代码都会写. CF1143C Queen 其实只要注意到如果一个点开始能被删,那一直就能被删:一个点开 ...

  2. HDU5758 Explorer Bo 思维+树形dp

    题意自己看题目吧,挺短的. 思考过程:昨天感觉一天不做题很对不起自己,于是晚上跑到实验室打开别人树形dp的博客做了上面最后一个HDU的题,也是个多校题..一开始没有头绪了很久,因为起点不固定,所以这1 ...

  3. codeforces #541 F Asya And Kittens(并查集+输出路径)

    F. Asya And Kittens Asya loves animals very much. Recently, she purchased nn kittens, enumerated the ...

  4. golang语言并发与并行——goroutine和channel的详细理解(一)

    如果不是我对真正并行的线程的追求,就不会认识到Go有多么的迷人. Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据. ...

  5. 高级组件——选项卡面板JTabbedPane

    选项卡面板:JTabbedPane(标签位置,布局方式) 标签位置:JTabbedPane.TOP,JTabbedPane.BOTTOM,JTabbedPane.LEFT,JTabbedPane.RI ...

  6. HTML学习笔记Day8

    一.设置元素背景透明属性{background:rgba(255,255,255,0.5):} 1.元素背景透明,内容正常显示: 注:opacity:value:元素背景透明内容也透明: 2.rgba ...

  7. (BFS/DFS) leetcode 200. Number of Islands

    Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surro ...

  8. (string 数组) leetcode 804. Unique Morse Code Words

    International Morse Code defines a standard encoding where each letter is mapped to a series of dots ...

  9. linux c 编程 ------ 头文件及其作用

    #include <stdio.h> printf #include <sys/types.h> 基本系统数据类型.系统的基本数据类型在32编译环境中保持为32位值,在64编译 ...

  10. Feature Selection

    两方面(发散,相关)~三方法(FWE) F:方皮卡互 W:RFE E:惩罚树 一.简介 我们的数据处理后,喂给算法之前,考虑到特征的实际情况,通常会从两个方面考虑来选择特征: 1)特征是否发散:如果一 ...