support for deodexing methods read from Dalvik, using support in dexlib2

This commit is contained in:
Julian Dolby 2017-08-08 06:34:48 -04:00
parent e7a152341c
commit ecdb599674
6 changed files with 70 additions and 16 deletions

View File

@ -30,6 +30,7 @@ public final class ConstantKey<T> implements InstanceKey {
public ConstantKey(T value, IClass valueClass) {
this.value = value;
this.valueClass = valueClass;
assert valueClass != null;
}
@Override

View File

@ -76,11 +76,15 @@ public class Util {
public static URI[] androidLibs() {
List<URI> libs = new ArrayList<>();
if (walaProperties != null && walaProperties.getProperty(ANDROID_RT_DEX_DIR) != null) {
if (System.getenv("ANDROID_BOOT_OAT") != null) {
libs.add(new File(System.getenv("ANDROID_CORE_OAT")).toURI());
libs.add(new File(System.getenv("ANDROID_BOOT_OAT")).toURI());
} else if (walaProperties != null && walaProperties.getProperty(ANDROID_RT_DEX_DIR) != null) {
for(File lib : new File(walaProperties.getProperty(ANDROID_RT_DEX_DIR)).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith("dex") || name.endsWith("jar") || name.endsWith("apk");
return name.startsWith("boot") && name.endsWith("oat");
}
})) {
libs.add(lib.toURI());

View File

@ -69,6 +69,7 @@ import com.ibm.wala.util.io.TemporaryFile;
* @author barjo
*/
public class DexFileModule implements Module {
private final File f;
private final DexFile dexfile;
private final Collection<ModuleEntry> entries;
@ -104,7 +105,8 @@ public class DexFileModule implements Module {
*/
private DexFileModule(File f) throws IllegalArgumentException {
try {
dexfile = DexFileFactory.loadDexFile(f, Opcodes.forApi(25));
this.f = f;
dexfile = DexFileFactory.loadDexFile(f, Opcodes.forApi(24));
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
@ -113,7 +115,7 @@ public class DexFileModule implements Module {
entries = new HashSet<>();
for (ClassDef cdefitems : dexfile.getClasses()) {
entries.add(new DexModuleEntry(cdefitems));
entries.add(new DexModuleEntry(cdefitems, this));
}
}
@ -124,6 +126,13 @@ public class DexFileModule implements Module {
return dexfile;
}
/**
* @return The DexFile associated to this module.
*/
public File getFile() {
return f;
}
/*
* (non-Javadoc)
*

View File

@ -47,7 +47,10 @@
package com.ibm.wala.dalvik.classLoader;
import static org.jf.dexlib2.AccessFlags.*;
import static org.jf.dexlib2.AccessFlags.ABSTRACT;
import static org.jf.dexlib2.AccessFlags.INTERFACE;
import static org.jf.dexlib2.AccessFlags.PRIVATE;
import static org.jf.dexlib2.AccessFlags.PUBLIC;
import java.util.ArrayList;
import java.util.Collection;
@ -66,7 +69,6 @@ import com.ibm.wala.classLoader.BytecodeClass;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.Module;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
@ -387,7 +389,7 @@ public class DexIClass extends BytecodeClass<IClassLoader> {
}
@Override
public Module getContainer() {
return dexModuleEntry.asModule();
public DexFileModule getContainer() {
return dexModuleEntry.getContainer();
}
}

View File

@ -68,6 +68,9 @@ import java.util.Map;
import java.util.Set;
import org.jf.dexlib2.Opcode;
import org.jf.dexlib2.analysis.ClassPath;
import org.jf.dexlib2.analysis.ClassPathResolver;
import org.jf.dexlib2.analysis.MethodAnalyzer;
import org.jf.dexlib2.iface.AnnotationElement;
import org.jf.dexlib2.iface.Method;
import org.jf.dexlib2.iface.TryBlock;
@ -710,10 +713,42 @@ public class DexIMethod implements IBytecodeMethod<Instruction> {
return instructions.toArray(new Instruction[ instructions.size() ]);
}
private boolean odexMethod() {
for(org.jf.dexlib2.iface.instruction.Instruction inst : eMethod.getImplementation().getInstructions()) {
if (inst.getOpcode().odexOnly()) {
return true;
}
}
return false;
}
Iterable<? extends org.jf.dexlib2.iface.instruction.Instruction> deodex() {
try {
DexFileModule m = myClass.getContainer();
ClassPathResolver path =
new ClassPathResolver(Collections.singletonList(m.getFile().getParent() + "/"),
Collections.<String>emptyList(),
m.getDexFile());
ClassPath cp = new ClassPath(path.getResolvedClassProviders(), false, 56);
MethodAnalyzer analyzer = new MethodAnalyzer(cp, eMethod, null, false);
return analyzer.getInstructions();
} catch (Exception e) {
assert false : e;
return eMethod.getImplementation().getInstructions();
}
}
protected void parseBytecode() {
Iterable<? extends org.jf.dexlib2.iface.instruction.Instruction> instrucs = eMethod.getImplementation().getInstructions();
Iterable<? extends org.jf.dexlib2.iface.instruction.Instruction> instrucs =
odexMethod()?
deodex():
eMethod.getImplementation().getInstructions();
// for (org.jfmethod.getInstructionIndex(.dexlib.Code.Instruction inst: instrucs)
// {
@ -996,6 +1031,7 @@ public class DexIMethod implements IBytecodeMethod<Instruction> {
getExceptionReg(), inst.getOpcode(), this));
break;
case RETURN_VOID:
case RETURN_VOID_NO_BARRIER:
instructions.add(new Return.ReturnVoid(instLoc, inst.getOpcode(), this));
break;
case RETURN:
@ -1198,8 +1234,8 @@ public class DexIMethod implements IBytecodeMethod<Instruction> {
break;
}
case FILL_ARRAY_DATA:
System.out.println("Array Reference: " + ((Instruction31t)inst).getRegisterA());
System.out.println("Table Address Offset: " + ((Instruction31t)inst).getCodeOffset());
// System.out.println("Array Reference: " + ((Instruction31t)inst).getRegisterA());
// System.out.println("Table Address Offset: " + ((Instruction31t)inst).getCodeOffset());
TypeReference arrayElementType = findOutArrayElementType(inst, instructions.toArray(new Instruction[0]), instCounter);
instructions.add(new ArrayFill(instLoc, ((Instruction31t)inst).getRegisterA(), ((Instruction31t)inst).getCodeOffset(),
@ -2278,7 +2314,7 @@ public class DexIMethod implements IBytecodeMethod<Instruction> {
}
default:
throw new RuntimeException("not implemented instruction: 0x"
+ inst.getOpcode().toString());
+ inst.getOpcode().toString() + " in " + eMethod.getDefiningClass() + ":" + eMethod.getName());
}
currentCodeAddress += inst.getCodeUnits();

View File

@ -59,9 +59,11 @@ public class DexModuleEntry implements ModuleEntry {
private final ClassDef classDefItem;
private final String className;
public DexModuleEntry(ClassDef cdefitems) {
private final DexFileModule container;
public DexModuleEntry(ClassDef cdefitems, DexFileModule container) {
classDefItem = cdefitems;
this.container = container;
String temp =cdefitems.getType();
// className = temp;
if (temp.endsWith(";"))
@ -139,8 +141,8 @@ public class DexModuleEntry implements ModuleEntry {
}
@Override
public Module getContainer() {
return asModule();
public DexFileModule getContainer() {
return container;
}
@Override