论文阅读:LibHunter. Xie. How Does Code Optimization Impact Third-party Library Detection for Android App

LibHunter. How Does Code Optimization Impact Third-party Library Detection for Android Applications?

LibHunter 这个工具名称和之前的论文冲了

ICSE2024

Authors:

  • 一作:谢子凡 (phd 在读), 华科
  • 通讯:文明 (AP), 华科

前人的 TPL 版本检测工具声称对混淆有抵抗力,但缺少对代码优化的考虑。本文系统调研了优化策略会如何影响现有的 TPL 版本检测工具,并根据调研结果,开发了 LibHunter,可以抵抗主要的代码优化方法,并且也抗混淆和代码优化。

1. Introduction

首先讲安卓应用广泛使用 TPL,用于广告、社交、支付、改善开发体验。很多 apk 使用了 20+ apk。然后提了一下 TPL 有供应链安全风险,供应链长且复杂,因此开发者和平台需要及时发现并修复上游风险。

然而,TPL 版本检测会受到混淆代码精简代码优化的影响。文章随后例举了常用的混淆器和优化器,现存 TPL 检测方法(LibPecker, LibScan),指出他们没考虑优化器,并指出 R8 是标准sdk 的一部分被广泛用来优化代码,会影响代码结构。

为此,文章首先评估了 R8 的使用范围,然后评估了 R8 对现有工具 (LibScan) 的影响。

  • 评估使用范围:从 FDroid 下载 open source apps, 检查 Grade build file,发现 41.1% 的应用有 R8
  • 评估对现有工具的影响:调整 R8 的策略配置,构建数据集 dataset1dataset_1dataset1, 包含 “D8 alone”, “Obfuscation”, “Shrinking”, “Optimization + Shrink”, and “Obfuscation + Optimization + Shrink” (R8’s default strategy). 发现 LibScan 库识别的 F1 下降至 41.1%,版本识别的 F1 下降至 14.7%.
  • 评估优化策略对 TPL 识别的影响:构建 dataset2dataset_2dataset2,给 app 生成 13 个单优化策略变体。
  • 发现 inlining 和 CallSiteOptimization 最影响正确性

Callsite Optimization(调用点优化) 是一种编译器优化技术,旨在优化函数调用的性能,通常涉及内联展开(inlining)、参数传播(argument propagation)、分支优化(Branch Optimization)、去虚函数调用(Devirtualization)等手段,以减少函数调用的开销,提高执行效率。

例如 (x) -> {return 'a' if x> 32 else 'b'} 可以被 AP 优化成 ‘a’,D 和 BO 则分别减少了 vtable 查询和分支跳转的开销。

为了解决 Inlining 和 CSO,本文提出 LibHunter,通过 4 个主要步骤,利用 opcode 和 string 特征,用静态分析方法模拟优化的处理过程计算 enhanced features,比对方法间的相似度。其中,对于需要模拟优化过程才能匹配的方法,文章定义为 partial matched。最后,通过相似方法的占比,文章计算类之间的相似度,判定 TPL 存在性。

2. Background and Motivation

进入第二章,首先在 2.1 介绍了 D8/R8 的 usage,在 2.2 介绍现存的 TPL 检测工具,并简单讲了一下 motivation。

关于 D8/R8,在 2.1 节,D8 是 Android Gradle Plugin 在 3.1.0 版本 (2018/03) 引入的内置 dex 编译器,功能是把 .class 编译成 .dex;R8 是 3.4.0 版本 (2019/04) 引入的工具,在 D8 基础上,加入了 code shrinking, obfuscation, optimization 等优化功能。通过设置 minifyEnabled true 可以打开 R8 的混淆和优化功能,否则,默认会开启 D8,支持 Switch Rewriting 和 String Optimization。

