com.android.dex.Dex Java Examples

The following examples show how to use com.android.dex.Dex. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source Project: Box   Author: lulululbj   File: ClassNode.java    License: Apache License 2.0 6 votes vote down vote up
private void loadStaticValues(ClassDef cls, List<FieldNode> staticFields) throws DecodeException {
	for (FieldNode f : staticFields) {
		if (f.getAccessFlags().isFinal()) {
			f.addAttr(FieldInitAttr.NULL_VALUE);
		}
	}
	int offset = cls.getStaticValuesOffset();
	if (offset == 0) {
		return;
	}
	Dex.Section section = dex.openSection(offset);
	StaticValuesParser parser = new StaticValuesParser(dex, section);
	parser.processFields(staticFields);

	// process const fields
	root().getConstValues().processConstFields(this, staticFields);
}
 
Example #2
Source Project: bazel   Author: bazelbuild   File: DexFileAggregatorTest.java    License: Apache License 2.0 6 votes vote down vote up
@Test
public void testMonodex_alwaysWritesSingleShard() throws Exception {
  DexFileAggregator dexer =
      new DexFileAggregator(
          new DxContext(),
          dest,
          newDirectExecutorService(),
          MultidexStrategy.OFF,
          /*forceJumbo=*/ false,
          2 /* dex has more than 2 methods and fields */,
          WASTE,
          DexFileMergerTest.DEX_PREFIX);
  Dex dex2 = DexFiles.toDex(convertClass(ByteStreams.class));
  dexer.add(dex);
  dexer.add(dex2);
  verify(dest, times(0)).addFile(any(ZipEntry.class), any(Dex.class));
  dexer.close();
  verify(dest).addFile(any(ZipEntry.class), written.capture());
  assertThat(Iterables.size(written.getValue().classDefs())).isEqualTo(2);
}
 
Example #3
Source Project: buck   Author: facebook   File: DexMerger.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Reads a class_def_item beginning at {@code in} and writes the index and
 * data.
 */
private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap) {
    idsDefsOut.assertFourByteAligned();
    idsDefsOut.writeInt(classDef.getTypeIndex());
    idsDefsOut.writeInt(classDef.getAccessFlags());
    idsDefsOut.writeInt(classDef.getSupertypeIndex());
    idsDefsOut.writeInt(classDef.getInterfacesOffset());

    int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());
    idsDefsOut.writeInt(sourceFileIndex);

    int annotationsOff = classDef.getAnnotationsOffset();
    idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));

    int classDataOff = classDef.getClassDataOffset();
    if (classDataOff == 0) {
        idsDefsOut.writeInt(0);
    } else {
        idsDefsOut.writeInt(classDataOut.getPosition());
        ClassData classData = in.readClassData(classDef);
        transformClassData(in, classData, indexMap);
    }

    int staticValuesOff = classDef.getStaticValuesOffset();
    idsDefsOut.writeInt(indexMap.adjustStaticValues(staticValuesOff));
}
 
Example #4
Source Project: buck   Author: facebook   File: FindUsages.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Returns the set of types that can be assigned to {@code typeIndex}.
 */
private Set<Integer> findAssignableTypes(Dex dex, int typeIndex) {
    Set<Integer> assignableTypes = new HashSet<Integer>();
    assignableTypes.add(typeIndex);

    for (ClassDef classDef : dex.classDefs()) {
        if (assignableTypes.contains(classDef.getSupertypeIndex())) {
            assignableTypes.add(classDef.getTypeIndex());
            continue;
        }

        for (int implemented : classDef.getInterfaces()) {
            if (assignableTypes.contains(implemented)) {
                assignableTypes.add(classDef.getTypeIndex());
                break;
            }
        }
    }

    return assignableTypes;
}
 
Example #5
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 6 votes vote down vote up
private void transformClassData(Dex in, ClassData classData, IndexMap indexMap) {
    contentsOut.classDatas.size++;

    ClassData.Field[] staticFields = classData.getStaticFields();
    ClassData.Field[] instanceFields = classData.getInstanceFields();
    ClassData.Method[] directMethods = classData.getDirectMethods();
    ClassData.Method[] virtualMethods = classData.getVirtualMethods();

    classDataOut.writeUleb128(staticFields.length);
    classDataOut.writeUleb128(instanceFields.length);
    classDataOut.writeUleb128(directMethods.length);
    classDataOut.writeUleb128(virtualMethods.length);

    transformFields(indexMap, staticFields);
    transformFields(indexMap, instanceFields);
    transformMethods(in, indexMap, directMethods);
    transformMethods(in, indexMap, virtualMethods);
}
 
Example #6
Source Project: buck   Author: facebook   File: Main.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Merges the dex files in library jars. If multiple dex files define the
 * same type, this fails with an exception.
 */
private byte[] mergeLibraryDexBuffers(byte[] outArray) throws IOException {
    ArrayList<Dex> dexes = new ArrayList<Dex>();
    if (outArray != null) {
        dexes.add(new Dex(outArray));
    }
    for (byte[] libraryDex : libraryDexBuffers) {
        dexes.add(new Dex(libraryDex));
    }
    if (dexes.isEmpty()) {
        return null;
    }
    DexMerger dexMerger = new DexMerger(
        dexes.toArray(new Dex[0]),
        CollisionPolicy.FAIL,
        context);
    Dex merged = dexMerger.merge();
    return merged.getBytes();
}
 
Example #7
Source Project: buck   Author: facebook   File: MergeTest.java    License: Apache License 2.0 6 votes vote down vote up
public static void main(String[] args) throws Throwable {

    for (int i = 0; i < NUMBER_OF_TRIES; i++) {
      String fileName1 = args[(int) (Math.random() * args.length)];
      String fileName2 = args[(int) (Math.random() * args.length)];
      try {
        Dex toMerge = new Dex(new File(fileName1));
        Dex toMerge2 = new Dex(new File(fileName2));
        new DexMerger(toMerge, toMerge2, CollisionPolicy.KEEP_FIRST).merge();
      } catch (DexIndexOverflowException e) {
        // ignore index overflow
      } catch (Throwable t) {
        System.err.println(
            "Problem merging those 2 dexes: \"" + fileName1 + "\" and \"" + fileName2 + "\"");
        throw t;
      }
    }
  }
 
Example #8
Source Project: buck   Author: facebook   File: DexMergeTest.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Merging dex files uses pessimistic sizes that naturally leave gaps in the
 * output files. If those gaps grow too large, the merger is supposed to
 * compact the result. This exercises that by repeatedly merging a dex with
 * itself.
 */
public void testMergedOutputSizeIsBounded() throws Exception {
    /*
     * At the time this test was written, the output would grow ~25% with
     * each merge. Setting a low 1KiB ceiling on the maximum size caused
     * the file to be compacted every four merges.
     */
    int steps = 100;
    int compactWasteThreshold = 1024;

    Dex dexA = resourceToDexBuffer("/testdata/Basic.dex");
    Dex dexB = resourceToDexBuffer("/testdata/TryCatchFinally.dex");
    Dex merged = new DexMerger(dexA, dexB, CollisionPolicy.KEEP_FIRST).merge();

    int maxLength = 0;
    for (int i = 0; i < steps; i++) {
        DexMerger dexMerger = new DexMerger(dexA, merged, CollisionPolicy.KEEP_FIRST);
        dexMerger.setCompactWasteThreshold(compactWasteThreshold);
        merged = dexMerger.merge();
        maxLength = Math.max(maxLength, merged.getLength());
    }

    int maxExpectedLength = dexA.getLength() + dexB.getLength() + compactWasteThreshold;
    assertTrue(maxLength + " < " + maxExpectedLength, maxLength < maxExpectedLength);
}
 
Example #9
Source Project: buck   Author: facebook   File: DexMerger.java    License: Apache License 2.0 6 votes vote down vote up
private void transformMethods(Dex in, IndexMap indexMap, ClassData.Method[] methods) {
    int lastOutMethodIndex = 0;
    for (ClassData.Method method : methods) {
        int outMethodIndex = indexMap.adjustMethod(method.getMethodIndex());
        classDataOut.writeUleb128(outMethodIndex - lastOutMethodIndex);
        lastOutMethodIndex = outMethodIndex;

        classDataOut.writeUleb128(method.getAccessFlags());

        if (method.getCodeOffset() == 0) {
            classDataOut.writeUleb128(0);
        } else {
            codeOut.alignToFourBytesWithZeroFill();
            classDataOut.writeUleb128(codeOut.getPosition());
            transformCode(in, in.readCode(method), indexMap);
        }
    }
}
 
