Java 类soot.jimple.infoflow.android.resources.ARSCFileParser 实例源码

项目:JAADAS    文件:AndroidSourceSinkManager.java   
/**
 * Finds the given resource in the given package
 * 
 * @param resName
 *            The name of the resource to retrieve
 * @param resID
 * @param packageName
 *            The name of the package in which to look for the resource
 * @return The specified resource if available, otherwise null
 */
private AbstractResource findResource(String resName, String resID, String packageName) {
    // Find the correct package
    for (ARSCFileParser.ResPackage pkg : this.resourcePackages) {
        // If we don't have any package specification, we pick the app's
        // default package
        boolean matches = (packageName == null || packageName.isEmpty()) && pkg.getPackageName().equals(this.appPackageName);
        matches |= pkg.getPackageName().equals(packageName);
        if (!matches)
            continue;

        // We have found a suitable package, now look for the resource
        for (ARSCFileParser.ResType type : pkg.getDeclaredTypes())
            if (type.getTypeName().equals(resID)) {
                AbstractResource res = type.getFirstResource(resName);
                return res;
            }
    }
    return null;
}
项目:cheetah    文件:SetupApplicationJIT.java   
public SetupApplicationJIT(String apkFileLocation, String sootCP,
        ISourceSinkDefinitionProvider sourceSinkProvider) {
    this.apkFileLocation = apkFileLocation;
    this.sootCP = sootCP;
    try {
        // Load Android callbacks
        this.androidCallbacks = Activator.getDefault().getAndroidCallbacks();

        // Process manifest
        ProcessManifest processMan = new ProcessManifest(apkFileLocation);
        this.appPackageName = processMan.getPackageName();
        this.entrypoints = processMan.getEntryPointClasses();

        // Parse the resource file
        ARSCFileParser resParser = new ARSCFileParser();
        resParser.parse(apkFileLocation);
        this.resourcePackages = resParser.getPackages();

        // LayoutFileParser
        LayoutFileParser lfp = new LayoutFileParser(this.appPackageName, resParser);
        lfp.parseLayoutFile(apkFileLocation, entrypoints);

        // Create the SourceSinkManager
        Set<SootMethodAndClass> callbacks = new HashSet<>();
        for (Set<SootMethodAndClass> methods : this.callbackMethods.values())
            callbacks.addAll(methods);
        sourceSinkManager = new AccessPathBasedSourceSinkManager(sourceSinkProvider.getSources(),
                sourceSinkProvider.getSinks(), callbacks, LayoutMatchingMode.MatchSensitiveOnly,
                lfp == null ? null : lfp.getUserControlsByID());
        sourceSinkManager.setAppPackageName(this.appPackageName);
        sourceSinkManager.setResourcePackages(this.resourcePackages);
        sourceSinkManager.setEnableCallbackSources(true);
    } catch (IOException | XmlPullParserException e) {
        LOGGER.error("Error initializing " + apkFileLocation);
    }
}
项目:LibScout    文件:LayoutFileParser.java   
public LayoutFileParser(String packageName, ARSCFileParser resParser) {
    this.packageName = packageName;
    this.resParser = resParser;
}
项目:JAADAS    文件:AndroidSourceSinkManager.java   
/**
 * Finds the last assignment to the given local representing a resource ID
 * by searching upwards from the given statement
 * 
 * @param stmt
 *            The statement from which to look backwards
 * @param local
 *            The variable for which to look for assignments
 * @return The last value assigned to the given variable
 */
