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

项目: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;
}
项目:LibScout    文件:LayoutFileParser.java   
@Override
public void attr(String ns, String name, int resourceId, int type, Object obj) {
    // Is this the target file attribute?
    String tname = name.trim();
    if (tname.equals("layout")) {
        if (type == AxmlVisitor.TYPE_REFERENCE && obj instanceof Integer) {
            // We need to get the target XML file from the binary manifest
            AbstractResource targetRes = resParser.findResource((Integer) obj);
            if (targetRes == null) {
                logger.trace(Utils.INDENT + "Target resource " + obj + " for layout include not found");
                return;
            }    
            if (!(targetRes instanceof StringResource)) {
                logger.trace(Utils.INDENT + "Invalid target node for include tag in layout XML, was " + targetRes.getClass().getName());
                return;
            }    
            String targetFile = ((StringResource) targetRes).getValue();

            // If we have already processed the target file, we can
            // simply copy the callbacks we have found there
            if (callbackMethods.containsKey(targetFile))
                for (String callback : callbackMethods.get(targetFile))
                    addCallbackMethod(layoutFile, callback);
            else {
                // We need to record a dependency to resolve later
                MapUtils.addToSet(includeDependencies, targetFile, layoutFile);
            }    
        }    
    }    

    super.attr(ns, name, resourceId, type, obj);
}
项目:JAADAS    文件:LayoutFileParser.java   
/**
 * Parses the attributes required for a layout file inclusion
 * @param layoutFile The full path and file name of the file being parsed
 * @param rootNode The AXml node containing the attributes
 */
private void parseIncludeAttributes(String layoutFile, AXmlNode rootNode) {
    for (Entry<String, AXmlAttribute<?>> entry : rootNode.getAttributes().entrySet()) {
        String attrName = entry.getKey().trim();
        AXmlAttribute<?> attr = entry.getValue();

        if (attrName.equals("layout")) {
            if ((attr.getType() == AxmlVisitor.TYPE_REFERENCE || attr.getType() == AxmlVisitor.TYPE_INT_HEX)
                    && attr.getValue() instanceof Integer) {
                // We need to get the target XML file from the binary manifest
                AbstractResource targetRes = resParser.findResource((Integer) attr.getValue());
                if (targetRes == null) {
                    System.err.println("Target resource " + attr.getValue() + " for layout include not found");
                    return;
                }
                if (!(targetRes instanceof StringResource)) {
                    System.err.println("Invalid target node for include tag in layout XML, was "
                            + targetRes.getClass().getName());
                    return;
                }
                String targetFile = ((StringResource) targetRes).getValue();

                // If we have already processed the target file, we can
                // simply copy the callbacks we have found there
                if (callbackMethods.containsKey(targetFile))
                    for (String callback : callbackMethods.get(targetFile))
                        addCallbackMethod(layoutFile, callback);
                else {
                    // We need to record a dependency to resolve later
                    addToMapSet(includeDependencies, targetFile, layoutFile);
                }
            }
        }
    }
}
项目: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   
/**
 * 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");
  }
}