connglli / ELEGANT

ELEGANT - a tool to Effectively LocatE fraGmentAtion-iNduced compaTibility issues.
MIT License
3 stars 0 forks source link

weekly report: 2017.09.20-2017.09.26 #7

Closed connglli closed 6 years ago

connglli commented 6 years ago

周报

2017.09.20 ~ 2017.09.26

这周的工作相比前几周有了些进展,但问题还未完全解决。这次的周报还是主要汇报这周的工作进展,同时理一下目前仍然存在需要讨论的问题。

问题解决

首先说上周提到的三个问题:

  1. 如何对 field 和 iface 进行定位
  2. PDG 目前已经可以构建,并且可以成功得到针对某个 callsite 的依赖节点,但却无法明确地获得其对应的 Unit
  3. 如何添加一个 intra-procedural 的 data-flow analysis 来对 DDG 进行捕获

上周提出这三个问题后 Lili 很快给出了解答,非常感谢!针对 Lili 的回答我也对代码进行了修改:

针对第一个问题,Lili 也提到很难对这种 API 进行定位,尤其是一些编译优化的存在使得底层代码变动的更大,比如直接使用常量折叠与常量计算把一些高级 API 里才会用到的常量直接利用字面量替换了进去。这种很难进行捕捉。因此这两种暂时进行了 @WARNING 提示。

代码中暂时以 TODO 的形式留下了:

case ApiField.TAG: {
    // TODO I have no idea how to get the callsite of a specific field

    System.out.println("@WARNING: Model of @field is not supported by now");

    // ApiField apiField = (ApiField) model.getApi();
    // SootField sootField = scene.getField(apiField.getSiganiture());

    break;
}

针对第二个问题,也是困扰了我一段时间的问题,Lili 的实现中直接使用了 Block 对应的 Units,而并未定位到具体的 Unit,这在分析的准确性上也不会影响,接受 Lili 的建议,这里我也直接这样做了。这部分代码的相关逻辑主要是这样(注释部分):

/**
 * Backward slicing algorithm.
 *
 * we find the backward slicing of a unit by:
 *  1. get the corresponding pdg, which describes the unit's method
 *  2. find the corresponding PDGNode srcNode, which contains the unit
 *  3. find all the dependent PDGNodes of srcNode
 *  4. get all the units of each dependent PDGNode
 *
 */
private Set<Unit> runBackwardSlicingFor(Callsite callsite);

针对第三个问题,由于目前对 SDG 的了解不是很多,因此暂时还未实现。

进展

进展一

这周在稍微有点头绪后,先把整个代码需要运行起来的其他部分完成了,也就是 PubSub 模式的 Tracker/Issue。代码集中在 tracker 包下。

进展二

对检测 Issue 是否会得到解决做了初步判断,主要是根据 Context 给出的条件对 Jimple Stmt 进行判断,判断其是否会进行相关的环境判断(如 api level,devices)等,但现在的判断非常不精确,仅仅会检查其是否会对 os.Build 进行调用,具体的值判断还需要对 Stmt 进行分析,个人觉得这也是一个难点。由于针对不同的 API 会有不同的检测方式,甚至对同一种 API 也会有多种检测方式和实现方式,即使利用 slicing 恐怕也难以进行。还需进一步思考。目前这部分判断在:

/**
 * Check whether the stmt can handle the specific issue
 *
 */
public boolean canHandleIssue(ApiContext model, Unit unit) {
    // we only parse Jimple
    if (!(unit instanceof Stmt) || !((Stmt) unit).containsFieldRef()) {
        return false;
    }

    //
    // TODO CHECK
    //  I don;t know exactly what FieldRef of a Stmt is!!!
    //  what if a Stmt contains more than one SootField?
    //
    Stmt stmt = (Stmt) unit;
    SootField field = stmt.getFieldRef().getField();
    String siganiture = field.getSignature();

    if (model.needCheckApiLevel() || model.needCheckSystemVersion()) {
        return Strings.contains(siganiture,
                "android.os.Build.VERSION_CODES",
                "android.os.Build.VERSION.SDK_INT",
                "android.os.Build.VERSION.SDK");
    }

    if (model.hasBadDevices()) {
        return Strings.contains(siganiture,
                "android.os.Build.BOARD",
                "android.os.Build.BRAND",
                "android.os.Build.DEVICE",
                "android.os.Build.PRODUCT");
    }

    return false;
}
进展三

各部分到目前为止已经搭建好了,而且每部分也都有了基础的实现代码,接下来就到遗留问题了!

遗留问题

照常,对问题进行解释与说明:

SDG

SDG 构建还未进行,上面提到了。

unitIteratorOfPDGNode

Set<Unit> runBackwardSlicingFor(Callsite callsite) 依赖于方法 Iterator<Unit> unitIteratorOfPDGNode(PDGNode n),该方法做了如下假设:

假设 PDGNode 的类型仅有 CFGNODEREGION 两种,因为 Soot 的 javaDOC 中有这么几句:

In essence, the PDG nodes represent (within them) either CFG nodes or Region nodes.

直接认为该 DOC 是正确的(DOC 太乱,都不敢相信其正确性),因此做了如下实现:

/**
 * In javaDoc of Soot, the following information are mentioned:
 *
 *   This class(PDGNode) defines a Node in the Program Dependence
 *   Graph. There might be a need to store additional information
 *   in the PDG nodes. In essence, the PDG nodes represent (within
 *   them) either CFG nodes or Region nodes.
 *
 * So we simply considered that as only CFGNODE and REGION are allowed
 */
private Iterator<Unit> unitIteratorOfPDGNode(PDGNode n) {
    Iterator<Unit> iterator = null;
    PDGNode.Type type = n.getType();

    // get iterator
    if (type.equals(PDGNode.Type.CFGNODE)) {
        iterator = ((Block) n.getNode()).iterator();
    } else if (type.equals(PDGNode.Type.REGION)) {
        iterator = ((Region) n.getNode()).getUnitGraph().iterator();
    } else {
        System.out.println("Only REGION and CFGNODE are allowed");
    }

    return iterator;
}
canHandleIssue

boolean canHandleIssue(ApiContext model, Unit unit) 目前实现过于简单,上面也提到过,是个难点。

心声