FlowDroid架构剖析
作者:互联网
最近算是把FlowDroid源代码翻了一遍,并非通读,而是把整个系统的逻辑/设计整理了一下。这里稍微记录一下。由于FlowDroid能够分析Android程序,所以有一部分代码是对Android相关领域做适配,由于个人目前的工作对Android静态分析还不是很涉及,所以在分析FlowDroid源码时省略了Android相关的适配代码,主要是作通用Java相关的分析。
FlowDroid
几大组件:
- EntryPointCreator:使用EntryPointCreator指定分析的入口
- SourceSinkManager:给定一个Stmt, 确定Source和Sink(对应SourceInfo,SinkInfo)
- NativeCallHandler:
- 默认使用 DefaultNativeCallHandler
- TaintPropagationWrapper:定义不应该被直接分析的类、方法。相反,分析结果取自外部模型中的方法摘要
- 一般通过IInfoflow.setTaintWrapper(…) 来配置
- Aliasing: 别名控制器
- IAliasingStrategy为别名策略: FlowSensitive(默认), PtsBased(andersen式), Lazy
- 以 BackwardsInfoflowProblem 为问题的求解器
- IFDSSolver:IFDS求解器
- 前向污点传播求解:InfoflowProblem
- 后向别名分析: BackwardsInfoflowProblem
- PathReconstructor:污点传播路径复现
- IPC Manager 是安卓相关,不予考虑
Infoflow
配置ITaintPropagationWrapper
的接口,Infoflow
类会继承该接口。
interface ITaintWrapperDataFlowAnalysis {
// 配置TaintPropagationWrapper
void setTaintWrapper(ITaintPropagationWrapper taintWrapper);
ITaintPropagationWrapper getTaintWrapper();
}
*IInfoflow
interface soot.jimple.infoflow.IInfoflow extends ITaintWrapperDataFlowAnalysis {
// 配置InfoflowConfiguration的接口
InfoflowConfiguration getConfig();
void setConfig(InfoflowConfiguration config);
// 用于配置NativeCallHandler
void setNativeCallHandler(INativeCallHandler handler);
// 用于信息流分析的前后分析行为植入
void setPreProcessors(Collection<? extends PreAnalysisHandler> preprocessors);
void setPostProcessors(Collection<? extends PostAnalysisHandler> postprocessors);
// 计算信息流(信息流分析)的主入口接口
void computeInfoflow(String appPath,
String libPath,
IEntryPointCreator entryPointCreator,
List<String> sources,
List<String> sinks);
void computeInfoflow(String appPath,
String libPath,
Collection<String> entryPoints,
Collection<String> sources,
Collection<String> sinks);
void computeInfoflow(String appPath,
String libPath,
String entryPoint,
Collection<String> sources,
Collection<String> sinks);
void computeInfoflow(String appPath,
String libPath,
IEntryPointCreator entryPointCreator,
ISourceSinkManager sourcesSinks);
void computeInfoflow(String appPath,
String libPath,
String entryPoint,
ISourceSinkManager sourcesSinks);
// 获取分析结果
InfoflowResults getResults();
// 是否分析结果可用
boolean isResultAvailable();
// 配置 结果可用时的回调函数
void addResultsAvailableHandler(ResultsAvailableHandler handler);
// 用于配置底层Soot
void setSootConfig(IInfoflowConfig config);
// 用于配置 Path reconstructor 算法
void setPathBuilderFactory(IPathBuilderFactory factory);
// 获取已经收集的Source点
Set<Stmt> getCollectedSources();
// 获取已经收集的Sink点
Set<Stmt> getCollectedSinks();
// 主线程(如GUI)用于控制、中断分析
void abortAnalysis();
// 污点前向传播时调用
void setTaintPropagationHandler(TaintPropagationHandler handler);
// 别名后向传播时调用
void setBackwardsPropagationHandler(TaintPropagationHandler handler);
// 配置内存管理器
void setMemoryManagerFactory(IMemoryManagerFactory factory);
// 配置Executor
void setExecutorFactory(IExecutorFactory executorFactory);
// 配置污点传播规则管理器
void setPropagationRuleManagerFactory(IPropagationRuleManagerFactory ruleManagerFactory);
// Android IPC相关, 不需要关注
void setIPCManager(IIPCManager ipcManager);
}
class soot.jimple.infoflow.Infoflow extends AbstractInfoflow {
// 分析纯Java代码,无任何APKs或者Android SDK依赖
public Infoflow() { ... }
// 分析APK文件
public Infoflow(String androidPath, boolean forceAndroidJar) { ... }
// 分析APK文件
public Infoflow(String androidPath,
boolean forceAndroidJar,
BiDirICFGFactory icfgFactory) { ... }
}
EntryPointCreator (√)
interface IEntryPointCreator {
// 生成dummy Main方法,它会调用给定列表中的所有方法
SootMethod createDummyMain();
void setSubstituteCallParams(boolean b);
void setSubstituteClasses(List<String> l);
Collection<String> getRequiredClasses();
Collection<SootMethod> getAdditionalMethods();
Collection<SootField> getAdditionalFields();
SootMethod getGeneratedMainMethod();
}
- BaseEntryPointCreator: 创建一个空的dummyMainClass, dummyMainMethod
- DefaultEntryPointCreator
任意顺序处理entry point method
- 通过传入的函数签名,往dummyMainMethod中添加对这些函数签名的调用
- 调用顺序任意
- SequentialEntryPointCreator
- 调用顺序就是一个列表
- 其它的EntryPointCreator都是android相关的
- DefaultEntryPointCreator
IInfoflowConfig
soot.jimple.infoflow.config.IInfoflowConfig
用于配置FlowDroid的InfoflowConfiguration
和Soot的Options
public interface IInfoflowConfig {
void setSootOptions(Options options, InfoflowConfiguration config);
}
// 比如
// 配置污染路径:能够得到比较详细的污染路径
config.getPathConfiguration().setPathReconstructionMode(InfoflowConfiguration.PathReconstructionMode.Precise);
InfoflowManager
最重要的两次实例化:
- 一次是forward 前向污点分析时实例化
- 一次是backward 后向别名分析时实例化
class InfoflowManager {
// 配置Infoflow
InfoflowConfiguration config;
// IFDS/IDE求解器 (forward: source -> sink)
IInfoflowSolver forwardSolver;
// ICFG, 流程间控制流图
IInfoflowCFG icfg;
// SourceSinkManager
ISourceSinkManager sourceSinkManager;
// 污点传播Wrapper
ITaintPropagationWrapper taintWrapper;
// 类型工具
TypeUtils typeUtils;
// 快速Hierarchy
FastHierarchy hierarchy;
// AccessPath 工厂类
AccessPathFactory accessPathFactory;
// 全局污点管理
GlobalTaintManager globalTaintManager;
// 别名
Aliasing aliasing;
}
污染传播相关
IInfoflowSolver
public interface soot.jimple.infoflow.solver.IInfoflowSolver {
// 当求解时,调度给定的边。如果边早已经被处理过,返回false
boolean processEdge(PathEdge<Unit, Abstraction> edge);
// 通过incoming抽象,给出方法的summary
Set<Pair<Unit, Abstraction>> endSummary(SootMethod m, Abstraction d3);
void injectContext(IInfoflowSolver otherSolver,
SootMethod callee,
Abstraction d3,
Unit callSite,
Abstraction d2,
Abstraction d1);
void cleanup();
void setFollowReturnsPastSeedsHandler(IFollowReturnsPastSeedsHandler handler);
void setMemoryManager(IMemoryManager<Abstraction, Unit> memoryManager);
IMemoryManager<Abstraction, Unit> getMemoryManager();
void setPredecessorShorteningMode(PredecessorShorteningMode mode);
long getPropagationCount();
void solve();
void setSolverId(boolean solverId);
// 求解器对应的IFDS Problem
AbstractInfoflowProblem getTabulationProblem();
void setMaxJoinPointAbstractions(int maxJoinPointAbstractions);
void setMaxCalleesPerCallSite(int maxCalleesPerCallSite);
void setMaxAbstractionPathLength(int maxAbstractionPathLength);
void setPeerGroup(SolverPeerGroup solverPeerGroup);
void terminate();
}
ISourceSinkManager
// SourceSinkManager用于告诉是否一条语句包含Source或者Sink
interface soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager {
// 初始化
void initialize();
// 看是否一个Stmt包含一个Source
SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager);
// 看是否一个Stmt包含一个Sink
SinkInfo getSinkInfo(Stmt sCallSite, InfoflowManager manager, AccessPath ap);
}
ISourceSinkManager
的具体实现:
BaseSourceSinkManager
BaseSourceSinkManager implements ISourceSinkManager, IOneSourceAtATimeManager {
DefaultSourceSinkManager
默认 SourceSinkManager,调用computeInfoflow时通过传入sources, sinks集合会默认创建一个DefaultSourceSinkManager
也可提供一个ISourceSinkDefinitionProvider实例作为SourceSink的定义源
DefaultSourceSinkManager implements ISourceSinkManager {
MethodBasedSourceSinkManager
基于方法的SourceSinkManager, 用于用户扩展的类,给定一个callSite, 我们只需要决定它的targetMethod的sourceSink相关信息
MethodBasedSourceSinkManager implements ISourceSinkManager {
-
EmptySourceSinkManager
空SourceSinkManager
EmptySourceSinkManager extends MethodBasedSourceSinkManager {
SummarySourceSinkManager
: 可使用它来生成方法的Summaries。
SummaryGenerator就使用它来生成方法的污点摘要
SummarySourceSinkManager implements ISourceSinkManager {
ISourceSinkDefinitionProvider
可用于给ISourceSinkManager类提供source,sink的定义
public interface soot.jimple.infoflow.sourcesSinks.definitions.ISourceSinkDefinitionProvider {
Set<? extends ISourceSinkDefinition> getSources();
Set<? extends ISourceSinkDefinition> getSinks();
Set<? extends ISourceSinkDefinition> getAllMethods();
}
- XMLSourceSinkParser: 测试类XmlParserTest查看使用
- FilteringSourceSinkDefinitionProvider
- NullSourceSinkDefinitionProvider
PropagationRuleManager
IPropagationRuleManagerFactory(只有一个子类DefaultPropagationRuleManagerFactory) 用于创建 PropagationRuleManager
InfoflowProblem实例化时需要传入IPropagationRuleManagerFactory
// 用于管理传播规则
soot.jimple.infoflow.problems.rules.PropagationRuleManager
ITaintPropagationWrapper
定义不应该被直接分析的类、方法。相反,分析结果取自外部模型中的方法摘要(which improves performance and helps if the sources are not available)
interface soot.jimple.infoflow.taintWrappers.ITaintPropagationWrapper {
void initialize(InfoflowManager manager);
// 检查调用语句用于黑盒污点传播, 这能让我们手动在方法调用间传播污点, 而不要求分析深入到方法内
Set<Abstraction> getTaintsForMethod(Stmt stmt, Abstraction d1, Abstraction taintedPath);
// 告诉分析器不要在callee内部传播
boolean isExclusive(Stmt stmt, Abstraction taintedPath);
// 被摘要的方法通过给定抽象生成的可能的别名
Set<Abstraction> getAliasesForMethod(Stmt stmt, Abstraction d1, Abstraction taintedPath);
boolean supportsCallee(SootMethod method);
boolean supportsCallee(Stmt callSite);
int getWrapperHits();
int getWrapperMisses();
}
soot.jimple.infoflow.cmd.MainClass#initializeTaintWrapper方法中有ITaintPropagationWrapper的各种实例化方式,可供参考
- IReversibleTaintWrapper
- SummaryTaintWrapper: 通过IMethodSummaryProvider提供Summary, 使用StubDroid创建的方法摘要
- ReportMissingSummaryWrapper
- TaintWrapperList: 遍历ITaintPropagationWrapper列表list,如果list中有一个返回非空污点集合,此集合就被使用
- TaintWrapperSet: 遍历ITaintPropagationWrapper集合Set, 将所有返回的非空污点集合作并集
- SummaryTaintWrapper: 通过IMethodSummaryProvider提供Summary, 使用StubDroid创建的方法摘要
- AbstractTaintWrapper
- *EasyTaintWrapper
- IdentityTaintWrapper: 如果receiver object或者函数调用的入参有污点,那么返回值也被污染
- RecordingTaintWrapper: 用于记录统计数据, 从不会返回任何污点信息
- SummaryGenerationTaintWrapper: 在summary构造的时候使用
IMethodSummaryProvider
// 能提供方法摘要的公共类接口
interface IMethodSummaryProvider {
Set<String> getLoadableClasses();
// 支持直接返回方法summary的类
Set<String> getSupportedClasses();
// 是否支持提供该类的方法summary
boolean supportsClass(String clazz);
//
default ClassMethodSummaries getMethodFlows(SootClass sootClass, String methodSubSignature) {
return getMethodFlows(sootClass.getName(), methodSubSignature);
}
ClassMethodSummaries getMethodFlows(String className, String methodSignature);
ClassSummaries getMethodFlows(Set<String> classes, String methodSignature);
ClassMethodSummaries getClassFlows(String clazz);
boolean mayHaveSummaryForMethod(String subsig);
ClassSummaries getSummaries();
boolean isMethodExcluded(String className, String subSignature);
}
- XMLSummaryProvider: 从外部xml文件中加载Summary
- LazySummaryProvider: 懒加载summary
- EagerSummaryProvider: 实例化时立即load summary
- MemorySummaryProvider: 从内存数据结构中加载Summary
- MergingSummaryProvider: IMethodSummaryProvider的组合
工具类
SootMethodRepresentationParser
- 解析方法签名
标签:Set,架构,String,void,剖析,boolean,ISourceSinkManager,FlowDroid,污点 来源: https://blog.csdn.net/qq_37206105/article/details/119334544