Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

Now You See Me: Real-time Dynamic Function Call Detection

作者:Franck de Goër, Sanjay Rawat, Dennis Andriesse, Herbert Bos, Roland Groz

单位:UGA, VU Amsterdam, ANSSI | Vrije Universiteit Amsterdam | LIG, Univ. Grenoble Alpes

会议:2018 Annual Computer Security Applications Conference

原文链接:https://dl.acm.org/citation.cfm?id=3274712


作者实现了一x86平台的实时调用检测工具iCi,该工具不依赖源码和调试信息,不依赖静态分析,只用动态跑一遍,可以为CFI、Profile、逆向、调试等工作提供支持。

x86上有CALL指令用于函数调用,但编译器可能会将尾调用优化成JMP,只分析CALL会遗漏。如:

  • coreutilsgcc -O2编译,10%的调用都是JMP
  • ffmpeg使用perf不能捕捉到所有调用(1109142/1467291)

作者主要解决了识别哪些JMP指令实际上是函数调用的问题。该工具仅面向编译器生成的代码,不考虑多入口、函数交错(手写汇编才会出现);要求返回地址在栈上,不考虑混淆过的代码。

实现

三类语句

  • CALL
  • PLT中的JMP:除了PLT内跳转都是
  • JMP:需要过filter

JMP filter

需要跟踪以下信息:

  • 当前PC,当前JMP的目标
  • 当前函数入口点(上一个检出的调用地址,可能不准确)
  • 当前栈状态和上次调用的栈状态(栈顶指针)
  • 当前返回地址

Exclusion

  • PLT内跳转
  • 内部前跳:目标在PC和当前函数入口之间
  • 内部后跳:目标在PC和当前函数已知的最高返回位置之间
  • (如果函数边界的信息是错的,会出假阴性,但结果上看这很少发生)
  • 栈状态不一致:尾递归调用发生前应该清栈,栈顶只剩返回地址

Inclusion

  • 跳转到已知的入口点:也有可能是从函数的第一条指令开始的循环,但是这样不会符合栈状态一致性的要求,会在之前被排除;函数开始后一般也会先进行一些准备,这种情况很少见
  • 外部前跳:目标在当前函数入口点之前;实际上是下一条规则的一个特例
  • 目标和PC之间跨入口点:因为所比较的入口点不确定,是最耗时的检测,所以最后进行

缓存结果

  • 只缓存排除的结果(跳转语句位置);接受的结果被保存为入口点(跳转目标),之后再遇到需要额外再过一次排除检测
  • 默认拒绝时也不添加到缓存,因为可能是信息不充分导致的无法判断,之后可能还有救

函数边界识别

  • 识别出一个调用才添加入口点
  • 最高返回地址初始化为入口点,同时跟踪RET指令和返回地址栈,以此更新每个函数的返回地址

评估

  • 开发了一个Oracle基准,两个naïve实现(认为所有JMP都是/都不是)
  • f-score

    $p=\frac{|TP|}{|TP|+|FP|}$ 所做出的肯定识别中有多少是对的

    $r=\frac{|TP|}{|TP|+|FN|}$ 在标准结果中,实际识别出了多少

    $f_{score}=\frac{2pr}{p+r}$ 调和平均

Oracle

  • 通过调试符号表、PLT段、动态分析获取函数入口信息
  • 监视非连续的PC流,新PC是入口点的直接记录为调用
  • 从入口点开始的循环:函数开始会有准备的语句,所以不担心
  • PC连续的调用:作者认为这个不常见

结果

评估结果

原始数据

  • OOP友好(ffmpeg、SPEC),多种优化级别、编译器表现都不错
  • 有大量假阳性,但是是CALL带来的(地址指向了.plt.got段)
  • 性能上,iCi劣于jcall但优于jmp(因为有排除缓存)

相关工作

关于函数分析此前已有大量工作,但主要为静态分析,通过编译器特定的函数边界特征来进行识别,这样的识别需要对每种编译器进行特定的处理,且对于优化过的代码效果较差;2017发表过一篇基于CFG分析的函数调用识别的工作,不再需要进行编译器特定处理,但对于基于JMP的尾调用,需要目标函数至少被CALL调用一次才能识别;本文所述的方法是通过实时、在线的动态分析进行,无需静态分析的参与,且特别面向JMP进行了识别。