Example #10
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * Reads a class_def_item beginning at {@code in} and writes the index and
 * data.
 */
private void transformClassDef(Dex in, ClassDef classDef, IndexMap indexMap) {
    idsDefsOut.assertFourByteAligned();
    idsDefsOut.writeInt(classDef.getTypeIndex());
    idsDefsOut.writeInt(classDef.getAccessFlags());
    idsDefsOut.writeInt(classDef.getSupertypeIndex());
    idsDefsOut.writeInt(classDef.getInterfacesOffset());

    int sourceFileIndex = indexMap.adjustString(classDef.getSourceFileIndex());
    idsDefsOut.writeInt(sourceFileIndex);

    int annotationsOff = classDef.getAnnotationsOffset();
    idsDefsOut.writeInt(indexMap.adjustAnnotationDirectory(annotationsOff));

    int classDataOff = classDef.getClassDataOffset();
    if (classDataOff == 0) {
        idsDefsOut.writeInt(0);
    } else {
        idsDefsOut.writeInt(classDataOut.getPosition());
        ClassData classData = in.readClassData(classDef);
        transformClassData(in, classData, indexMap);
    }

    int staticValuesOff = classDef.getStaticValuesOffset();
    idsDefsOut.writeInt(indexMap.adjustEncodedArray(staticValuesOff));
}
 
Example #11
Source Project: rhino-android   Author: F43nd1r   File: BaseAndroidClassLoader.java    License: Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public Class<?> defineClass(String name, byte[] data) {
    try {
        DexOptions dexOptions = new DexOptions();
        DexFile dexFile = new DexFile(dexOptions);
        DirectClassFile classFile = new DirectClassFile(data, name.replace('.', '/') + ".class", true);
        classFile.setAttributeFactory(StdAttributeFactory.THE_ONE);
        classFile.getMagic();
        DxContext context = new DxContext();
        dexFile.add(CfTranslator.translate(context, classFile, null, new CfOptions(), dexOptions, dexFile));
        Dex dex = new Dex(dexFile.toDex(null, false));
        Dex oldDex = getLastDex();
        if (oldDex != null) {
            dex = new DexMerger(new Dex[]{dex, oldDex}, CollisionPolicy.KEEP_FIRST, context).merge();
        }
        return loadClass(dex, name);
    } catch (IOException | ClassNotFoundException e) {
        throw new FatalLoadingException(e);
    }
}
 
Example #12
Source Project: Box   Author: lulululbj   File: Grep.java    License: Apache License 2.0 5 votes vote down vote up
private Set<Integer> getStringIds(Dex dex, Pattern pattern) {
    Set<Integer> stringIds = new HashSet<Integer>();
    int stringIndex = 0;
    for (String s : dex.strings()) {
        if (pattern.matcher(s).find()) {
            stringIds.add(stringIndex);
        }
        stringIndex++;
    }
    return stringIds;
}
 
Example #13
Source Project: Box   Author: lulululbj   File: InputFile.java    License: Apache License 2.0 5 votes vote down vote up
private boolean addDexFile(String entryName, @Nullable Path filePath) {
	if (filePath == null) {
		return false;
	}
	Dex dexBuf = loadDexBufFromPath(filePath, entryName);
	if (dexBuf == null) {
		return false;
	}
	dexFiles.add(new DexFile(this, entryName, dexBuf, filePath));
	return true;
}
 
Example #14
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
private Dex mergeDexes() throws IOException {
    mergeStringIds();
    mergeTypeIds();
    mergeTypeLists();
    mergeProtoIds();
    mergeFieldIds();
    mergeMethodIds();
    mergeMethodHandles();
    mergeAnnotations();
    unionAnnotationSetsAndDirectories();
    mergeCallSiteIds();
    mergeClassDefs();

    // computeSizesFromOffsets expects sections sorted by offset, so make it so
    Arrays.sort(contentsOut.sections);

    // write the header
    contentsOut.header.off = 0;
    contentsOut.header.size = 1;
    contentsOut.fileSize = dexOut.getLength();
    contentsOut.computeSizesFromOffsets();
    contentsOut.writeHeader(headerOut, mergeApiLevels());
    contentsOut.writeMap(mapListOut);

    // generate and write the hashes
    dexOut.writeHashes();

    return dexOut;
}
 
Example #15
Source Project: atlas   Author: alibaba   File: DexArchiveMergerHook.java    License: Apache License 2.0 5 votes vote down vote up
private void mergeMonoDex(@NonNull Collection<Path> inputs, @NonNull Path output)
        throws IOException {
    Map<Path, List<Dex>> dexesFromArchives = Maps.newConcurrentMap();
    // counts how many inputs are yet to be processed
    AtomicInteger inputsToProcess = new AtomicInteger(inputs.size());
    ArrayList<ForkJoinTask<Void>> subTasks = new ArrayList<>();
    for (Path archivePath : inputs) {
        subTasks.add(
                forkJoinPool.submit(
                        () -> {
                            try (DexArchive dexArchive = DexArchives.fromInput(archivePath)) {
                                List<DexArchiveEntry> entries = dexArchive.getFiles();
                                List<Dex> dexes = new ArrayList<>(entries.size());
                                for (DexArchiveEntry e : entries) {
                                    dexes.add(new Dex(e.getDexFileContent()));
                                }

                                dexesFromArchives.put(dexArchive.getRootPath(), dexes);
                            }

                            if (inputsToProcess.decrementAndGet() == 0) {
                                mergeMonoDexEntries(output, dexesFromArchives).join();
                            }
                            return null;
                        }));
    }
    // now wait for all subtasks execution.
    subTasks.forEach(ForkJoinTask::join);
}
 
Example #16
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
private int readIntoMap(Dex.Section in, TableOfContents.Section section, IndexMap indexMap,
                        int index, TreeMap<T, List<Integer>> values, int dex) {
    int offset = in != null ? in.getPosition() : -1;
    if (index < section.size) {
        T v = read(in, indexMap, index);
        List<Integer> l = values.get(v);
        if (l == null) {
            l = new ArrayList<Integer>();
            values.put(v, l);
        }
        l.add(dex);
    }
    return offset;
}
 
Example #17
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
UnsortedValue(Dex source, IndexMap indexMap, T value, int index, int offset) {
    this.source = source;
    this.indexMap = indexMap;
    this.value = value;
    this.index = index;
    this.offset = offset;
}
 
Example #18
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * 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, indexMap, 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()));
        }
    }
}
 
Example #19
Source Project: buck   Author: facebook   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * 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, indexMap, 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()));
        }
    }
}
 
Example #20
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
private void transformStaticValues(Dex in, IndexMap indexMap) {
    TableOfContents.Section section = in.getTableOfContents().encodedArrays;
    if (section.exists()) {
        Dex.Section staticValuesIn = in.open(section.off);
        for (int i = 0; i < section.size; i++) {
            transformStaticValues(staticValuesIn, indexMap);
        }
    }
}
 
Example #21
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Transform all annotation set ref lists.
 */
private void transformAnnotationSetRefList(IndexMap indexMap, Dex.Section refListIn) {
    contentsOut.annotationSetRefLists.size++;
    annotationSetRefListOut.assertFourByteAligned();
    indexMap.putAnnotationSetRefListOffset(
            refListIn.getPosition(), annotationSetRefListOut.getPosition());

    int parameterCount = refListIn.readInt();
    annotationSetRefListOut.writeInt(parameterCount);
    for (int p = 0; p < parameterCount; p++) {
        annotationSetRefListOut.writeInt(indexMap.adjustAnnotationSet(refListIn.readInt()));
    }
}
 
Example #22
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
private void transformTries(Dex.Section out, Code.Try[] tries,
        int[] catchHandlerOffsets) {
    for (Code.Try tryItem : tries) {
        out.writeInt(tryItem.getStartAddress());
        out.writeUnsignedShort(tryItem.getInstructionCount());
        out.writeUnsignedShort(catchHandlerOffsets[tryItem.getCatchHandlerIndex()]);
    }
}
 
Example #23
Source Project: buck   Author: facebook   File: Grep.java    License: Apache License 2.0 5 votes vote down vote up
public Grep(final Dex dex, Pattern pattern, final PrintWriter out) {
    this.dex = dex;
    this.out = out;

    stringIds = getStringIds(dex, pattern);

    codeReader.setStringVisitor(new CodeReader.Visitor() {
        public void visit(DecodedInstruction[] all, DecodedInstruction one) {
            encounterString(one.getIndex());
        }
    });
}
 
