[Notes]Neural Nets Can Learn Function Type Signatures From Binaries

Abstract

识别函数类型签名对于二进制分析来说非常重要,但是对于二进制程序来说是个难点。本文实现了EKLAVYA,一个用于训练递归神经网络从反汇编的二进制代码中恢复函数类型签名的系统。主要有两点,一是不需要目标指令集的先验知识,二是它的结果具有可解释性。

在我们对clang和gcc编译的Linux二进制文件的评估中,针对两种不同的架构(x86和x64),EKLAVYA在函数参数计数和类型恢复任务方面分别显示了84%和81%的准确性。EKLAVYA在两个不同指令集上测试的编译器中很好地进行了泛化。

本文信息
作者 Zheng Leong Chua∗ ,Shiqi Shen∗ ,Prateek Saxena ,Zhenkai Liang
出处 usenix‘17

1.Introdction

提取程序语义对于以下几个领域意义重大:code hardening,bug-finding,clone detection,patching/repair analysis。二进制分析任务一般来说是指令,控制流,数据结构,甚至是全功能语义的恢复。语义级别越高,分析就越专门化,需要更多的专家知识。现有的分析方法大多依赖于启发式,而我们是否能够直接从二进制中提取出语义呢。

更具体的,本文主要研究从二进制代码恢复函数类型/签名的问题。该问题主要应用于二进制的控制流硬化和数据依赖分析。

2.Overview

(1) Function type recovery

Function type recovery 涉及从函数的二进制代码中识别函数的参数的数量和基本类型。这通常是构造控制流图和过程间数据依赖分析的子步骤,广泛应用于二进制分析和强化工具。

一般来说,函数类型恢复会使用这样的约定作为函数类型恢复的启发式:对所有指令的语义、ABI约定、编译器习惯用法做如下编码:

a.寄存器保存-还原的push/pop指令(push %rbp)

b.使用rsp作为特殊堆栈指针寄存器的指令(sub 0x20,%rsp)

c.分配堆栈空间的算术指令(sub 0x20,%rsp)

d.使用特殊寄存器传递参数的指令(mov %rdx,%rsi;mov %eax,%edi)

e.只在算术操作中使用整数类型的数据(mov %edx,%eax;add %eax,%eax;add %edx,%eax)

在传统的分析中常常需要这样的约定或规则来定位参数,而理想方案则是尽量减少在解决问题时使用的专业知识。比如,我们希望有一种能够在任何指令集上工作的机制,能够处理各种标准编译器和其中支持的优化。

在本文的工作中,目标是开发一个系统:可以自动学习规则,直接从二进制代码中识别函数类型,不需要监管。同时设计技术来确保学习的模型能够产生可解释的结果,与我们领域内的知识相符合。

0%