多读书多实践,勤思考善领悟

软件代码的静态和动态分析

本文于1886天之前发表,文中内容可能已经过时。

介绍代码的静态分析和动态分析技术,能够使读者在进行安全测试的时候在宏观上有一个明确的执行方向。

1. 代码静态分析技术

定义:是在不执行计算机程序的条件下,对源代码进行分析,找出代码缺陷。

执行方式:一般配合静态程序分析工具进行。

采用技术:数据分析流,机器学习,语义精简。

可检测类型:死锁,空指针,资源泄漏,缓存区溢出,安全漏洞,竟态条件。

用途:程序翻译/编译,程序优化重构,软件缺陷检测等。

对比:程序动态分析:需要实际执行程序

程序理解:静态分析这一术语一般用来形容自动化工具的分析,而人工分析则往往叫做程序理解。

优点:

  1. 能够检测所有的代码级别可执行路径组合,快速,准确。

  2. 直接面向源码,分析多种问题。

  3. 在研发阶段开始找到并修复多种问题,节省大量时间,人力成本

(注意:静态分析不是万能的,测试是持续的过程)

静态分析的对象是windows内核模块,第三方驱动程序等不开源的二进制代码。

  1. 首先需要通过反汇编工具对模块进行处理,生成相应的汇编代码,然后在此基础上分析,检查程序的语法,结构,过程,接口等,恢复和重建程序的数据类型,结构和框架,验证程序功能,逻辑是否正确。

  2. 在静态分析过程中,关键的地方是要做到准确提取信息,不论是源程序还是二进制程序,利用静态分析技术都可以从中提取出控制流,表达式,接口和数据流等相关的信息。

  3. 由于程序本身可以看作是抽象的,复杂的数据结构集合,因此程序的静态分析技术主要是根据从程序中提取的相关信息,从不同角度对程序的数据结构进行重构,根据模型推导数据之间的逻辑转换关系。

常用数据结构:

常用的数据结构包括函数调用图,抽象语法树,路径图等。

其中函数调用图是利用程序中函数之间的调用关系建立起的模型,抽象语法树是利用程序语义建立起的模型。

建立好抽象语法树模型后,可以进一步获取到程序模块,函数的执行过程,以及它们中间数据流动的过程,通过恢复程序的函数关系,可以建立起函数模型,在此基础上,根据这些模型可以采用二进制对比技术,语法分析,规则检查,类型推导等多种方法对程序进行安全分析。

如。对程序代码进行对比检查可以采用二进制对比技术,通过对比补丁前后函数汇编代码的不同,可以快速定位补丁修改位置,然后进行分析,明确漏洞触发的原因,实现编写出针对该漏洞的验证代码。

如何分析缺陷:

1.过程间分析:将考虑每一个合理的可执行路径

2.获取一系列的函数定义:资源分配,调用

3.数据流分析将跟踪所有应用中的不可信数据:source,sink,二者之间必须进行验证。

4.某些使用智能静态分析

找到潜在bug其实只是难题之一:

  1. 消除误报非常难

  2. 将复杂的缺陷解释出来很难

  3. 只找潜在的一次性缺陷是很难的

2. 动态调试技术

动态调试技术在软件逆向工程领域也是一个很热门的概念,他是与静态分析技术相对而言的。静态分析技术是指破解者利用反汇编工具将二进制的可执行文件翻译成汇编代码,通过对代码的分析来破解软件。而动态调试则是指破解者利用调试器跟踪软件的运行,寻求破解的路径。

代码动态调试技术,一般是通过观察程序在运行过程中的状态,如寄存器内容,函数执行结果,内存使用情况等等,分析函数功能,明确代码逻辑,挖掘可能存在的漏洞。

代码流和数据流是动态调试技术通常要特别关注的两个方面。

代码动态调试的特征是:

计算机必须真正运行被测试的程序,通过输入测试用例,对其运行情况即输入输出的对应关系进行分析,以达到检测的目的。

动态测试包括:

  1. 功能确认和接口测试

  2. 覆盖率分析

  3. 性能分析

  4. 内存分析

动态调试器:

调试器一般都支持设置断点功能,通过在代码中设置断点,可以动态跟踪目标程序代码的执行情况,检测可能存在问题的函数调用。

通过动态分析数据流,构造特殊输入数据来触发程序的潜在错误,对比运行得到的结果与期望获得的结果之间的差别,以便确定目标函数在安全方面有没有存在缺陷,并对比分析所得到的结果。

在dos环境下,最常用的调试工具是DEBUG,它的作用有:

  1. 直接输入,更改,跟踪,运行汇编程序

  2. 观察操作系统的内容

  3. 查看ROM BIOS的内容

  4. 观察更改RAM内部的设置值

  5. 以扇区或文件的方式读写软盘数据等

调试器分类:用户模式调试器,内核模式调试器

在windows下有很多软件调试工具,使用比较广泛的工具有olldbg,softlCE等,由于内核程序是在内核态空间中运行的,所以普通用户态应用程序的调试工具,方法不适合用于内核程序,现在调试内核主要有一下三种方法:

  1. 采用硬件调试器

  2. 编写用于调试的驱动程序和中断处理函数,安装在内核里面,在操作系统内核中断的时候,硬件被它们接管。有softlCE,syserDebugger两种。

  3. 微软在windows内核中添加了支持调试的相关服务。

Windows内核调试一般采用第三种方法,调试器采用微软提供的windbg,他能连接到微软服务器,下载与调试模块匹配的符号文件,用于显示当前代码所在函数的函数名称,便于分析人员跟踪。

WinDbg:

Windbg能进行三种调试:远程调试,dump调试,本地调试。

Windbg主要设计用于双机调试:调试机和被调试机。

通常为了调试过程中的方便以及保护被调试机的稳定,将被调试机设置在虚拟机内,虚拟软件通常不能直接管理硬件,也需要运行在一个真实的操作系统中,虚拟机和真实系统之间通过把串行端口模拟成命名管道的方式来通信,其做法是在虚拟机中建立一个虚拟的串行端口,把它映射到真实系统的一个命名管道上,虚拟软件软件把对这个串行端口的读写转换为对真实系统中命名管道的读写,然后就可以使用windbg连接命令管道与虚拟机中的内核调试模块通信,实现了一台机器上进行双机调试的目的。

Olydbg:

目前最流行的调试工具是OllDbg,成为当今最流行的调试解密工具,同时还支持插件扩展功能,是目前最强大的调试工具。