其他分享
首页 > 其他分享> > FlowDroid架构剖析

FlowDroid架构剖析

作者:互联网

最近算是把FlowDroid源代码翻了一遍,并非通读,而是把整个系统的逻辑/设计整理了一下。这里稍微记录一下。由于FlowDroid能够分析Android程序,所以有一部分代码是对Android相关领域做适配,由于个人目前的工作对Android静态分析还不是很涉及,所以在分析FlowDroid源码时省略了Android相关的适配代码,主要是作通用Java相关的分析。

FlowDroid

几大组件:

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();
}

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

最重要的两次实例化:

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 implements ISourceSinkManager, IOneSourceAtATimeManager {
  DefaultSourceSinkManager implements ISourceSinkManager {
  MethodBasedSourceSinkManager implements ISourceSinkManager {
    EmptySourceSinkManager extends MethodBasedSourceSinkManager {
  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();
}

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的各种实例化方式,可供参考

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);
}

工具类

SootMethodRepresentationParser

标签:Set,架构,String,void,剖析,boolean,ISourceSinkManager,FlowDroid,污点
来源: https://blog.csdn.net/qq_37206105/article/details/119334544