@Nullable private Dex makeDexBuf(String entryName, InputStream inputStream) { try { return new Dex(inputStream); } catch (Exception e) { LOG.error("Failed to load file: {}, error: {}", entryName, e.getMessage(), e); return null; } }
public Section openSection(int offset) { return dexBuf.open(offset); }
public ProtoId getProtoId(int protoIndex) { return dexBuf.protoIds().get(protoIndex); }
for (ClassDef classDef : dex.classDefs()) { currentClass = classDef; currentMethod = null; ClassData classData = dex.readClassData(classDef); for (ClassData.Field field : classData.allFields()) { int fieldIndex = field.getFieldIndex(); if (fieldIds.contains(fieldIndex)) { out.println(location() + " field declared " + dex.fieldIds().get(fieldIndex)); int methodIndex = method.getMethodIndex(); if (methodIds.contains(methodIndex)) { out.println(location() + " method declared " + dex.methodIds().get(methodIndex)); codeReader.visitAll(dex.readCode(method).getInstructions());
@Override public String toString() { if (dex == null) { return declaringClassIndex + " " + protoIndex + " " + nameIndex; } return dex.typeNames().get(declaringClassIndex) + "." + dex.strings().get(nameIndex) + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset()); } }
/** * Prints usages to out. Returns the number of matches found. */ public int grep() { for (ClassDef classDef : dex.classDefs()) { currentClass = classDef; currentMethod = null; if (classDef.getClassDataOffset() == 0) { continue; } ClassData classData = dex.readClassData(classDef); // find the strings in encoded constants int staticValuesOffset = classDef.getStaticValuesOffset(); if (staticValuesOffset != 0) { readArray(new EncodedValueReader(dex.open(staticValuesOffset))); } // find the strings in method bodies for (ClassData.Method method : classData.allMethods()) { currentMethod = method; if (method.getCodeOffset() != 0) { codeReader.visitAll(dex.readCode(method).getInstructions()); } } } currentClass = null; currentMethod = null; return count; }
public static void main(String[] args) throws IOException { if (args.length < 2) { printUsage(); return; } Dex merged = new Dex(new File(args[1])); for (int i = 2; i < args.length; i++) { Dex toMerge = new Dex(new File(args[i])); merged = new DexMerger(merged, toMerge, CollisionPolicy.KEEP_FIRST).merge(); } merged.writeTo(new File(args[0])); }
if (wastedByteCount > + compactWasteThreshold) { DexMerger compacter = new DexMerger( dexOut, new Dex(0), CollisionPolicy.FAIL, compactedSizes); result = compacter.mergeDexes(); System.out.printf("Result compacted from %.1fKiB to %.1fKiB to save %.1fKiB%n", dexOut.getLength() / 1024f, result.getLength() / 1024f, wastedByteCount / 1024f); System.out.printf("Merged dex A (%d defs/%.1fKiB) with dex B " + "(%d defs/%.1fKiB). Result is %d defs/%.1fKiB. Took %.1fs%n", dexA.getTableOfContents().classDefs.size, dexA.getLength() / 1024f, dexB.getTableOfContents().classDefs.size, dexB.getLength() / 1024f, result.getTableOfContents().classDefs.size, result.getLength() / 1024f, elapsed / 1000000000f);
@Override public String toString() { if (dex == null) { return shortyIndex + " " + returnTypeIndex + " " + parametersOffset; } return dex.strings().get(shortyIndex) + ": " + dex.typeNames().get(returnTypeIndex) + " " + dex.readTypeList(parametersOffset); } }
private void transformAnnotationDirectories(Dex in, IndexMap indexMap) { TableOfContents.Section section = in.getTableOfContents().annotationsDirectories; if (section.exists()) { Dex.Section directoryIn = in.open(section.off); for (int i = 0; i < section.size; i++) { transformAnnotationDirectory(directoryIn, indexMap); } } }
/** * Reads just enough data on each class so that we can sort it and then find * it later. */ private void readSortableTypes(SortableType[] sortableTypes, Dex buffer, IndexMap indexMap) { for (ClassDef classDef : buffer.classDefs()) { SortableType sortableType = indexMap.adjust(new SortableType(buffer, classDef)); int t = sortableType.getTypeIndex(); if (sortableTypes[t] == null) { sortableTypes[t] = sortableType; } else if (collisionPolicy != CollisionPolicy.KEEP_FIRST) { throw new DexException("Multiple dex files define " + buffer.typeNames().get(classDef.getTypeIndex())); } } }
public FieldId getFieldId(int fieldIndex) { return dexBuf.fieldIds().get(fieldIndex); }
private Dex mergeDexes() throws IOException { mergeStringIds(); mergeTypeIds(); mergeTypeLists(); mergeProtoIds(); mergeFieldIds(); mergeMethodIds(); mergeAnnotations(); unionAnnotationSetsAndDirectories(); mergeClassDefs(); // write the header contentsOut.header.off = 0; contentsOut.header.size = 1; contentsOut.fileSize = dexOut.getLength(); contentsOut.computeSizesFromOffsets(); contentsOut.writeHeader(headerOut); contentsOut.writeMap(mapListOut); // generate and write the hashes dexOut.writeHashes(); return dexOut; }
public DexIndexPrinter(File file) throws IOException { this.dex = new Dex(file); this.tableOfContents = dex.getTableOfContents(); }
/** * Generates the signature and checksum of the dex file {@code out} and * writes them to the file. */ public void writeHashes() throws IOException { open(SIGNATURE_OFFSET).write(computeSignature()); open(CHECKSUM_OFFSET).writeInt(computeChecksum()); }
public void loadClasses() { for (ClassDef cls : dexBuf.classDefs()) { addClassNode(new ClassNode(this, cls)); } }
public MethodId getMethodId(int mthIndex) { return dexBuf.methodIds().get(mthIndex); }