原文链接 程序动态分析
什么是动态分析?
-
有时我们想知道执行一个程序运行时的一些信息,通常存在的问题有:
- 我写的程序运行的时候可能会怎么样?
- 为什么这种情况会发生?
- 程序中哪部分是耗时最多的?
- 哪些代码可以并行化处理?
- 程序中存在错误怎么处理?
如何进行动态分析?
通常我们通过记录程序执行时的一些信息已对程序进行分析。
具体的来说,通常有三种方式可以记录程序运行时的信息:
- 追踪程序变量等信息并记录
- 使用查插桩技术,额外添加代码辅助记录
- 以上两种方法结合使用
简单想法:基础块剖析
通常我们不用对程序的每个部分进行分析,有点类似之前文章程序切片技术提到的程序切片技术,在剖析基本块的时候我们最关心的问题是效率怎么样,如果一个工具需要的开销很大,在实际应用的时候就难以被接受。这时我们通常需要考虑如何选择有效的策略对程序进行剖析。
有效的剖析策略
剖析的基本策略如下,在使用剖析技术时需要考虑是否满足:
- 尽可能简单
- 确认然后避免冗余的信息
- 使用采样的方式分析
- 对程序压缩和编码
- 由剖析结果指导插桩操作
- 尽量使用局部分析和推理
路径剖析
路径剖析问题关注的是程序运行时执行的路径,对每条可能执行的路径进行编码
采用的步骤如下:
在对路径进行编码时,通常有两种方法,一般的方法是使用字典来记录,开销比较大,不推荐使用。另一种是使用 CFG 图来进行适配。
对一些常见的标准测试集进行路径剖析,可得出他们的基本路径信息
以上的分析仅包含简单的情况,即没有包含存在循环路径的程序,那么对于存在循环的路径怎么对路径进行编码也是我们需要考虑的问题。
实际上我们不用考虑的这么全面,对于有循环路径的程序,我们只需要记录什么地方存在循环,通常我们只关注这次运行时通常经过的路径有哪些?或者说是对于这一批输入,程序通常经过的路径有哪些?
但是如果我们不知道程序的输入是什么该如何分析这段程序?
那就需要使用代码建模技术。
近似建模技术
当我们不知道程序的输入是什么的时候,我们通常使用程序建模技术,对某个程序的行为进行建模
如何/什么时候插桩
对程序基本执行路径进行剖析完成后,根据剖析的信息,我们通常需要对程序进行插桩处理进一步分析程序的特性。在不同的阶段或者不同的代码级别上插桩的难度和效率都是不一样的。通常有基于源码或者中间代码的插桩,基于静态二进制的插桩和动态二进制的插桩。
动态分析步骤
动态分析一般的步骤分为三步:插桩,执行,分析。
其中静态和动态二进制插桩的方式又有所不同。
后面还介绍了 AddressSanitizer 工具的使用,此部分见之前发布的文章 AddressSanitizer VS Valgrind。
总结
总结一下,动态分析关注的是程序运行时的真实行为,通过插桩的方式修改程序的行为并收集相关信息以对程序进行充分分析。
如果我们不想深入了解程序的信息,而且不想有程序运行的过程,这样可以分析出来程序的一些特性吗?答案当然是可以的,这就需要我们接下来的静态分析技术。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于