Postmortem Program Analysis with Hardware-Enhanced Post-Crash Artifacts
  YhJDCD5ihXhp 2023年11月02日 23 0
  • 硬件辅助的程序崩溃分析

Summary

  • 当crash发生的时候,OS通常会保存程序的终止状态。可能会将这个进程的内存及当时的寄存器状态存入core dump,程序员可以根据这debug,但是工作量依旧很大。
  • 利用Intel处理器提供的Processor Tracing(PT),记录程序执行过程中的指令跳转信息,然后利用这些信息重构执行过的指令序列。
  • POMP利用Core Dump和PT记录的信息进行自动化分析。
  • 首先根据已有的信息进行控制流的重建,即crash之前执行过的指令序列。
  • 第二步,反向恢复数据流。具体的说就是Core Dump中有最后一条指令执行时的内存状态,然后POMP从最后一条指令出发,进行逆向计算来重现各指令执行前的内存状态。
  • 完成数据流的分析后,根据数据流做逆向污点分析并标记处导致crash的传播路径。

Method

Reverse Execution

  • use-define chain
  • 在第一步中,算法首先反向解析执行跟踪。对于跟踪中的每条指令,它根据该指令的语义提取相应变量的使用和定义,然后将它们链接到先前构建的使用-定义链。
  • 当添加新的use ordefine 的时候。算法会检查相应变量的可达性,并试图解析链上的这些变量。比如A18添加定义:esp = esp + 4,算法检查esp可以在没有改变的条件下到达底端,所以esp和esp+4可以正常赋值,并解析是否可以根据esp 的赋值解析出更多的变量信息。
  • 在构建use-define chain的时候通过两种方式跟踪约束。在一种方式中,我们的算法通过检查指令语义来提取约束,二是检查已使用的定义关系来提取约束。约束关系就是eax=[ebp-0xc]、eax>ebx类似的。后面的内存别名验证中的假设检验会用到。
  • 内存别名验证
  • 在逆向执行和正向分析的时候可能会遇到未知地址的内存访问引入问题,比如指令A15会覆盖eax的值。根据正向分析,eax的值可以由指令A12确定。该条指令 mov eax, [ebp+0x8] 将位于[ebp+0x8]位置的内存拷贝进入eax。直观上来说,我们只需要将[ebp+0x8]位置的内存值从Core Dump中取出即可。但是我们发现指令A14对于内存位置[eax]进行了写入操作。由于eax的值此时未知,那么我们可能面临两种情况。第一种,A14中的eax等于A12中的ebp + 0x8指向的值;第二种反之。
  • 如果有假设暂时不能拒绝某一情况,可以引入新的假设,新的假设确定后可以进一步判断之前的假设,但是会出现假设递归的情况,验证影响效率,POMP规定假设最多只有两重。如果此时还不能判断假设的对错,那会依旧保留之前的干预TAG。

Backward Taint Analysis

  • POMP首先要找sink,一般执行无效指令或取消引用无效地址会引起crash。解引用 一般是指访问程序不允许或不存在的内存地址。第一种情况,POMP将EIP作为sink,第二种情况,通用寄存器(32位):eax,ecx,edx,ebx,esp,ebp,esi,edi,因为它包含一个指向无效地址的值。
  • 在识别了sink的情况下,POMP污染sink并向后执行污染传播。在这种反向传播的过程中,POMP查找前面提到的use-define链,并确定污点变量的定义。这种sink识别的标准是确保定义可以在没有任何其他干预的情况下达到污点变量。继续本文的例子。在sink eax作为初始污染变量的情况下,POMP在链上选择A19:def:eax=[ebp-0xc],因为这个定义可以在没有干预的情况下到达污染变量eax。
  • POMP解析该定义,并将污点传递给新的变量,是所有的变量,因为每个变量都可能引起污点变量损坏,这样不会错过引起崩溃的变量,但是也会污染许多安全的变量,论文后面也讨论了over-tainting的方法。

Evaluation

  • POMP对31个真实程序的崩溃进行了测试,这些崩溃包括堆、栈和整数溢出,UAF和空指针解引用。

Experiment Setup

  • 对于32个crash,先根据相关信息进行手动分析检查手动可得到的最小指令集。作为基准。
  • 检查崩溃的根本原因是否包含在自动识别的指令集POMP中
  • 检查POMP的输出是否涵盖了我们手动跟踪的最小指令集
  • 探讨POMP是否可以显著减少必须手动检查的执行跟踪
  • 为了评估POMP的效率,我们记录了发现与每个程序崩溃真正相关的指令所花费的时间。还记录了反向执行的指令及其数量。
  • 我们选择并使用部分执行跟踪进行评估。在这项工作中,我们的选择策略遵循一个迭代过程。首先,我们引入崩溃函数的指令来反向执行。如果这个部分跟踪不足以发现根本原因,我们会追溯以前调用的函数,然后逐个函数地添加指令,直到POMP能够覆盖这个根本原因。

Result

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  qNufQyMQglJ5   2023年11月02日   23   0   0 赋值作用域mysql
  YgmmQQ65rPv4   2023年11月02日   39   0   0 赋值Java运算符
YhJDCD5ihXhp
最新推荐 更多