Example #24
Source Project: Box   Author: lulululbj   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) throws IOException {
    if (args.length < 2) {
        printUsage();
        return;
    }

    Dex[] dexes = new Dex[args.length - 1];
    for (int i = 1; i < args.length; i++) {
        dexes[i - 1] = new Dex(new File(args[i]));
    }
    Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST, new DxContext()).merge();
    merged.writeTo(new File(args[0]));
}
 
Example #25
Source Project: buck   Author: facebook   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
private void transformStaticValues(Dex in, IndexMap indexMap) {
    TableOfContents.Section section = in.getTableOfContents().encodedArrays;
    if (section.exists()) {
        Dex.Section staticValuesIn = in.open(section.off);
        for (int i = 0; i < section.size; i++) {
            transformStaticValues(staticValuesIn, indexMap);
        }
    }
}
 
Example #26
Source Project: buck   Author: facebook   File: DexMerger.java    License: Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) throws IOException {
    if (args.length < 2) {
        printUsage();
        return;
    }

    Dex[] dexes = new Dex[args.length - 1];
    for (int i = 1; i < args.length; i++) {
        dexes[i - 1] = new Dex(new File(args[i]));
    }
    Dex merged = new DexMerger(dexes, CollisionPolicy.KEEP_FIRST, new DxContext()).merge();
    merged.writeTo(new File(args[0]));
}
 
Example #27
Source Project: Box   Author: lulululbj   File: Main.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Merges the dex files in library jars. If multiple dex files define the
 * same type, this fails with an exception.
 */
private byte[] mergeLibraryDexBuffers(byte[] outArray) throws IOException {
    ArrayList<Dex> dexes = new ArrayList<Dex>();
    if (outArray != null) {
        dexes.add(new Dex(outArray));
    }
    for (byte[] libraryDex : libraryDexBuffers) {
        dexes.add(new Dex(libraryDex));
    }
    if (dexes.isEmpty()) {
        return null;
    }
    Dex merged = new DexMerger(dexes.toArray(new Dex[dexes.size()]), CollisionPolicy.FAIL, context).merge();
    return merged.getBytes();
}
 
Example #28
Source Project: bazel   Author: bazelbuild   File: DexFileAggregatorTest.java    License: Apache License 2.0 5 votes vote down vote up
@Test
public void testClose_emptyWritesNothing() throws Exception {
  DexFileAggregator dexer =
      new DexFileAggregator(
          new DxContext(),
          dest,
          newDirectExecutorService(),
          MultidexStrategy.MINIMAL,
          /*forceJumbo=*/ false,
          DEX_LIMIT,
          WASTE,
          DexFileMergerTest.DEX_PREFIX);
  dexer.close();
  verify(dest, times(0)).addFile(any(ZipEntry.class), any(Dex.class));
}
 
Example #29
Source Project: Box   Author: lulululbj   File: FindUsages.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Returns the fields with {@code memberNameIndex} declared by {@code
 * declaringType}.
 */
private Set<Integer> getFieldIds(Dex dex, Set<Integer> memberNameIndexes, int declaringType) {
    Set<Integer> fields = new HashSet<Integer>();
    int fieldIndex = 0;
    for (FieldId fieldId : dex.fieldIds()) {
        if (memberNameIndexes.contains(fieldId.getNameIndex())
                && declaringType == fieldId.getDeclaringClassIndex()) {
            fields.add(fieldIndex);
        }
        fieldIndex++;
    }
    return fields;
}
 
Example #30
Source Project: Box   Author: lulululbj   File: FindUsages.java    License: Apache License 2.0 5 votes vote down vote up
/**
 * Returns the methods with {@code memberNameIndex} declared by {@code
 * declaringType} and its subtypes.
 */
private Set<Integer> getMethodIds(Dex dex, Set<Integer> memberNameIndexes, int declaringType) {
    Set<Integer> subtypes = findAssignableTypes(dex, declaringType);

    Set<Integer> methods = new HashSet<Integer>();
    int methodIndex = 0;
    for (MethodId method : dex.methodIds()) {
        if (memberNameIndexes.contains(method.getNameIndex())
                && subtypes.contains(method.getDeclaringClassIndex())) {
            methods.add(methodIndex);
        }
        methodIndex++;
    }
    return methods;
}