【课程笔记】南大软件分析课程12——Soundiness

Tattoo

发布日期: 2020-08-10 19:00:31 浏览量: 73
评分:
star star star star star star star star star star_border
*转载请注明来自write-bug.com

最近在看“静态分析”技术相关的文章,看到这个系列的笔记和视频教程,感觉介绍得很好,通俗易懂,而且还比较详细,故转载分享,同时也备份保留下,方便自己今后阅读。(PS:建议大家一边看笔记,一边看视频,加深理解)
原作者:bsauce
原文链接:https://www.jianshu.com/p/1ca6e11b1e72

首先非常感谢南京大学李樾谭添老师的无私分享,之前学习程序分析是看的北大熊英飞老师的ppt,但是很多地方没看懂,正如李樾老师所说的那样,熊英飞老师的授课涵盖非常广,不听课只看ppt的话,理解起来还是很有难度的。但李樾老师的视频就讲解的非常易懂,示例都是精心挑选的,所以墙裂推荐。

推送门南大课件 南大视频课程 北大课件


目录

  1. Soundness & Soundiness
  2. 复杂语言特性一:Java Reflection
  3. 复杂语言特性二:Native Code

重点

理解soundiness的含义,为什么要引入它?

理解为什么Java reflectionnative code分析这么复杂。

课程就这么结束了,抽象解释可能要在研究生课程再讲。

分析真实复杂程序时,产生的问题都与Soundiness有关,是最前沿的topic之一。

1.Soundness & Soundiness

Soundness:保守估计,分析结果能包含程序所有可能的执行。学术界和工业界都做不到。

复杂语言特性:导致分析结果不精确。

  • Java:Reflection, native code, dynamic class loading, etc.

  • JavaScript:eval(执行任意命令), document object model (DOM,和DOM加护), etc.

  • C/C++:Pointer arithmetic(指针地址+1或乘以), function pointers, etc.

现状:有些文章不提这类问题,或者随意一提(如eval)。极具误导性,导致相信该工具很sound,且影响专家的评判。

Soundiness:直观相信的”truth”,但没有任何事实和证据。

词语对比

  • sound analysis:能捕捉所有动态运行行为,理想化。

  • soundy analysis:目标是捕捉所有动态行为,但对于某些复杂语言特性可以unsound。

  • unsound analysis:为了效率、精度,故意不处理某些行为。

2.复杂语言特性一:Java Reflection—反射

(1)介绍Java反射

Java Reflection:反射机制很重要的一点就是“运行时”,其使得我们可以在程序运行时加载、探索以及使用编译期间完全未知的 .class 文件。换句话说,Java 程序可以加载一个运行时才得知名称的 .class 文件,然后获悉其完整构造,并生成其对象实体、或对其 fields(变量)设值、或调用其 methods(方法)。

说明:无反射代码在编译时就能确定对象;反射代码在运行时才确定对象,如c指向什么,”Person”也可能是的字符串指针,很难静态分析。分析该类代码很有必要,如弄清对象到底调用了哪个目标函数、对象域的指向关系等。

(2)分析方法

分析方法:String Contant analysis + Pointer Analysis(Reflection Analysis for Java——APLAS 2005)。

示例:目标是分析m调用的目标函数。

  • 找到m的定义点,即Method m = c.getMethod(mName, ...);

  • 通过String Contant analysis找到mName指向内容

  • 通过指针分析找到c指向内容

  • 通过String Contant analysis找到cName指向内容

  • 知道了是调用Person类的setName函数

问题:若字符串的值无法通过静态分析得到,则反射目标不能求解。Eg,字符串来自配置文件、网络、命令行、复杂字符串处理、动态生成、加密。

(3)改进

解决方法:Type Inference + String analysis + Pointer Analysis(Self-Inferencing Reflection Resolution for Java——ECOOP 2014,李樾,谭添老师的成果)。在创造点不可推,但在使用点可推。

示例:类名依赖cmd参数,解不出来;但在调用点,通过Java的类型系统推导parameters,发现parameters是this指针。推出结论就是,175行的目标函数有1个参数,且声明类型要么是FrameworkCommandInterpreter要么是其子类。结果推断出50个反射目标函数,48个为true。

最新工作Understanding and Analyzing Java Reflection (TOSEM 2019) Yue Li, Tian Tan, Jingling Xue。不仅求解反射对象更准确更多,而且能说出哪里解的不准。

常用方法Taming reflection: Aiding static analysis in the presence of reflection and custom class loaders (ICSE 2011)。利用动态分析来解,缺点是测试用例的覆盖路径有限,优点是只要解出来,结果都为真。

3.复杂语言特性二:Native Code

Native Code:一个Native Method就是一个java调用非java代码的接口。该方法的实现由非java语言实现,已被编译为特定于处理器的机器码的代码,这些代码可以直接被虚拟机执行,与字节码的区别:虚拟机是一个把通用字节码转换成用于特定处理器的本地代码的程序,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern “C”告知C++编译器去调用一个C的函数。

Java Native Interface(JNI):是一种编程框架(函数模型,反映参数格式等),使得Java虚拟机中的Java程序可以调用本地应用/或库,也可以被其他程序调用。 本地程序一般是用其它语言(C、C++或汇编语言等)编写的,并且被编译为基于本机硬件和操作系统的程序。

示例:先加载Native库,声明Native函数,*env变量可以在Native代码中用于创建对象、访问域、调用Java中的方法等,支持230个JNI函数。问题是跨语言之后,如何静态分析je.guessMe()这个调用?

方法:对重要的native code手动建模。例如,对经常调用的arraycopy()函数进行建模,建模后就是一个拷贝循环,但从指针分析角度来讲,看到这个循环,我们就把数组指针进行传递。

最新工作:Identifying Java Calls in Native Code via Binary Scanning (ISSTA 2020)。通过扫描二进制程序来识别native code中的Java调用。

扩展:想深入研究Soundiness,可参考网站http://soundiness.org

参考

Java 反射由浅入深 | 进阶必备

java native方法使用

上传的附件

发送私信

人生最好的三个词:久别重逢,失而复得,虚惊一场

93
文章数
34
评论数
最近文章
eject