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