下图罗列了 R8 的优化选项,可以选择开启关闭。其中,TreeShaking 用于移除无用的 class, field, method, attribute, 不同于 DeadCodeRemoval。文章指出 DeadCodeRemoval 不是一个单独的可设置策略,而是嵌入在整个优化过程中,所以不单列。(我之前以为是 DCR 导致 LibScan 挂了,这篇文章说是 CSO 和 inlining)
在这里插入图片描述

在 2.2 节介绍了相关工作,涉及 LibScout, LibPecker, LibID, ATVHunter, LibScan。文章简单介绍了每个方法的贡献,并提了一下应对混淆和优化策略的不足。文章指出 LibScan 是 SOTA 的,但是 paper does include experiments on the impact of optimization on tool performance, it lacks further analysis of how optimizations affect performance and does not propose solutions to resist these effects.

由于已有工具考虑了混淆没考虑优化,本文尝试系统研究优化会如何影响这些工具。

3. Empirical Study

第三节试图主导一个综合研究,探索优化策略会如何影响现有的 TPL 工具。为此,本节设置了三个研究问题:

  • RQ1: Pervasiveness of R8: How pervasive it is for Android apps to utilize the R8/D8 compiler?
  • RQ2: Impact of Code Optimization: How does code optimization affect the performance of existing TPL detection tools?
  • RQ3: Impact of Optimization Strategies: Which code optimization strategies cast a greater impact on the performance of TPL detection tools?

3.1 数据集构建

构建数据集 ,标注 APP -> TPL 的映射关系。本文和 PHunter & LibScan 一样,也是爬的 F-Droid 构建数据集 apk 集合,通过分析 Gradle 文件标注 TPL,并筛选有至少一个洞的 TPL。

为了研究优化对工具的影响,文章从 4151 个 apk 里挑选了 200 个应用,对应 31 个包含漏洞的 TPL 和 379 个 apk-tpl 对。本文采用五种不同的优化策略编译该应用,(1) D8 alone, (2) Obf, (3) Srk, (4) Opt + Srk, and (5) Obf + Opt + Srk,即 1 组由 D8 编译,4 组由不同策略 R8 编译,构成 1000 个 apk 的 dataset1dataset_1dataset1

前文提到的 13 种优化实现是 R8 的内部参数控制的,官方 release 版本只能全开/全关。为了研究不同优化策略的影响,本文修改并重新编译了 13 个 R8,每种开启 Shrinking 和一个单策略。文章进一步从 dataset1dataset_1dataset1 中挑选 50 个应用,用得到的 R8 编译,得到 650=13∗50650=13*50650=1350 个 app,组成 dataset2dataset_2dataset2

本节最后介绍了度量方法和 TPL 数据集。度量方法里,定义了 TP, FP, TN, FN 和 library-level, version-level 的定义;TPL 数据集里,爬取了 Maven 和 Gradle 里 31 个脆弱 TPL 的所有版本,共 3447 项。

实验设置和 PHunter 差不多,估计是做 PHunter 实验做出来的

3.2 RQ1: Pervasiveness of R8/D8

从 4151 个项目里,考察 D8 发布后即版本大于 3.1.0 的项目,共 2347 个。然后通过 minifyEnabled true 参数判定是 R8 还是 D8

  • 1380(58.8%) 使用 D8;964 (41.1%) R8;3 others.
  • 也就是说,至少有一半的项目年久失修了

3.3 RQ2: Impact of Code Optimization

给每个已有的方法,用各种 R8 混淆策略组合跑一遍,结果如表 2.

在这里插入图片描述
在说明部分针对 SOTA 工具 LibScan 分析了下为什么会受 D8/R8 影响

  • D8 的 String Otimizations 会优化 apk 处理字符串相关的 opcode
  • R8 的 inlining 会扩展 caller 处的代码,VerticalClassMerger 会优化内嵌类。

3.4 RQ3: Impact of Optimization Strategies

算盘声大家都听见了,怕不是就是对着 LibScan 做实验出发的

进一步测量各种优化策略对 LibScan 的影响,结果如图 1

在这里插入图片描述
得到结果:各种策略都有影响,普遍在 57% - 60% 的区间,但有两个奇差。因此引出本文的工具,针对 Inlining 和 CallSiteOpt

在本节结尾,作者给了一个实例,解释 Inlining 和 CallSiteOptimization 会发生什么。对于 CSO 如图所示,会在替换、删除形参或修改返回值类型为 void,导致 fuzzy signature 不同。对于 inlining,为了避免扩大程序体积,R8 定义了一个经验数组 A={+∞,28,16,12,10}A = \{+∞, 28, 16, 12, 10\}A={+,28,16,12,10},对于一个被调用 kkk 次的 callee,只有当 callee 的长度小于 A[k]A[k]A[k] 时才会 inline,5次以上不会 inline。
在这里插入图片描述

Insights

针对 Inlining 和 CSO 设计检测特征并不容易,本文的 insights 是通过静态分析模拟优化逻辑,模拟出相似的函数

  • Insight1: 模拟 CSO 的优化逻辑,分析方法里没用到的参数和返回值
  • Insight2: follow R8 的 inline 逻辑,静态分析找到要 inline 的方法

4. Approach

前面花了这么多篇幅来引出 Inlining 和 CSO 是 LibScan 的最显著挑战,讲了他们各自执行的操作,并提出用静态分析来模拟的解决思路。本节提了 LibScan 的方法。开局先叠甲,说本工具是针对 R8 默认策略开发的。

文章如此总结 LibScan:通过提取能抵抗优化的语义,来比对候选 TPL 和 app。其中,抗优化的语义包括:

  1. Insight1: 通过 CG 和数据流分析推断经过 CSO 之后的函数原型
  2. Insight2: 跟踪 inline 过程,预测被综合后的方法 features 是什么

感觉名字起高了,更像是一个 patch。总之,LibHunter 包含三个主要步骤:

  • Signature-based Class Matching
  • Similarity-Based Method Matching
  • Cross-Inlining Method Matching

在这里插入图片描述

4.1 Signature-based Class Matching

和 LibScan 和 PHunter 都很像。这一步在类 - 函数 - opcode 的层次中,在类的层次给每个类构建一个 fuzzy signature 的集合,然后通过集合的包含关系来判断 TPL 和 apk 的关联性。本文的改进是,利用静态分析工具模拟 CSO,扩展 fuzzy signatures,成为包含正则 ? 和选择语法的广义 fuzzy signature。

首先,本文分别收集类中 field 的特征集合 SfieldS_{field}Sfield 和方法的特征 SmethodS_{method}Smethod。对于 field,收集其声明类型;对于 func,收集其 decl-seq。用 X 表示自定义类型/

然后,适配 CSO。对于给定的 TPL 方法 m,在这一步首先查询 CG,在所有 caller 上做数据流分析,记录 const 的 parameter。如果返回值没用过也要 discard。然后,检查 m 内部,删去没用的 parameter。为了适配各种情况的优化结果,被删的参数是可选留下的,因此本文借助正则语法,生成的特征形如 ˆ(int|void),int(,long)?$

这一步骤要求 SxAPP⊂SxTPLS_{x}^{APP} \subset S_{x}^{TPL}SxAPPSxTPL, 也就是成员可能被删除。

4.2 Similarity-Based Method Matching

更细致地在 methods 间比较。本节提到了一点,为什么要进入方法层面做匹配,因为 inline 会导入其他 class 的特征,所以需要下沉到 method matching。

本文参考 LibScan 和 ATVHunter,提取 opcode 和 string 特征(做成集合 mop,mstrm^{op}, m^{str}mop,mstr),并通过 Fully Matching 和 Partially Matching 两步,匹配方法。

Fully Matching

一个 mappm_{app}mapp 和一个 mtplm_{tpl}mtpl 方法的相似度高于阈值,直接匹配。

通过特征集合的交/并的比值计算相似度

