Skip to content

Commit

Permalink
analyze the try-catch blocks to track relatedValues
Browse files Browse the repository at this point in the history
only the method invocations that throws related exceptions will be considered
  • Loading branch information
hanada committed Aug 11, 2023
1 parent 7d901aa commit 67dcffe
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.iscas.crashtracker.client.exception;

import com.alibaba.fastjson.JSONArray;
import com.esotericsoftware.minlog.Log;
import com.google.common.collect.Lists;
import com.iscas.crashtracker.base.Analyzer;
import com.iscas.crashtracker.base.Global;
Expand Down Expand Up @@ -50,7 +51,7 @@ private void getExceptionList() {
JSONArray exceptionListElement = new JSONArray(new ArrayList<>());
HashSet<SootClass> applicationClasses = new HashSet<>(Scene.v().getApplicationClasses());
for (SootClass sootClass : applicationClasses) {
if(!sootClass.getPackageName().startsWith(ConstantUtils.CGANALYSISPREFIX)) continue;
if(Global.v().getAppModel().getAppName().contains(ConstantUtils.FRAMEWORKPREFIX) && !sootClass.getPackageName().startsWith(ConstantUtils.FRAMEWORKPREFIX)) continue;
exceptionInfoList = new ArrayList<>();
HashSet<SootMethod> methodsInTheClass = new HashSet<>(sootClass.getMethods());
for (SootMethod sootMethod : methodsInTheClass) {
Expand Down Expand Up @@ -86,7 +87,7 @@ private void getExceptionList() {
private void getPermissionSet() {
HashSet<SootClass> applicationClasses = new HashSet<>(Scene.v().getApplicationClasses());
for (SootClass sootClass : applicationClasses) {
if (!sootClass.getPackageName().startsWith(ConstantUtils.CGANALYSISPREFIX)) continue;
if(Global.v().getAppModel().getAppName().contains(ConstantUtils.FRAMEWORKPREFIX) && !sootClass.getPackageName().startsWith(ConstantUtils.FRAMEWORKPREFIX)) continue;
for (SootMethod sootMethod : sootClass.getMethods()) {
if (!sootMethod.hasActiveBody()) continue;
for(Unit u: sootMethod.getActiveBody().getUnits()){
Expand Down Expand Up @@ -141,7 +142,7 @@ private void getOtherNonThrowUnits(Map<SootMethod, Map<Unit, Local>> method2unit
InvokeExpr invoke = SootUtils.getInvokeExp(unit);
if (invoke == null || invoke.getMethod() == null) return;
if (invoke.getMethod().getName().contains("access$") || invoke.getMethod().getName().contains("<init>")) return;
if (!invoke.getMethod().getDeclaringClass().getPackageName().startsWith(ConstantUtils.CGANALYSISPREFIX)) return;
if (Global.v().getAppModel().getAppName().contains(ConstantUtils.FRAMEWORKPREFIX) && !invoke.getMethod().getDeclaringClass().getPackageName().startsWith(ConstantUtils.FRAMEWORKPREFIX)) return;
for (Value arg : invoke.getArgs()) {
if (!arg.getType().toString().endsWith("Throwable") && !arg.getType().toString().endsWith("Exception")) continue;
if (!(arg instanceof Local)) continue;
Expand Down Expand Up @@ -226,7 +227,7 @@ public void getThrowUnitWithType(Map<Unit, String> unit2Message, SootMethod soot
}

} else if (rightValue instanceof CaughtExceptionRef) {
log.warn("Unimplemented condition: rightValue is CaughtExceptionRef");
// log.warn("Unimplemented condition: rightValue is CaughtExceptionRef");
// todo
// caught an Exception here
// $r1 := @caughtexception;
Expand Down Expand Up @@ -536,6 +537,7 @@ private void getExceptionCondition(SootMethod sootMethod, Unit unit, ExceptionIn
SootUtils.getAllPredsofUnit(sootMethod, unit,allPreds);
List<Unit> gotoTargets = getGotoTargets(body);
List<Unit> predsOf = unitGraph.getPredsOf(unit);
boolean ifMeetTryCatch = false;
for (Unit predUnit : predsOf) {
if (predUnit instanceof IfStmt) {
exceptionInfo.getTracedUnits().add(predUnit);
Expand All @@ -561,19 +563,39 @@ private void getExceptionCondition(SootMethod sootMethod, Unit unit, ExceptionIn
JIdentityStmt stmt = (JIdentityStmt) predUnit;
if(stmt.getRightOp() instanceof CaughtExceptionRef){
exceptionInfo.addCaughtValues(stmt.getRightOp());
Log.error("1");
//analyze the try-catch block of this exception
List<Unit> caughtUnits = getTryCatchUnits(sootMethod, predUnit);
SootClass caughtType = getCaughtExceptionType(sootMethod, predUnit);

for(Unit caughtUnit: caughtUnits) {
boolean invocationThrowThatException = isInvocationThrowThatException(caughtType,caughtUnit);
if(invocationThrowThatException==false) continue;
for (ValueBox vb : caughtUnit.getUseBoxes()) {
extendRelatedValues(sootMethod,SootUtils.getUnitListFromMethod(sootMethod), exceptionInfo, caughtUnit, vb.getValue(), new ArrayList<>(), getCondHistory, fromThrow);
}
ifMeetTryCatch = true;
}
}
}
if(ifMeetTryCatch) continue;
getExceptionCondition(sootMethod, predUnit, exceptionInfo,getCondHistory, fromThrow, lastGoto);
}
}

private boolean isInvocationThrowThatException(SootClass caughtType, Unit caughtUnit) {
if(caughtType==null) return true;
InvokeExpr invokeExpr = SootUtils.getInvokeExp(caughtUnit);
if(invokeExpr==null) return false;
for(SootClass throwsException: invokeExpr.getMethod().getExceptions()){
if(Scene.v().getActiveHierarchy().isClassSubclassOfIncluding(throwsException, caughtType)){
return true;
}
}
return false;
}


/**
* tracing the values relates to the one used in if condition
*/
Expand Down Expand Up @@ -606,10 +628,15 @@ private String extendRelatedValues(SootMethod sootMethod, List<Unit> allPreds, E
}else if(identityStmt.getRightOp() instanceof CaughtExceptionRef){
exceptionInfo.addCaughtValues(identityStmt.getRightOp());
//analyze the try-catch block of this exception
Log.error("2");
List<Unit> caughtUnits = getTryCatchUnits(sootMethod, defUnit);
SootClass caughtType = getCaughtExceptionType(sootMethod, defUnit);

for(Unit caughtUnit: caughtUnits) {
boolean invocationThrowThatException = isInvocationThrowThatException(caughtType,caughtUnit);
if(invocationThrowThatException==false) continue;
for (ValueBox vb : caughtUnit.getUseBoxes()) {
extendRelatedValues(sootMethod, SootUtils.getUnitListFromMethod(sootMethod), exceptionInfo, caughtUnit, vb.getValue(), valueHistory, getCondHistory, fromThrow);
extendRelatedValues(sootMethod,SootUtils.getUnitListFromMethod(sootMethod), exceptionInfo, caughtUnit, vb.getValue(), new ArrayList<>(), getCondHistory, fromThrow);
}
}
return "CaughtExceptionRef";
Expand Down Expand Up @@ -676,6 +703,28 @@ private String extendRelatedValues(SootMethod sootMethod, List<Unit> allPreds, E
return "";
}

/**
* get the type of the caught exception
* @param sootMethod
* @param defUnit
* @return
*/
private SootClass getCaughtExceptionType(SootMethod sootMethod, Unit defUnit) {
for (Trap trap : sootMethod.getActiveBody().getTraps()) {
if (trap.getHandlerUnit() == defUnit) {
return trap.getException();
}
}
return null;
}


/**
* get the units in the try-catch block
* @param sootMethod
* @param defUnit
* @return
*/
private List getTryCatchUnits(SootMethod sootMethod, Unit defUnit) {
List<Unit> tryCatchUnits = new ArrayList<>();
for (Trap trap : sootMethod.getActiveBody().getTraps()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.iscas.crashtracker.utils.ConstantUtils;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import soot.PackManager;

import java.io.IOException;

Expand All @@ -27,6 +28,7 @@ protected void clientAnalyze() {
if (!MyConfig.getInstance().isSootAnalyzeFinish()) {
SootAnalyzer sootAnalyzer = new SootAnalyzer();
sootAnalyzer.analyze();
// PackManager.v().writeOutput();
}

if (!MyConfig.getInstance().isCallGraphAnalyzeFinish()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,25 @@ public void testConfig() {
}

private void setArgs() {
String path, androidVersion;
String path, targetFolder;
path = "C:\\Users\\yanjw\\programs\\framework\\classes\\";
path = "D:\\SoftwareData\\dataset\\android-framework\\classes\\";
MyConfig.getInstance().setAndroidOSVersion("10.0");
// MyConfig.getInstance().setAndroidOSVersion("");
path = "..\\M_framework\\";

String client = "ExceptionInfoClient";

androidVersion = "android"+MyConfig.getInstance().getAndroidOSVersion();;
MyConfig.getInstance().setAppName(androidVersion);
targetFolder = "android7.0";;
// targetFolder = "test";
MyConfig.getInstance().setAppName(targetFolder);
MyConfig.getInstance().setAppPath(path + File.separator);
MyConfig.getInstance().setClient(client);
MyConfig.getInstance().setResultWarpperFolder("..\\results" + File.separator);
MyConfig.getInstance().setResultFolder("..\\Files" + File.separator);
MyConfig.getInstance().setResultWarpperFolder("..\\ETSResults" + File.separator);
MyConfig.getInstance().setResultFolder("..\\ETSResults" + File.separator);
MyConfig.getInstance().setTimeLimit(100);
MyConfig.getInstance().setAndroidJar("E:\\AndroidSDK\\android-sdk-windows-new\\platforms");
MyConfig.getInstance().setSrc_prec(Options.src_prec_only_class);
MyConfig.getInstance().setFileSuffixLength(0);
String androidFolder = MyConfig.getInstance().getResultFolder() +File.separator+androidVersion+File.separator;
String androidFolder = MyConfig.getInstance().getResultFolder() +File.separator+targetFolder+File.separator;
MyConfig.getInstance().setExceptionFilePath(androidFolder+"exceptionInfo"+File.separator);
MyConfig.getInstance().setPermissionFilePath(androidFolder+"Permission"+File.separator+"permission.txt");
MyConfig.getInstance().setAndroidCGFilePath(androidFolder+"CallGraphInfo"+File.separator+"cg.txt");
Expand Down
2 changes: 1 addition & 1 deletion scripts/runCrashTracker-Apk.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def analyzeApk(apkPath, resPath, sdk, frameworkVersion, strategy):
if apk[-4:] ==".apk":
resFile = outputDir + os.sep + apk[:-4] + os.sep +apk[:-4] + ".json"
if(reRun or not os.path.exists(resFile) or not isAPKisAnalyzed(resPath,apk[:-4])):
command = "java -jar "+jarFile+" -path "+ apkPath +" -name "+apk+" -androidJar "+ sdk +" "+ extraArgs +" -crashInput Files"+ os.sep +"crashInfo.json -exceptionInput Files -client ApkCrashAnalysisClient" +" -outputDir "+outputDir #+ " >> "+logDir+ os.sep +jar[:-4]+".txt"
command = "java -jar "+jarFile+" -path "+ apkPath +" -name "+apk+" -androidJar "+ sdk +" "+ extraArgs +" -crashInput Files"+ os.sep +"crashInfo.json -exceptionInput ETSResults -client ApkCrashAnalysisClient" +" -outputDir "+outputDir #+ " >> "+logDir+ os.sep +jar[:-4]+".txt"
future1 = pool.submit(executeCmd, command)
pool.shutdown()

Expand Down
2 changes: 1 addition & 1 deletion scripts/runCrashTracker-Jar.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ def analyzeJar(jarPath, resPath, sdk, frameworkVersion, strategy):
resFile = outputDir + os.sep + jar[:-4] + os.sep +jar[:-4] + ".json"
analyzed = isJarisAnalyzed(resPath,jar[:-4])
if(reRun or not os.path.exists(resFile) or not analyzed ):
command = "java -jar "+jarFile+" -path "+ jarPath +" -name "+jar+" -androidJar "+ sdk +" "+ extraArgs +" -crashInput Files"+ os.sep +"crashInfo.json -exceptionInput Files -client JarCrashAnalysisClient" +" -outputDir "+outputDir #+ " >> "+logDir+ os.sep +jar[:-4]+".txt"
command = "java -jar "+jarFile+" -path "+ jarPath +" -name "+jar+" -androidJar "+ sdk +" "+ extraArgs +" -crashInput Files"+ os.sep +"crashInfo.json -exceptionInput ETSResults -client JarCrashAnalysisClient" +" -outputDir "+outputDir #+ " >> "+logDir+ os.sep +jar[:-4]+".txt"
print(command + "@@@"+ str(analyzed))
future1 = pool.submit(executeCmd, command)
pool.shutdown()
Expand Down

0 comments on commit 67dcffe

Please sign in to comment.