private Integer findLastResIDAssignment(Stmt stmt, Local local, BiDiInterproceduralCFG<Unit, SootMethod> cfg, Set<Stmt> doneSet) {
    if (!doneSet.add(stmt))
        return null;

    // If this is an assign statement, we need to check whether it changes
    // the variable we're looking for
    if (stmt instanceof AssignStmt) {
        AssignStmt assign = (AssignStmt) stmt;
        if (assign.getLeftOp() == local) {
            // ok, now find the new value from the right side
            if (assign.getRightOp() instanceof IntConstant)
                return ((IntConstant) assign.getRightOp()).value;
            else if (assign.getRightOp() instanceof FieldRef) {
                SootField field = ((FieldRef) assign.getRightOp()).getField();
                for (Tag tag : field.getTags())
                    if (tag instanceof IntegerConstantValueTag)
                        return ((IntegerConstantValueTag) tag).getIntValue();
                    else
                        System.err.println("Constant " + field + " was of unexpected type");
            } else if (assign.getRightOp() instanceof InvokeExpr) {
                InvokeExpr inv = (InvokeExpr) assign.getRightOp();
                if (inv.getMethod().getName().equals("getIdentifier") && inv.getMethod().getDeclaringClass().getName().equals("android.content.res.Resources") && this.resourcePackages != null) {
                    // The right side of the assignment is a call into the
                    // well-known
                    // Android API method for resource handling
                    if (inv.getArgCount() != 3) {
                        System.err.println("Invalid parameter count for call to getIdentifier");
                        return null;
                    }

                    // Find the parameter values
                    String resName = "";
                    String resID = "";
                    String packageName = "";

                    // In the trivial case, these values are constants
                    if (inv.getArg(0) instanceof StringConstant)
                        resName = ((StringConstant) inv.getArg(0)).value;
                    if (inv.getArg(1) instanceof StringConstant)
                        resID = ((StringConstant) inv.getArg(1)).value;
                    if (inv.getArg(2) instanceof StringConstant)
                        packageName = ((StringConstant) inv.getArg(2)).value;
                    else if (inv.getArg(2) instanceof Local)
                        packageName = findLastStringAssignment(stmt, (Local) inv.getArg(2), cfg);
                    else {
                        System.err.println("Unknown parameter type in call to getIdentifier");
                        return null;
                    }

                    // Find the resource
                    ARSCFileParser.AbstractResource res = findResource(resName, resID, packageName);
                    if (res != null)
                        return res.getResourceID();
                }
            }
        }
    }

    // Continue the search upwards
    for (Unit pred : cfg.getPredsOf(stmt)) {
        if (!(pred instanceof Stmt))
            continue;
        Integer lastAssignment = findLastResIDAssignment((Stmt) pred, local, cfg, doneSet);
        if (lastAssignment != null)
            return lastAssignment;
    }
    return null;
}
项目:ic3-dialdroid    文件:SetupApplication.java   
private void calculateCallbackMethods(ARSCFileParser resParser, LayoutFileParser lfp)
    throws IOException {
  AbstractCallbackAnalyzer jimpleClass = null;

  boolean hasChanged = true;
  while (hasChanged) {
    hasChanged = false;

    // Create the new iteration of the main method
    soot.G.reset();
    initializeSoot(true);
    createMainMethod();

    if (jimpleClass == null) {
      // Collect the callback interfaces implemented in the app's
      // source code
      jimpleClass =
          callbackClasses == null ? new DefaultCallbackAnalyzer(config, entrypoints, callbackFile)
              : new DefaultCallbackAnalyzer(config, entrypoints, callbackClasses);
      jimpleClass.collectCallbackMethods();

      // Find the user-defined sources in the layout XML files. This
      // only needs to be done once, but is a Soot phase.
      lfp.parseLayoutFile(apkFileLocation);
    } else {
      jimpleClass.collectCallbackMethodsIncremental();
    }

    // Run the soot-based operations
    PackManager.v().getPack("wjpp").apply();
    PackManager.v().getPack("cg").apply();
    PackManager.v().getPack("wjtp").apply();

    // Collect the results of the soot-based phases
    for (Entry<String, Set<SootMethodAndClass>> entry : jimpleClass.getCallbackMethods()
        .entrySet()) {
      Set<SootMethodAndClass> curCallbacks = this.callbackMethods.get(entry.getKey());
      if (curCallbacks != null) {
        if (curCallbacks.addAll(entry.getValue())) {
          hasChanged = true;
        }
      } else {
        this.callbackMethods.put(entry.getKey(), new HashSet<>(entry.getValue()));
        hasChanged = true;
      }
    }

    if (entrypoints.addAll(jimpleClass.getDynamicManifestComponents())) {
      hasChanged = true;
    }
  }

  // Collect the XML-based callback methods
  collectXmlBasedCallbackMethods(resParser, lfp, jimpleClass);
}
项目:ic3-dialdroid    文件:SetupApplication.java   
/**
 * Collects the XML-based callback methods, e.g., Button.onClick() declared in layout XML files
 *
 * @param resParser The ARSC resource parser
 * @param lfp The layout file parser
 * @param jimpleClass The analysis class that gives us a mapping between layout IDs and components
 */
private void collectXmlBasedCallbackMethods(ARSCFileParser resParser, LayoutFileParser lfp,
    AbstractCallbackAnalyzer jimpleClass) {
  // Collect the XML-based callback methods
  for (Entry<String, Set<Integer>> lcentry : jimpleClass.getLayoutClasses().entrySet()) {
    final SootClass callbackClass = Scene.v().getSootClass(lcentry.getKey());

    for (Integer classId : lcentry.getValue()) {
      AbstractResource resource = resParser.findResource(classId);
      if (resource instanceof StringResource) {
        final String layoutFileName = ((StringResource) resource).getValue();

        // Add the callback methods for the given class
        Set<String> callbackMethods = lfp.getCallbackMethods().get(layoutFileName);
        if (callbackMethods != null) {
          for (String methodName : callbackMethods) {
            final String subSig = "void " + methodName + "(android.view.View)";

            // The callback may be declared directly in the
            // class
            // or in one of the superclasses
            SootClass currentClass = callbackClass;
            while (true) {
              SootMethod callbackMethod = currentClass.getMethodUnsafe(subSig);
              if (callbackMethod != null) {
                addCallbackMethod(callbackClass.getName(), new AndroidMethod(callbackMethod));
                break;
              }
              if (!currentClass.hasSuperclass()) {
                System.err.println("Callback method " + methodName + " not found in class "
                    + callbackClass.getName());
                break;
              }
              currentClass = currentClass.getSuperclass();
            }
          }
        }

        // For user-defined views, we need to emulate their
        // callbacks
        Set<LayoutControl> controls = lfp.getUserControls().get(layoutFileName);
        if (controls != null) {
          for (LayoutControl lc : controls) {
            registerCallbackMethodsForView(callbackClass, lc);
          }
        }
      } else {
        System.err.println("Unexpected resource type for layout class");
      }
    }
  }

  // Add the callback methods as sources and sinks
  {
    Set<SootMethodAndClass> callbacksPlain = new HashSet<SootMethodAndClass>();
    for (Set<SootMethodAndClass> set : this.callbackMethods.values()) {
      callbacksPlain.addAll(set);
    }
    System.out.println("Found " + callbacksPlain.size() + " callback methods for "
        + this.callbackMethods.size() + " components");
  }
}