/** * Writes a DexFile out to disk * * @param path The path to write the dex file to * @param dexFile a DexFile to write */ public static void writeDexFile(@Nonnull String path, @Nonnull DexFile dexFile) throws IOException { DexPool.writeTo(path, dexFile); }
protected void newDexPool() { curPool = new DexPool(opcodes); dexPools.add(curPool); }
public void internClass(final ClassDef clz) { curPool.mark(); curPool.internClass(clz); if (hasOverflowed()) { // reset to state before overflow occurred curPool.reset(); // we need a new dexpool newDexPool(); // re-execute on new pool since the last execution was dropped // NOTE: We do not want to call internClass recursively here, this // might end in an endless loop // if the class is to large for a single dex file! curPool.internClass(clz); // If a single class causes an overflow, we're really out of luck if (curPool.hasOverflowed()) { throw new RuntimeException("Class is bigger than a single dex file can be"); } } }
public static void writeTo(@Nonnull DexDataStore dataStore, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException { DexPool dexPool = new DexPool(input.getOpcodes()); for (ClassDef classDef: input.getClasses()) { dexPool.internClass(classDef); } dexPool.writeTo(dataStore); }
DexPool dexPool = new DexPool(Opcodes.getDefault()); dexPool.internClass(class1); dexPool.mark(); dexPool.internClass(class2); dexPool.reset(); dexPool.writeTo(dataStore); dexFile1 = new RawDexFile(Opcodes.getDefault(), dataStore.getBuffer()); DexPool dexPool = new DexPool(Opcodes.getDefault()); dexPool.internClass(class1); dexPool.writeTo(dataStore); dexFile2 = new RawDexFile(Opcodes.getDefault(), dataStore.getBuffer());
public <C extends ClassDef> void writeClassesTo( List<C> classList, DexDataStoreFactory store) throws IOException { int dexNum = 0; DexPool dexPool = new DexPool(opcodes); ClassPool clsPool = dexPool.classSection; classList.sort(Comparator.comparing(ClassDef::getType)); for (ClassDef classDef : classList) { int numMethodIds = dexPool.methodSection.getItemCount(); int numFieldIds = dexPool.fieldSection.getItemCount(); int constantPoolSize = classDef.getDirectMethodCount() + classDef.getVirtualMethodCount() + classDef.getStaticFieldCount() + classDef.getInstanceFieldCount(); int maxMethodIdsInDex = numMethodIds + constantPoolSize + MAX_METHOD_ADDED_DURING_DEX_CREATION; int maxFieldIdsInDex = numFieldIds + constantPoolSize + MAX_FIELD_ADDED_DURING_DEX_CREATION; if (maxMethodIdsInDex > mMaxNumberOfIdxPerDex || maxFieldIdsInDex > mMaxNumberOfIdxPerDex) { dexPool.writeTo(store.getDataStore(dexNum)); dexNum++; dexPool = new DexPool(opcodes); clsPool = dexPool.classSection; } clsPool.intern(classDef); } dexPool.writeTo(store.getDataStore(dexNum)); }
dexPool.internEncodedValue(initialValue);
public static void writeTo(@Nonnull String path, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException { DexPool dexPool = makeDexPool(); for (ClassDef classDef: input.getClasses()) { ((ClassPool)dexPool.classSection).intern(classDef); } dexPool.writeTo(new FileDataStore(new File(path))); }
public static void writeTo(@Nonnull DexDataStore dataStore, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException { DexPool dexPool = new DexPool(input.getOpcodes()); for (ClassDef classDef: input.getClasses()) { dexPool.internClass(classDef); } dexPool.writeTo(dataStore); }
public void intern(@Nonnull ArrayEncodedValue arrayEncodedValue) { Integer prev = internedItems.put(arrayEncodedValue, 0); if (prev == null) { for (EncodedValue value: arrayEncodedValue.getValue()) { dexPool.internEncodedValue(value); } } }
public static void writeTo(@Nonnull String path, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException { DexPool dexPool = new DexPool(input.getOpcodes()); for (ClassDef classDef: input.getClasses()) { dexPool.internClass(classDef); } dexPool.writeTo(new FileDataStore(new File(path))); }
/** * Writes all built dex files to the given folder. * * @param folder * the output folder * @return File handles to all written dex files * @throws IOException * when failed to create {@link FileDataStore} */ public List<File> writeTo(String folder) throws IOException { final List<File> result = new ArrayList<>(dexPools.size()); for (DexPool dexPool : dexPools) { int count = result.size(); // name dex files: classes.dex, classes2.dex, classes3.dex, etc. File file = new File(folder, "classes" + (count == 0 ? "" : count + 1) + ".dex"); result.add(file); FileDataStore fds = new FileDataStore(file); dexPool.writeTo(fds); fds.close(); } return result; } }
public void intern(@Nonnull ArrayEncodedValue arrayEncodedValue) { Integer prev = internedItems.put(arrayEncodedValue, 0); if (prev == null) { for (EncodedValue value: arrayEncodedValue.getValue()) { dexPool.internEncodedValue(value); } } }
public static DexPool makeDexPool(int api) { StringPool stringPool = new StringPool(); TypePool typePool = new TypePool(stringPool); FieldPool fieldPool = new FieldPool(stringPool, typePool); TypeListPool typeListPool = new TypeListPool(typePool); ProtoPool protoPool = new ProtoPool(stringPool, typePool, typeListPool); MethodPool methodPool = new MethodPool(stringPool, typePool, protoPool); AnnotationPool annotationPool = new AnnotationPool(stringPool, typePool, fieldPool, methodPool); AnnotationSetPool annotationSetPool = new AnnotationSetPool(annotationPool); ClassPool classPool = new ClassPool(stringPool, typePool, fieldPool, methodPool, annotationSetPool, typeListPool); return new DexPool(api, stringPool, typePool, protoPool, fieldPool, methodPool, classPool, typeListPool, annotationPool, annotationSetPool); }
public static void writeTo(@Nonnull String path, @Nonnull org.jf.dexlib2.iface.DexFile input) throws IOException { DexPool dexPool = new DexPool(input.getOpcodes()); for (ClassDef classDef: input.getClasses()) { dexPool.internClass(classDef); } dexPool.writeTo(new FileDataStore(new File(path))); }
public static void writeDexFile(String path, DexFile dexFile) throws IOException { DexPool.writeTo(path, dexFile); }
public void intern(@Nonnull Annotation annotation) { Integer prev = internedItems.put(annotation, 0); if (prev == null) { dexPool.typeSection.intern(annotation.getType()); for (AnnotationElement element: annotation.getElements()) { dexPool.stringSection.intern(element.getName()); dexPool.internEncodedValue(element.getValue()); } } }
/** * Writes a DexFile out to disk * * @param path The path to write the dex file to * @param dexFile a DexFile to write */ public static void writeDexFile(@Nonnull String path, @Nonnull DexFile dexFile) throws IOException { DexPool.writeTo(path, dexFile); }
public void intern(@Nonnull Annotation annotation) { Integer prev = internedItems.put(annotation, 0); if (prev == null) { dexPool.typeSection.intern(annotation.getType()); for (AnnotationElement element: annotation.getElements()) { dexPool.stringSection.intern(element.getName()); dexPool.internEncodedValue(element.getValue()); } } }
static void outputDex(@Nonnull DexFile dex, @Nonnull File output, boolean replace) throws IOException { if (output.exists()) { if (replace) { MiscUtil.delete(output); } else { final File old = output; output = MiscUtil.appendTail(output, "-deodex"); LLog.i(old + " already existed, use name " + output.getName()); } } DexPool.writeTo(output.getAbsolutePath(), dex); LLog.i("Output to " + output); }