/** * Generates the signature and checksum of the dex file {@code out} and * writes them to the file. */ public void writeHashes() throws IOException { openSection(SIGNATURE_OFFSET).write(computeSignature(true)); openSection(CHECKSUM_OFFSET).writeInt(computeChecksum()); }
public DebugInfoItemSectionPatchAlgorithm( DexPatchFile patchFile, Dex oldDex, Dex patchedDex, SparseIndexMap oldToPatchedIndexMap ) { super(patchFile, oldDex, oldToPatchedIndexMap); if (patchedDex != null) { this.patchedDebugInfoItemTocSec = patchedDex.getTableOfContents().debugInfos; this.patchedDebugInfoItemSec = patchedDex.openSection(this.patchedDebugInfoItemTocSec); } }
public int findClassDefIndexFromTypeIndex(int typeIndex) { checkBounds(typeIndex, tableOfContents.typeIds.size); if (!tableOfContents.classDefs.exists()) { return -1; } for (int i = 0; i < tableOfContents.classDefs.size; i++) { if (typeIndexFromClassDefIndex(i) == typeIndex) { return i; } } return -1; }
public void executeAndSaveTo(OutputStream out) throws IOException { byte[] oldDexSign = this.oldDex.computeSignature(false); if (oldDexSign == null) { throw new IOException("failed to compute old dex's signature."); TableOfContents patchedToc = this.patchedDex.getTableOfContents(); Dex.Section headerOut = this.patchedDex.openSection(patchedToc.header.off); patchedToc.writeHeader(headerOut); Dex.Section mapListOut = this.patchedDex.openSection(patchedToc.mapList.off); patchedToc.writeMap(mapListOut); this.patchedDex.writeHashes(); this.patchedDex.writeTo(out);
public ClassData readClassData(ClassDef classDef) { int offset = classDef.classDataOffset; if (offset == 0) { throw new IllegalArgumentException("offset == 0"); } return openSection(offset).readClassData(); }
@Override protected TableOfContents.Section getTocSection(Dex dex) { return dex.getTableOfContents().annotationSets; }
@Override public boolean equals(Object obj) { DexClassInfo other = (DexClassInfo) obj; if (!classDesc.equals(other.classDesc)) { return false; } return owner.computeSignature(false).equals(other.owner.computeSignature(false)); } }
for (ClassDef classDef : this.newDex.classDefs()) { String typeName = this.newDex.typeNames().get(classDef.typeIndex); for (Pattern pattern : classNamePatterns) { if (pattern.matcher(typeName).matches()) { int patchedStringIdsSize = newDex.getTableOfContents().stringIds.size * SizeOf.STRING_ID_ITEM; int patchedTypeIdsSize = newDex.getTableOfContents().typeIds.size * SizeOf.TYPE_ID_ITEM; int patchedProtoIdsSize = newDex.getTableOfContents().protoIds.size * SizeOf.PROTO_ID_ITEM; int patchedFieldIdsSize = newDex.getTableOfContents().fieldIds.size * SizeOf.MEMBER_ID_ITEM; int patchedMethodIdsSize = newDex.getTableOfContents().methodIds.size * SizeOf.MEMBER_ID_ITEM; int patchedClassDefsSize = newDex.getTableOfContents().classDefs.size * SizeOf.CLASS_DEF_ITEM; if (this.oldDex.getTableOfContents().stringIds.isElementFourByteAligned) { this.patchedStringIdsOffset = SizeOf.roundToTimesOfFour(this.patchedStringIdsOffset); if (this.oldDex.getTableOfContents().stringDatas.isElementFourByteAligned) { this.patchedStringDataItemsOffset = SizeOf.roundToTimesOfFour(this.patchedStringDataItemsOffset); if (this.oldDex.getTableOfContents().typeIds.isElementFourByteAligned) { this.patchedTypeIdsOffset = SizeOf.roundToTimesOfFour(this.patchedTypeIdsOffset); + patchedIdSectionSize + this.stringDataSectionDiffAlg.getPatchedSectionSize(); if (this.oldDex.getTableOfContents().typeLists.isElementFourByteAligned) {
/** * Look up a method id declaring class index from a method index. Cheaper than: * {@code methodIds().get(methodIndex).getDeclaringClassIndex();} */ public int declaringClassIndexFromMethodIndex(int methodIndex) { checkBounds(methodIndex, tableOfContents.methodIds.size); int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex); return data.getShort(position) & 0xFFFF; // declaringClassIndex }
public Set<DexClassInfo> getClassInfosInDexesWithDuplicateCheck() { Map<String, DexClassInfo> classDescToInfoMap = new HashMap<>(); for (Dex dex : dexes) { int classDefIndex = 0; for (ClassDef classDef : dex.classDefs()) { String classDesc = dex.typeNames().get(classDef.typeIndex); if (!classDescToInfoMap.containsKey(classDesc)) { classDescToInfoMap.put(classDesc, new DexClassInfo(classDesc, classDefIndex, classDef, dex)); ++classDefIndex; } else { throw new IllegalStateException( String.format( "duplicate class descriptor [%s] in different dexes.", classDesc ) ); } } } return new HashSet<>(classDescToInfoMap.values()); } }
public void writeTo(File dexOut) throws IOException { OutputStream out = null; try { out = new BufferedOutputStream(new FileOutputStream(dexOut)); writeTo(out); } catch (Exception e) { throw new DexException(e); } finally { if (out != null) { try { out.close(); } catch (Exception e) { // ignored. } } } }
@Override public Integer get(int index) { return descriptorIndexFromTypeIndex(index); } @Override public int size() {
public void executeAndSaveTo(OutputStream out) throws IOException { byte[] oldDexSign = this.oldDex.computeSignature(false); if (oldDexSign == null) { throw new IOException("failed to compute old dex's signature."); TableOfContents patchedToc = this.patchedDex.getTableOfContents(); Dex.Section headerOut = this.patchedDex.openSection(patchedToc.header.off); patchedToc.writeHeader(headerOut); Dex.Section mapListOut = this.patchedDex.openSection(patchedToc.mapList.off); patchedToc.writeMap(mapListOut); this.patchedDex.writeHashes(); this.patchedDex.writeTo(out);
public Code readCode(ClassData.Method method) { int offset = method.codeOffset; if (offset == 0) { throw new IllegalArgumentException("offset == 0"); } return openSection(offset).readCode(); }
oldDex = (oldFile != null ? new Dex(oldFile) : null); newDex = (newFile != null ? new Dex(newFile) : null); for (ClassDef classDef : oldDex.classDefs()) { String desc = oldDex.typeNames().get(classDef.typeIndex); if (Utils.isStringMatchesPatterns(desc, patternsOfClassDescToCheck)) { oldClassesDescToCheck.add(desc); for (ClassDef classDef : newDex.classDefs()) { String desc = newDex.typeNames().get(classDef.typeIndex); if (Utils.isStringMatchesPatterns(desc, patternsOfClassDescToCheck)) { newClassesDescToCheck.add(desc);
@Override protected TableOfContents.Section getTocSection(Dex dex) { return dex.getTableOfContents().methodIds; }
buffer.writeInt(this.patchedEncodedArrayItemsOffset); buffer.writeInt(this.patchedAnnotationsDirectoryItemsOffset); buffer.write(this.oldDex.computeSignature(false)); int firstChunkOffset = buffer.position(); buffer.position(posOfFirstChunkOffsetField);
for (ClassDef classDef : this.newDex.classDefs()) { String typeName = this.newDex.typeNames().get(classDef.typeIndex); for (Pattern pattern : classNamePatterns) { if (pattern.matcher(typeName).matches()) { int patchedStringIdsSize = newDex.getTableOfContents().stringIds.size * SizeOf.STRING_ID_ITEM; int patchedTypeIdsSize = newDex.getTableOfContents().typeIds.size * SizeOf.TYPE_ID_ITEM; int patchedProtoIdsSize = newDex.getTableOfContents().protoIds.size * SizeOf.PROTO_ID_ITEM; int patchedFieldIdsSize = newDex.getTableOfContents().fieldIds.size * SizeOf.MEMBER_ID_ITEM; int patchedMethodIdsSize = newDex.getTableOfContents().methodIds.size * SizeOf.MEMBER_ID_ITEM; int patchedClassDefsSize = newDex.getTableOfContents().classDefs.size * SizeOf.CLASS_DEF_ITEM; if (this.oldDex.getTableOfContents().stringIds.isElementFourByteAligned) { this.patchedStringIdsOffset = SizeOf.roundToTimesOfFour(this.patchedStringIdsOffset); if (this.oldDex.getTableOfContents().stringDatas.isElementFourByteAligned) { this.patchedStringDataItemsOffset = SizeOf.roundToTimesOfFour(this.patchedStringDataItemsOffset); if (this.oldDex.getTableOfContents().typeIds.isElementFourByteAligned) { this.patchedTypeIdsOffset = SizeOf.roundToTimesOfFour(this.patchedTypeIdsOffset); + patchedIdSectionSize + this.stringDataSectionDiffAlg.getPatchedSectionSize(); if (this.oldDex.getTableOfContents().typeLists.isElementFourByteAligned) {