All Downloads are FREE. Search and download functionalities are using the official Maven repository.

qilin.core.reflection.ReflectionModel Maven / Gradle / Ivy

/* Qilin - a Java Pointer Analysis Framework
 * Copyright (C) 2021-2030 Qilin developers
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3.0 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 *
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 */

package qilin.core.reflection;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import qilin.core.PTAScene;
import qilin.util.DataFactory;
import qilin.util.PTAUtils;
import sootup.core.graph.MutableStmtGraph;
import sootup.core.jimple.common.expr.AbstractInvokeExpr;
import sootup.core.jimple.common.stmt.FallsThroughStmt;
import sootup.core.jimple.common.stmt.JAssignStmt;
import sootup.core.jimple.common.stmt.JInvokeStmt;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.Body;
import sootup.core.model.SootMethod;

public abstract class ReflectionModel {
  protected final PTAScene ptaScene;
  protected final String sigForName =
      "";
  protected final String sigForName2 =
      "";
  protected final String sigClassNewInstance = "";
  protected final String sigConstructorNewInstance =
      "";
  protected final String sigMethodInvoke =
      "";
  protected final String sigFieldSet =
      "";
  protected final String sigFieldGet =
      "";
  protected final String sigArrayNewInstance =
      "";
  protected final String sigArrayGet =
      "";
  protected final String sigArraySet =
      "";
  protected final String sigReifiedField =
      "";
  protected final String sigReifiedDeclaredField =
      "";
  protected final String sigReifiedFieldArray =
      "";
  protected final String sigReifiedDeclaredFieldArray =
      "";
  protected final String sigReifiedMethod =
      "";
  protected final String sigReifiedDeclaredMethod =
      "";
  protected final String sigReifiedMethodArray =
      "";
  protected final String sigReifiedDeclaredMethodArray =
      "";

  protected ReflectionModel(PTAScene ptaScene) {
    this.ptaScene = ptaScene;
  }

  private Collection transform(Stmt s) {
    AbstractInvokeExpr ie = s.getInvokeExpr();
    switch (ie.getMethodSignature().toString()) {
      case sigForName:
      case sigForName2:
        return transformClassForName(s);
      case sigClassNewInstance:
        return transformClassNewInstance(s);
      case sigConstructorNewInstance:
        return transformContructorNewInstance(s);
      case sigMethodInvoke:
        return transformMethodInvoke(s);
      case sigFieldSet:
        return transformFieldSet(s);
      case sigFieldGet:
        return transformFieldGet(s);
      case sigArrayNewInstance:
        return transformArrayNewInstance(s);
      case sigArrayGet:
        return transformArrayGet(s);
      case sigArraySet:
        return transformArraySet(s);
      default:
        return Collections.emptySet();
    }
  }

  /** replace reflection call with appropriate statements */
  public void buildReflection(SootMethod m) {
    if (!ptaScene.reflectionBuilt.add(m)) {
      return;
    }
    Map> newUnits = DataFactory.createMap();
    Body body = PTAUtils.getMethodBody(m);
    List units = body.getStmts();
    for (final Stmt u : units) {
      if (u.containsInvokeExpr()) {
        newUnits.put(u, transform(u));
      }
    }
    Body.BodyBuilder builder = Body.builder(body, Collections.emptySet());
    final MutableStmtGraph stmtGraph = builder.getStmtGraph();
    for (Stmt unit : newUnits.keySet()) {
      for (Stmt succ : newUnits.get(unit)) {
        if (succ instanceof JAssignStmt) {
          JAssignStmt assign = (JAssignStmt) succ;
          stmtGraph.insertBefore(unit, assign);
        } else if (succ instanceof JInvokeStmt) {
          JInvokeStmt invoke = (JInvokeStmt) succ;
          stmtGraph.insertBefore(unit, invoke);
        } else {
          System.out.println("unit:" + unit);
          System.out.println("succ:" + succ.getClass());
          stmtGraph.putEdge((FallsThroughStmt) unit, succ);
        }
      }
    }
    PTAUtils.updateMethodBody(m, builder.build());
  }

  abstract Collection transformClassForName(Stmt s);

  abstract Collection transformClassNewInstance(Stmt s);

  abstract Collection transformContructorNewInstance(Stmt s);

  abstract Collection transformMethodInvoke(Stmt s);

  abstract Collection transformFieldSet(Stmt s);

  abstract Collection transformFieldGet(Stmt s);

  abstract Collection transformArrayNewInstance(Stmt s);

  abstract Collection transformArrayGet(Stmt s);

  abstract Collection transformArraySet(Stmt s);
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy