光一样的少年|大规模下加速源代码分析( 三 )


遍历(或分析函数)的输入变量始终是 CFG 节点 , 如遍历定义中所述 。例如 , 在 mineT 遍历定义中 , 节点是输入变量 。分析函数的输出变量可以是以下三种类型之一:1)遍历返回的变量作为输出 , 例如 , 在 domT 遍历的情况下为 doms; 2)全局变量 , 例如在 apiT 遍历的情况下为 apiCallNodes 和 conditionsAtNodes mineT 遍历 , 或 3)作为输出写入控制台的变量 , 例如 , 在进行 analysisT 遍历的情况下的前提条件 。
光一样的少年|大规模下加速源代码分析每个选定的路径都会产生一个作为路径条件的规则 。 给定遍历(或分析函数)的一组非循环路径 , 以及遍历的输入/输出变量 , 算法 1 计算规则集 R , 该规则集 R 包含从非循环路径提取的路径条件 。 对于每个路径 , 算法 1 访问该路径中的节点并检查该节点是否为分支节点 。 然后 , 算法 1 提取输入变量(iv)的别名列表 , 以检查分支节点是否包含输入变量或其别名(第 8-9 行) , 如果是 , 则使用以下命令获取包含在节点中的谓词表达式: 辅助函数 getPredicate(第 7 行) 。getPredicate 辅助函数可以返回 null 或 true 或谓词表达式 。
当分支节点的谓词表达式不包含任何使用输入变量(iv)或其别名访问语句/表达式的表达式时 , getPredicate 函数将返回 null 。例如 , 图 4c 中第 4 行中的谓词表达式“ contains(apiCallNodes , node.id)”不访问该语句/表达式 , 而谓词表达式“ def(node.expr)&& hasSubstring(node.expr)”访问该表达式使用输入变量节点 。 表 1 提供了分支节点上的谓词表达式的几个示例 , 以及图 4 中描述的示例挖掘任务的 getPredicate 函数所返回的值 。 当 getPredicate 返回 null 时 , 算法 1 只会忽略分支节点并继续处理其他节点 。
光一样的少年|大规模下加速源代码分析表 1 getPredicate 辅助功能的谓词提取方案
如果存在一个谓词表达式 , 该谓词表达式包含一个使用输入变量(iv)或其别名访问语句/表达式的表达式 , 但并非所有谓词表达式中的符号都可以解析 , 则 getPredicate 函数将返回 true 。 这可能在几种情况下发生 , 例如 , 谓词表达式包含全局变量 , 或者其值无法解析的局部变量 , 或者函数调用又不是局部的(调用的函数可以访问全局变量) 。 我们已经考虑了分析语言可能发生的所有可能情况 , 并在表 1 中列出了一些示例 。 getPredicate 函数返回 true 失败案例 , 它表明存在一个谓词但无法提取 。 我们注意到使用 failToExtract 布尔值(在算法 1 中)会导致失败 , 该布尔值稍后将在第 24 行中使用 , 它以合理的行为终止规则提取 , 该行为假设输入 CFG 中的所有节点都与挖掘任务相关 。
最后的情况是 getPredicate 函数能够从分支节点成功提取谓词表达式 。 请注意 , 在这种情况下返回的谓词表达式已完全根据符号进行了解析 , 并且仅包含基于输入变量的语句/表达式 。 在这种情况下 , 我们根据路径中后继节点所属的分支(真或假分支)确定是否添加谓词表达式或其否定 。 路径条件是路径中所有谓词表达式的“逻辑和”(第 16-19 行) 。 如果当前访问的节点不是分支节点 , 则获取输出变量 ov 的别名 , 并检查该节点是否包含输出变量或其别名(第 21-22 行) 。 这里的想法是仅保留那些有助于测试输出的路径条件 。 在访问路径中的所有节点结束时 , 如果当前路径对输出有所贡献 , 则将计算出的路径条件添加到规则集 R 中(第 26-27 行) 。
光一样的少年|大规模下加速源代码分析图 5 我们通过静态分析为 API 前提条件挖掘任务生成的规则集 R 如图 4 所示


推荐阅读