Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* 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.builder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import qilin.CoreConfig;
import qilin.core.ArtificialMethod;
import qilin.util.PTAUtils;
import sootup.core.IdentifierFactory;
import sootup.core.frontend.OverridingBodySource;
import sootup.core.frontend.OverridingClassSource;
import sootup.core.graph.MutableStmtGraph;
import sootup.core.inputlocation.EagerInputLocation;
import sootup.core.jimple.Jimple;
import sootup.core.jimple.basic.Immediate;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.NoPositionInformation;
import sootup.core.jimple.basic.StmtPositionInfo;
import sootup.core.jimple.basic.Value;
import sootup.core.jimple.common.ref.JStaticFieldRef;
import sootup.core.jimple.common.stmt.FallsThroughStmt;
import sootup.core.jimple.common.stmt.JNopStmt;
import sootup.core.jimple.common.stmt.JReturnVoidStmt;
import sootup.core.model.*;
import sootup.core.signatures.FieldSignature;
import sootup.core.signatures.MethodSignature;
import sootup.core.signatures.MethodSubSignature;
import sootup.core.types.ClassType;
import sootup.core.views.View;
import sootup.java.core.JavaIdentifierFactory;
public class FakeMainFactory extends ArtificialMethod {
public static FakeMainFactory instance;
public static int implicitCallEdges;
private final SootClass fakeClass;
private final SootClass mainClass;
private final EntryPoints entryPoints;
public FakeMainFactory(View view, SootClass mainClazz) {
super(view);
this.mainClass = mainClazz;
this.entryPoints = new EntryPoints();
this.localStart = 0;
String className = "qilin.pta.FakeMain";
IdentifierFactory fact = view.getIdentifierFactory();
ClassType declaringClassSignature = JavaIdentifierFactory.getInstance().getClassType(className);
FieldSignature ctSig =
fact.getFieldSignature("currentThread", declaringClassSignature, "java.lang.Thread");
SootField currentThread =
new SootField(ctSig, EnumSet.of(FieldModifier.STATIC), NoPositionInformation.getInstance());
FieldSignature gtSig =
fact.getFieldSignature("globalThrow", declaringClassSignature, "java.lang.Exception");
SootField globalThrow =
new SootField(gtSig, EnumSet.of(FieldModifier.STATIC), NoPositionInformation.getInstance());
MethodSignature methodSignatureOne =
view.getIdentifierFactory()
.getMethodSignature(className, "main", "void", Collections.emptyList());
StmtPositionInfo noPosInfo = StmtPositionInfo.getNoStmtPositionInfo();
final JReturnVoidStmt returnVoidStmt = new JReturnVoidStmt(noPosInfo);
final JNopStmt jNop = new JNopStmt(noPosInfo);
this.bodyBuilder = Body.builder();
makeFakeMain(currentThread);
final MutableStmtGraph stmtGraph = bodyBuilder.getStmtGraph();
stmtGraph.addBlock(stmtList);
stmtGraph.setStartingStmt(jNop);
stmtGraph.putEdge(jNop, stmtList.get(0));
stmtGraph.putEdge((FallsThroughStmt) stmtList.get(stmtList.size() - 1), returnVoidStmt);
bodyBuilder
.setMethodSignature(methodSignatureOne)
.setPosition(NoPositionInformation.getInstance());
Body bodyOne = bodyBuilder.build();
SootMethod dummyMainMethod =
new SootMethod(
new OverridingBodySource(methodSignatureOne, bodyOne),
methodSignatureOne,
EnumSet.of(MethodModifier.PUBLIC, MethodModifier.STATIC),
Collections.emptyList(),
NoPositionInformation.getInstance());
this.method = dummyMainMethod;
this.fakeClass =
new SootClass(
new OverridingClassSource(
Collections.singleton(dummyMainMethod),
new LinkedHashSet<>(Arrays.asList(currentThread, globalThrow)),
EnumSet.of(ClassModifier.PUBLIC),
null,
JavaIdentifierFactory.getInstance().getClassType("java.lang.Object"),
null,
NoPositionInformation.getInstance(),
null,
view.getIdentifierFactory().getClassType(className),
new EagerInputLocation()),
SourceType.Application);
}
public SootMethod getFakeMain() {
return this.method;
}
private List getEntryPoints() {
List ret = new ArrayList<>();
if (CoreConfig.v().getPtaConfig().clinitMode == CoreConfig.ClinitMode.FULL) {
ret.addAll(entryPoints.clinits());
} else {
// on the fly mode, resolve the clinit methods on the fly.
ret.addAll(Collections.emptySet());
}
if (CoreConfig.v().getPtaConfig().singleentry) {
List entries = entryPoints.application();
if (entries.isEmpty()) {
throw new RuntimeException("Must specify MAINCLASS when appmode enabled!!!");
} else {
ret.addAll(entries);
}
} else {
ret.addAll(entryPoints.application());
ret.addAll(entryPoints.implicit());
}
System.out.println("#EntrySize:" + ret.size());
return ret;
}
public JStaticFieldRef getFieldCurrentThread() {
SootField field = fakeClass.getField("currentThread").get();
return Jimple.newStaticFieldRef(field.getSignature());
}
public Value getFieldGlobalThrow() {
SootField field = fakeClass.getField("globalThrow").get();
return Jimple.newStaticFieldRef(field.getSignature());
}
private void makeFakeMain(SootField currentThread) {
implicitCallEdges = 0;
for (SootMethod entry : getEntryPoints()) {
if (entry.isStatic()) {
if (entry
.getSignature()
.getSubSignature()
.toString()
.equals("void main(java.lang.String[])")) {
Value mockStr = getNew(PTAUtils.getClassType("java.lang.String"));
Immediate strArray = getNewArray(PTAUtils.getClassType("java.lang.String"));
addAssign(getArrayRef(strArray), mockStr);
addInvoke(entry.getSignature().toString(), strArray);
implicitCallEdges++;
} else if (CoreConfig.v().getPtaConfig().clinitMode != CoreConfig.ClinitMode.ONFLY
|| !PTAUtils.isStaticInitializer(entry)) {
// in the on fly mode, we won't add a call directly for methods.
addInvoke(entry.getSignature().toString());
implicitCallEdges++;
}
}
}
if (CoreConfig.v().getPtaConfig().singleentry) {
return;
}
Local sv = getNextLocal(PTAUtils.getClassType("java.lang.String"));
Local mainThread = getNew(PTAUtils.getClassType("java.lang.Thread"));
Local mainThreadGroup = getNew(PTAUtils.getClassType("java.lang.ThreadGroup"));
Local systemThreadGroup = getNew(PTAUtils.getClassType("java.lang.ThreadGroup"));
JStaticFieldRef gCurrentThread = Jimple.newStaticFieldRef(currentThread.getSignature());
addAssign(gCurrentThread, mainThread); // Store
Local vRunnable = getNextLocal(PTAUtils.getClassType("java.lang.Runnable"));
Local lThreadGroup = getNextLocal(PTAUtils.getClassType("java.lang.ThreadGroup"));
addInvoke(
mainThread,
"(java.lang.ThreadGroup,java.lang.String)>",
mainThreadGroup,
sv);
Local tmpThread = getNew(PTAUtils.getClassType("java.lang.Thread"));
addInvoke(
tmpThread,
"(java.lang.ThreadGroup,java.lang.Runnable)>",
lThreadGroup,
vRunnable);
addInvoke(tmpThread, "");
addInvoke(systemThreadGroup, "()>");
addInvoke(
mainThreadGroup,
"(java.lang.ThreadGroup,java.lang.String)>",
systemThreadGroup,
sv);
Local lThread = getNextLocal(PTAUtils.getClassType("java.lang.Thread"));
Local lThrowable = getNextLocal(PTAUtils.getClassType("java.lang.Throwable"));
Local tmpThreadGroup = getNew(PTAUtils.getClassType("java.lang.ThreadGroup"));
addInvoke(
tmpThreadGroup,
"",
lThread,
lThrowable); // TODO.
// ClassLoader
Local defaultClassLoader = getNew(PTAUtils.getClassType("sun.misc.Launcher$AppClassLoader"));
addInvoke(defaultClassLoader, "()>");
Local vClass = getNextLocal(PTAUtils.getClassType("java.lang.Class"));
Local vDomain = getNextLocal(PTAUtils.getClassType("java.security.ProtectionDomain"));
addInvoke(
defaultClassLoader,
"",
sv);
addInvoke(
defaultClassLoader,
"",
vClass,
vDomain);
addInvoke(
defaultClassLoader, "", vClass);
// PrivilegedActionException
Local privilegedActionException =
getNew(PTAUtils.getClassType("java.security.PrivilegedActionException"));
Local gLthrow = getNextLocal(PTAUtils.getClassType("java.lang.Exception"));
addInvoke(
privilegedActionException,
"(java.lang.Exception)>",
gLthrow);
}
public class EntryPoints {
final MethodSubSignature sigMain;
final MethodSubSignature sigFinalize;
final MethodSubSignature sigExit;
final MethodSubSignature sigClinit;
final MethodSubSignature sigInit;
final MethodSubSignature sigStart;
final MethodSubSignature sigRun;
final MethodSubSignature sigObjRun;
final MethodSubSignature sigForName;
private EntryPoints() {
sigMain = JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_MAIN);
sigFinalize =
JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_FINALIZE);
sigExit = JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_EXIT);
sigClinit =
JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_CLINIT);
sigInit = JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_INIT);
sigStart = JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_START);
sigRun = JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_RUN);
sigObjRun =
JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_OBJ_RUN);
sigForName =
JavaIdentifierFactory.getInstance().parseMethodSubSignature(JavaMethods.SIG_FOR_NAME);
}
protected void addMethod(List set, SootClass cls, MethodSubSignature methodSubSig) {
Optional extends SootMethod> osm = cls.getMethod(methodSubSig);
osm.ifPresent(set::add);
}
protected void addMethod(List set, String methodSig) {
MethodSignature ms = JavaIdentifierFactory.getInstance().parseMethodSignature(methodSig);
Optional extends SootMethod> osm = view.getMethod(ms);
osm.ifPresent(set::add);
}
/**
* Returns only the application entry points, not including entry points invoked implicitly by
* the VM.
*/
public List application() {
List ret = new ArrayList<>();
if (mainClass != null) {
addMethod(ret, mainClass, sigMain);
for (SootMethod clinit : clinitsOf(mainClass)) {
ret.add(clinit);
}
}
return ret;
}
/** Returns only the entry points invoked implicitly by the VM. */
public List implicit() {
List ret = new ArrayList();
// if (Options.v().src_prec() == Options.src_prec_dotnet) {
// return ret;
// }
addMethod(ret, JavaMethods.INITIALIZE_SYSTEM_CLASS);
addMethod(ret, JavaMethods.THREAD_GROUP_INIT);
// addMethod( ret, "");
addMethod(ret, JavaMethods.THREAD_EXIT);
addMethod(ret, JavaMethods.THREADGROUP_UNCAUGHT_EXCEPTION);
// addMethod( ret, "");
addMethod(ret, JavaMethods.CLASSLOADER_INIT);
addMethod(ret, JavaMethods.CLASSLOADER_LOAD_CLASS_INTERNAL);
addMethod(ret, JavaMethods.CLASSLOADER_CHECK_PACKAGE_ACC);
addMethod(ret, JavaMethods.CLASSLOADER_ADD_CLASS);
addMethod(ret, JavaMethods.CLASSLOADER_FIND_NATIVE);
addMethod(ret, JavaMethods.PRIV_ACTION_EXC_INIT);
// addMethod( ret, "");
addMethod(ret, JavaMethods.RUN_FINALIZE);
addMethod(ret, JavaMethods.THREAD_INIT_RUNNABLE);
addMethod(ret, JavaMethods.THREAD_INIT_STRING);
return ret;
}
/** Returns all the entry points. */
public List all() {
List ret = new ArrayList();
ret.addAll(application());
ret.addAll(implicit());
return ret;
}
/** Returns a list of all static initializers. */
public List clinits() {
List ret = new ArrayList<>();
Collection extends SootClass> classes = view.getClasses();
for (SootClass cl : classes) {
addMethod(ret, cl, sigClinit);
}
return ret;
}
/** Returns a list of all clinits of class cl and its superclasses. */
public Iterable clinitsOf(SootClass cl) {
// Do not create an actual list, since this method gets called quite often
// Instead, callers usually just want to iterate over the result.
Optional extends SootMethod> oinit = cl.getMethod(sigClinit);
Optional extends ClassType> osuperClass = cl.getSuperclass();
// check super classes until finds a constructor or no super class there anymore.
while (!oinit.isPresent() && osuperClass.isPresent()) {
ClassType superType = osuperClass.get();
Optional extends SootClass> oSuperClass = view.getClass(superType);
if (!oSuperClass.isPresent()) {
break;
}
SootClass superClass = oSuperClass.get();
oinit = superClass.getMethod(sigClinit);
osuperClass = superClass.getSuperclass();
}
if (!oinit.isPresent()) {
return Collections.emptyList();
}
SootMethod initStart = oinit.get();
return () ->
new Iterator() {
SootMethod current = initStart;
@Override
public SootMethod next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
SootMethod n = current;
// Pre-fetch the next element
current = null;
Optional extends SootClass> oCurrentClass =
view.getClass(n.getDeclaringClassType());
if (!oCurrentClass.isPresent()) {
return n;
}
SootClass currentClass = oCurrentClass.get();
while (true) {
Optional extends ClassType> osuperType1 = currentClass.getSuperclass();
if (!osuperType1.isPresent()) {
break;
}
ClassType classType = osuperType1.get();
Optional extends SootClass> osuperClass1 = view.getClass(classType);
if (!osuperClass1.isPresent()) {
break;
}
SootClass superClass = osuperClass1.get();
Optional extends SootMethod> om = superClass.getMethod(sigClinit);
if (om.isPresent()) {
current = om.get();
break;
}
currentClass = superClass;
}
return n;
}
@Override
public boolean hasNext() {
return current != null;
}
};
}
}
}