soot-oss / soot

Soot - A Java optimization framework
GNU Lesser General Public License v2.1
2.85k stars 706 forks source link

Analysis dex file that exists in the assets folder #2009

Open HP-Allen opened 10 months ago

HP-Allen commented 10 months ago

gradle:

implementation 'org.soot-oss:soot:4.4.1' 
implementation 'de.upb.cs.swt:heros:1.1.0'
implementation 'org.slf4j:slf4j-simple:2.0.7'
implementation 'org.slf4j:slf4j-api:2.0.7'

java code:

        G.reset();
        Options.v().set_prepend_classpath(true);
        Options.v().set_allow_phantom_refs(true);
        Options.v().set_output_format(Options.output_format_jimple);
        Options.v().set_process_dir(Collections.singletonList("com.camera.zdazz.verName1.2.1.verCode21.apk"));
        Options.v().set_whole_program(true);
        Options.v().set_src_prec(Options.src_prec_apk);
        Options.v().set_app(true);
        Options.v().set_process_multiple_dex(true);
        Options.v().set_android_jars("F:\\android-platforms-master\\platforms");

        Scene.v().loadNecessaryClasses();

        List<SootMethod> entryPoints = new ArrayList<>();

        for (SootClass sc : Scene.v().getApplicationClasses()) {
            entryPoints.addAll(sc.getMethods());
        }
        Scene.v().setEntryPoints(entryPoints);

        PackManager.v().runPacks();

debug information:

Exception in thread "main" java.lang.RuntimeException: error: backward analysis on an empty entry set.
    at soot.toolkits.scalar.FlowAnalysis$Orderer.newUniverse(FlowAnalysis.java:180)
    at soot.toolkits.scalar.FlowAnalysis.doAnalysis(FlowAnalysis.java:531)
    at soot.toolkits.scalar.BackwardFlowAnalysis.doAnalysis(BackwardFlowAnalysis.java:50)
    at soot.toolkits.scalar.SimpleLiveLocals.<init>(SimpleLiveLocals.java:70)
    at soot.toolkits.scalar.FastColorer.assignColorsToLocals(FastColorer.java:158)
    at soot.toolkits.scalar.LocalPacker.internalTransform(LocalPacker.java:117)
    at soot.BodyTransformer.transform(BodyTransformer.java:52)
    at soot.BodyTransformer.transform(BodyTransformer.java:56)
    at soot.dexpler.DexBody.jimplify(DexBody.java:869)
    at soot.dexpler.DexMethod$1.getBody(DexMethod.java:117)
    at soot.SootMethod.retrieveActiveBody(SootMethod.java:447)
    at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processNewMethod(OnFlyCallGraphBuilder.java:797)
    at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processReachables(OnFlyCallGraphBuilder.java:293)
    at soot.jimple.toolkits.callgraph.CallGraphBuilder.build(CallGraphBuilder.java:108)
    at soot.jimple.toolkits.callgraph.CHATransformer.internalTransform(CHATransformer.java:54)
    at soot.SceneTransformer.transform(SceneTransformer.java:36)
    at soot.Transform.apply(Transform.java:105)
    at soot.RadioScenePack.internalApply(RadioScenePack.java:64)
    at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:61)
    at soot.Pack.apply(Pack.java:118)
    at soot.PackManager.runWholeProgramPacks(PackManager.java:619)
    at soot.PackManager.runPacksNormally(PackManager.java:500)
    at soot.PackManager.runPacks(PackManager.java:425)
    at org.example.Main.main(Main.java:32)

I found that it analysed dex file that exists in the assets folder: info1

After I remove the assets/notplugmapnaveinfoox111.dex file, there was no error anymore: info2

Modified code in soot.dexpler.DexFileProvider.mappingForFile:

