use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project android-classyshark by google.
the class DexInfoTranslator method apply.
@Override
public void apply() {
try {
elements.clear();
File classesDex = extractClassesDex(dexFileName, apkFile, this);
DexFile dxFile = DexlibLoader.loadDexFile(classesDex);
DexBackedDexFile dataPack = (DexBackedDexFile) dxFile;
ELEMENT element = new ELEMENT("\nclasses: " + dataPack.getClassCount(), TAG.MODIFIER);
elements.add(element);
element = new ELEMENT("\nstrings: " + dataPack.getStringCount(), TAG.DOCUMENT);
elements.add(element);
element = new ELEMENT("\ntypes: " + dataPack.getTypeCount(), TAG.DOCUMENT);
elements.add(element);
element = new ELEMENT("\nprotos: " + dataPack.getProtoCount(), TAG.DOCUMENT);
elements.add(element);
element = new ELEMENT("\nfields: " + dataPack.getFieldCount(), TAG.DOCUMENT);
elements.add(element);
element = new ELEMENT("\nmethods: " + dataPack.getMethodCount(), TAG.IDENTIFIER);
elements.add(element);
element = new ELEMENT("\n\nFile size: " + JarInfoTranslator.readableFileSize(classesDex.length()), TAG.DOCUMENT);
elements.add(element);
element = new ELEMENT("\n\nClasses with Native Calls\n", TAG.MODIFIER);
elements.add(element);
Set<String> classesWithNativeMethods = getClassesWithNativeMethodsPerDexIndex(index, classesDex);
for (String classWithNativeMethods : classesWithNativeMethods) {
element = new ELEMENT(classWithNativeMethods + "\n", TAG.DOCUMENT);
elements.add(element);
}
} catch (Exception e) {
e.printStackTrace();
}
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project tinker by Tencent.
the class DexDiffDecoder method generateChangedClassesDexFile.
@SuppressWarnings("NewApi")
private void generateChangedClassesDexFile() throws IOException {
final String dexMode = config.mDexRaw ? "raw" : "jar";
List<File> oldDexList = new ArrayList<>();
List<File> newDexList = new ArrayList<>();
for (AbstractMap.SimpleEntry<File, File> oldAndNewDexFilePair : oldAndNewDexFilePairList) {
File oldDexFile = oldAndNewDexFilePair.getKey();
File newDexFile = oldAndNewDexFilePair.getValue();
if (oldDexFile != null) {
oldDexList.add(oldDexFile);
}
if (newDexFile != null) {
newDexList.add(newDexFile);
}
}
DexGroup oldDexGroup = DexGroup.wrap(oldDexList);
DexGroup newDexGroup = DexGroup.wrap(newDexList);
ChangedClassesDexClassInfoCollector collector = new ChangedClassesDexClassInfoCollector();
collector.setExcludedClassPatterns(config.mDexLoaderPattern);
collector.setLogger(dexPatcherLoggerBridge);
collector.setIncludeRefererToRefererAffectedClasses(true);
Set<DexClassInfo> classInfosInChangedClassesDex = collector.doCollect(oldDexGroup, newDexGroup);
Set<Dex> owners = new HashSet<>();
Map<Dex, Set<String>> ownerToDescOfChangedClassesMap = new HashMap<>();
for (DexClassInfo classInfo : classInfosInChangedClassesDex) {
owners.add(classInfo.owner);
Set<String> descOfChangedClasses = ownerToDescOfChangedClassesMap.get(classInfo.owner);
if (descOfChangedClasses == null) {
descOfChangedClasses = new HashSet<>();
ownerToDescOfChangedClassesMap.put(classInfo.owner, descOfChangedClasses);
}
descOfChangedClasses.add(classInfo.classDesc);
}
StringBuilder metaBuilder = new StringBuilder();
int changedDexId = 1;
for (Dex dex : owners) {
Set<String> descOfChangedClassesInCurrDex = ownerToDescOfChangedClassesMap.get(dex);
DexFile dexFile = new DexBackedDexFile(org.jf.dexlib2.Opcodes.forApi(20), dex.getBytes());
boolean isCurrentDexHasChangedClass = false;
for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
if (descOfChangedClassesInCurrDex.contains(classDef.getType())) {
isCurrentDexHasChangedClass = true;
break;
}
}
if (!isCurrentDexHasChangedClass) {
continue;
}
DexBuilder dexBuilder = new DexBuilder(Opcodes.forApi(23));
for (org.jf.dexlib2.iface.ClassDef classDef : dexFile.getClasses()) {
if (!descOfChangedClassesInCurrDex.contains(classDef.getType())) {
continue;
}
Logger.d("Class %s will be added into changed classes dex ...", classDef.getType());
List<BuilderField> builderFields = new ArrayList<>();
for (Field field : classDef.getFields()) {
final BuilderField builderField = dexBuilder.internField(field.getDefiningClass(), field.getName(), field.getType(), field.getAccessFlags(), field.getInitialValue(), field.getAnnotations());
builderFields.add(builderField);
}
List<BuilderMethod> builderMethods = new ArrayList<>();
for (Method method : classDef.getMethods()) {
MethodImplementation methodImpl = method.getImplementation();
if (methodImpl != null) {
methodImpl = new BuilderMutableMethodImplementation(dexBuilder, methodImpl);
}
BuilderMethod builderMethod = dexBuilder.internMethod(method.getDefiningClass(), method.getName(), method.getParameters(), method.getReturnType(), method.getAccessFlags(), method.getAnnotations(), methodImpl);
builderMethods.add(builderMethod);
}
dexBuilder.internClassDef(classDef.getType(), classDef.getAccessFlags(), classDef.getSuperclass(), classDef.getInterfaces(), classDef.getSourceFile(), classDef.getAnnotations(), builderFields, builderMethods);
}
// Write constructed changed classes dex to file and record it in meta file.
String changedDexName = null;
if (changedDexId == 1) {
changedDexName = "classes.dex";
} else {
changedDexName = "classes" + changedDexId + ".dex";
}
final File dest = new File(config.mTempResultDir + "/" + changedDexName);
final FileDataStore fileDataStore = new FileDataStore(dest);
dexBuilder.writeTo(fileDataStore);
final String md5 = MD5.getMD5(dest);
appendMetaLine(metaBuilder, changedDexName, "", md5, md5, 0, 0, 0, dexMode);
++changedDexId;
}
final String meta = metaBuilder.toString();
Logger.d("\nDexDecoder:write changed classes dex meta file data:\n%s", meta);
metaWriter.writeLineToInfoFile(meta);
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project dex2jar by pxb1988.
the class SmaliTest method dotest.
private void dotest(File dexFile) throws IOException {
DexBackedDexFile dex;
try {
dex = DexFileFactory.loadDexFile(dexFile, 14, false);
} catch (DexBackedDexFile.NotADexFile ex) {
ex.printStackTrace();
return;
}
Map<String, DexClassNode> map = readDex(dexFile);
for (DexBackedClassDef def : dex.getClasses()) {
String type = def.getType();
System.out.println(type);
DexClassNode dexClassNode = map.get(type);
Assert.assertNotNull(dexClassNode);
// original
String smali = baksmali(def);
Smali.smaliFile2Node("fake.smali", smali);
{
byte[] data = toDex(dexClassNode);
DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();
// original
String baksmali3 = baksmali(def2);
Assert.assertEquals(smali, baksmali3);
}
String psmali = pbaksmali(dexClassNode);
DexClassNode dexClassNode2 = Smali.smaliFile2Node("fake.smali", psmali);
Assert.assertEquals("cmp smalip", psmali, pbaksmali(dexClassNode2));
{
byte[] data = toDex(dexClassNode2);
DexBackedClassDef def2 = new DexBackedDexFile(new Opcodes(14, false), data).getClasses().iterator().next();
// original
String baksmali3 = baksmali(def2);
Assert.assertEquals(smali, baksmali3);
}
}
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class DexFileFactory method loadDexContainer.
/**
* Loads a file containing 1 or more dex files
*
* If the given file is a dex or odex file, it will return a MultiDexContainer containing that single entry.
* Otherwise, for an oat or zip file, it will return an OatFile or ZipDexContainer respectively.
*
* @param file The file to open
* @param opcodes The set of opcodes to use
* @return A MultiDexContainer
* @throws DexFileNotFoundException If the given file does not exist
* @throws UnsupportedFileTypeException If the given file is not a valid dex/zip/odex/oat file
*/
public static MultiDexContainer<? extends DexBackedDexFile> loadDexContainer(@Nonnull File file, @Nullable final Opcodes opcodes) throws IOException {
if (!file.exists()) {
throw new DexFileNotFoundException("%s does not exist", file.getName());
}
ZipDexContainer zipDexContainer = new ZipDexContainer(file, opcodes);
if (zipDexContainer.isZipFile()) {
return zipDexContainer;
}
InputStream inputStream = new BufferedInputStream(new FileInputStream(file));
try {
try {
DexBackedDexFile dexFile = DexBackedDexFile.fromInputStream(opcodes, inputStream);
return new SingletonMultiDexContainer(file.getPath(), dexFile);
} catch (DexBackedDexFile.NotADexFile ex) {
// just eat it
}
try {
DexBackedOdexFile odexFile = DexBackedOdexFile.fromInputStream(opcodes, inputStream);
return new SingletonMultiDexContainer(file.getPath(), odexFile);
} catch (DexBackedOdexFile.NotAnOdexFile ex) {
// just eat it
}
// Note: DexBackedDexFile.fromInputStream and DexBackedOdexFile.fromInputStream will reset inputStream
// back to the same position, if they fails
OatFile oatFile = null;
try {
oatFile = OatFile.fromInputStream(inputStream, new FilenameVdexProvider(file));
} catch (NotAnOatFileException ex) {
// just eat it
}
if (oatFile != null) {
// TODO: we should support loading earlier oat files, just not deodexing them
if (oatFile.isSupportedVersion() == OatFile.UNSUPPORTED) {
throw new UnsupportedOatVersionException(oatFile);
}
return oatFile;
}
} finally {
inputStream.close();
}
throw new UnsupportedFileTypeException("%s is not an apk, dex, odex or oat file.", file.getPath());
}
use of org.jf.dexlib2.dexbacked.DexBackedDexFile in project smali by JesusFreke.
the class DexWriterTest method testAnnotationElementOrder.
@Test
public void testAnnotationElementOrder() {
// Elements are out of order wrt to the element name
ImmutableSet<ImmutableAnnotationElement> elements = ImmutableSet.of(new ImmutableAnnotationElement("zabaglione", ImmutableNullEncodedValue.INSTANCE), new ImmutableAnnotationElement("blah", ImmutableNullEncodedValue.INSTANCE));
ImmutableAnnotation annotation = new ImmutableAnnotation(AnnotationVisibility.RUNTIME, "Lorg/test/anno;", elements);
ImmutableClassDef classDef = new ImmutableClassDef("Lorg/test/blah;", 0, "Ljava/lang/Object;", null, null, ImmutableSet.of(annotation), null, null);
MemoryDataStore dataStore = new MemoryDataStore();
try {
DexPool.writeTo(dataStore, new ImmutableDexFile(Opcodes.getDefault(), ImmutableSet.of(classDef)));
} catch (IOException ex) {
throw new RuntimeException(ex);
}
DexBackedDexFile dexFile = new DexBackedDexFile(Opcodes.getDefault(), dataStore.getBuffer());
ClassDef dbClassDef = Iterables.getFirst(dexFile.getClasses(), null);
Assert.assertNotNull(dbClassDef);
Annotation dbAnnotation = Iterables.getFirst(dbClassDef.getAnnotations(), null);
Assert.assertNotNull(dbAnnotation);
List<AnnotationElement> dbElements = Lists.newArrayList(dbAnnotation.getElements());
// Ensure that the elements were written out in sorted order
Assert.assertEquals(2, dbElements.size());
Assert.assertEquals("blah", dbElements.get(0).getName());
Assert.assertEquals("zabaglione", dbElements.get(1).getName());
}
Aggregations