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");
}
}