private Map<String, DexContainer<? extends DexFile>> mappingForFile(File dexSourceFile) throws IOException {
    int api = Scene.v().getAndroidAPIVersion();
    boolean multiple_dex = Options.v().process_multiple_dex();

    // load dex files from apk/folder/file
    MultiDexContainer<? extends DexBackedDexFile> dexContainer
        = loadDexContainer(dexSourceFile, Opcodes.forApi(api));

    // modified code from here ********************************************************************
    List<String> dexEntryNameAllList = dexContainer.getDexEntryNames();

    // remove subfolder dex files
    List<String> dexEntryNameList = new ArrayList<>();
    for (String entryName : dexEntryNameAllList) {
      if (!entryName.contains("/")) {
        dexEntryNameList.add(entryName);
      }
    }
    // modified code to here ********************************************************************

    int dexFileCount = dexEntryNameList.size();

    if (dexFileCount < 1) {
      if (Options.v().verbose()) {
        logger.debug("" + String.format("Warning: No dex file found in '%s'", dexSourceFile));
      }
      return Collections.emptyMap();
    }

    Map<String, DexContainer<? extends DexFile>> dexMap = new HashMap<>(dexFileCount);

    // report found dex files and add to list.
    // We do this in reverse order to make sure that we add the first entry if there is no classes.dex file in single dex
    // mode
    ListIterator<String> entryNameIterator = dexEntryNameList.listIterator(dexFileCount);
    while (entryNameIterator.hasPrevious()) {
      String entryName = entryNameIterator.previous();
      DexEntry<? extends DexFile> entry = dexContainer.getEntry(entryName);
      entryName = deriveDexName(entryName);
      logger.debug("" + String.format("Found dex file '%s' with %d classes in '%s'", entryName,
          entry.getDexFile().getClasses().size(), dexSourceFile.getCanonicalPath()));

      if (multiple_dex) {
        dexMap.put(entryName, new DexContainer<>(entry, entryName, dexSourceFile));
      } else if (dexMap.isEmpty() && (entryName.equals("classes.dex") || !entryNameIterator.hasPrevious())) {
        // We prefer to have classes.dex in single dex mode.
        // If we haven't found a classes.dex until the last element, take the last!
        dexMap = Collections.singletonMap(entryName, new DexContainer<>(entry, entryName, dexSourceFile));
        if (dexFileCount > 1) {
          logger.warn("Multiple dex files detected, only processing '" + entryName
              + "'. Use '-process-multiple-dex' option to process them all.");
        }
      }
    }
    return Collections.unmodifiableMap(dexMap);
  }
HP-Allen commented 10 months ago

Sorry for the APK file is too big to upload. I found another apk, which could also trigger error even though the error information is not same as top. Importantly, it can also be fixed with the above modifications.

apk file:

biquge_80230.zip

debug information:

Exception in thread "main" java.lang.IllegalStateException: No body for method <bykvm_19do.bykvm_19do.bykvm_if122.bykvm_19do.bykvm_long108.b: void <clinit>()>
    at soot.toolkits.graph.ExceptionalUnitGraph.buildHeadsAndTails(ExceptionalUnitGraph.java:626)
    at soot.toolkits.graph.ExceptionalUnitGraph.initialize(ExceptionalUnitGraph.java:231)
    at soot.toolkits.graph.ExceptionalUnitGraph.<init>(ExceptionalUnitGraph.java:127)
    at soot.toolkits.graph.ExceptionalUnitGraphFactory.newExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:55)
    at soot.toolkits.graph.ExceptionalUnitGraphFactory.createExceptionalUnitGraph(ExceptionalUnitGraphFactory.java:50)
    at soot.dexpler.DexReturnValuePropagator.internalTransform(DexReturnValuePropagator.java:58)
    at soot.BodyTransformer.transform(BodyTransformer.java:52)
    at soot.BodyTransformer.transform(BodyTransformer.java:56)
    at soot.dexpler.DexBody.jimplify(DexBody.java:740)
    at soot.dexpler.DexMethod$1.getBody(DexMethod.java:117)
    at soot.SootMethod.retrieveActiveBody(SootMethod.java:447)
    at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processNewMethod(OnFlyCallGraphBuilder.java:797)
    at soot.jimple.toolkits.callgraph.OnFlyCallGraphBuilder.processReachables(OnFlyCallGraphBuilder.java:293)
    at soot.jimple.toolkits.callgraph.CallGraphBuilder.build(CallGraphBuilder.java:108)
    at soot.jimple.toolkits.callgraph.CHATransformer.internalTransform(CHATransformer.java:54)
    at soot.SceneTransformer.transform(SceneTransformer.java:36)
    at soot.Transform.apply(Transform.java:105)
    at soot.RadioScenePack.internalApply(RadioScenePack.java:64)
    at soot.jimple.toolkits.callgraph.CallGraphPack.internalApply(CallGraphPack.java:61)
    at soot.Pack.apply(Pack.java:118)
    at soot.PackManager.runWholeProgramPacks(PackManager.java:619)
    at soot.PackManager.runPacksNormally(PackManager.java:500)
    at soot.PackManager.runPacks(PackManager.java:425)
    at org.example.Main.main(Main.java:32)

Hope above information are satisfying.