simfull(ma,mt)=JD(maop,mtop)2+JD(mastr,mtstr)2≥T1sim_{full}(m_a, m_t) = \frac{JD(m_a^{op}, m_t^{op})}{2} + \frac{JD(m_a^{str}, m_t^{str})}{2} \geq T_1 \quadsimfull(ma,mt)=2JD(maop,mtop)+2JD(mastr,mtstr)T1

限定完全匹配只有一个结果,多个结果取最高

Partially Matching

mappm_{app}mapp 可能 inline 了某个其他方法,包含 TPL 的 caller 方法的特征。通过 mtplm^{tpl}mtpl 特征在 mappm^{app}mapp 中的占比计算相似度。例如,m1TPLm_1^{TPL}m1TPL inlines m2TPLm_2^{TPL}m2TPL,整合进 mappm^{app}mapp, m1m_1m1 的特征包含于 yyy.

simpartial(ma,mt)=∣maop∩mtop∣∣mtop∣×2+∣mastr∩mtstr∣∣mtstr∣×2≥T1sim_{partial}(m_a, m_t) = \frac{|m_a^{op} \cap m_t^{op}|}{|m_t^{op}| \times 2} + \frac{|m_a^{str} \cap m_t^{str}|}{|m_t^{str}| \times 2} \geq T_1simpartial(ma,mt)=mtop×2maopmtop+mtstr×2mastrmtstrT1

partial matched 方法可以不止一个,被放到一个 list Lma⊂ctL_{m_a} \subset c_tLmact 里,需要经过 4.3 的 cross-inlining method matching。原因:TPL 方法如果很简单,比如就一个 return,相似度很高。

通过方法来 decide 类匹配

考虑到代码精简,仅当每个 cac_aca 的方法 mam_ama 都有至少一个匹配的 ctc_tct 中方法 mtm_tmt 时,判定cac_acactc_tct 的 match。

4.3 Cross-Inlining Method Matching

本节通过模拟 inlining,筛选 LmaL_{m_a}Lma,其中包含 mam_ama 可能匹配的所有 TPL方法 mtm_tmt.

具体来说,通过调用图计算调用链,然后按判定标准决定要不要迭代地 inline。跳过标准库。然后在扩展后的函数计算相似度:

simcross(ma,mt′)=JD(maop,mtop′)2+JD(mastr,mtstr′)2≥T1sim_{cross}(m_a, m_t') = \frac{JD(m_a^{op}, m_t^{op'})}{2} + \frac{JD(m_a^{str}, m_t^{str'})}{2} \geq T_1 \quad simcross(ma,mt)=2JD(maop,mtop)+2JD(mastr,mtstr)T1

4.4 TPL Version Identification

和 LibScan 一样,用 opcode 的占比来衡量相似度。

Confidence(ca,ct)=∑(ma,mt)∈MEca,ctsize(mt)+∑(ma,mt)∈MCca,ctsize(mt′)\begin{align*} Confidence(c_a,c_t) = & \sum\nolimits_{(m_a,m_t)\in ME_{c_a,c_t}} size(m_t) \\ & + \sum\nolimits_{(m_a,m_t)\in MC_{c_a,c_t}} size(m_t') \end{align*} Confidence(ca,ct)=(ma,mt)MEca,ctsize(mt)+(ma,mt)MCca,ctsize(mt)

取候选 TPL 类中, confidence 的 argmax 作为输出 class,构成匹配的集合 CMCMCM.

Sim(TPL,APP)=∑(ca,ct)∈CM(app,tpl)Confidence(ca,ct)csize(app)≥T2 Sim(TPL, APP) = \frac{\sum_{(c_a,c_t)\in CM(app,tpl)} Confidence(c_a,c_t)}{csize(app)} \geq T_2 Sim(TPL,APP)=csize(app)(ca,ct)CM(app,tpl)Confidence(ca,ct)T2

其中,用扩展后的 mt′m_t'mt 计算 partial 的贡献。

5. Evaluation

结果比所有已有方法好,不过还有提升空间。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值