diff --git a/CHANGES b/CHANGES index 150e15d6..b399d8a2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,9 +1,10 @@ v2.0.0 (TBA) -Fixed (issue #8) - Correctly uses -c to retain original manifest and META-INF. Thanks M1cha -Fixed (issue #403) - Uses new usage output to cleanup organization of features. --Fixed (issue #359) - Correclty handles malformed 9patch images. (Thanks Felipe Richards) +-Fixed (issue #359) - Correctly handles malformed 9patch images. (Thanks Felipe Richards) -Fixed (issue #401) - Uses versionInfo meta to correctly parse versionName and versionCode -Fixed (issue #440) - Include aapt binaries within Apktool to have closer control over build. +-Fixed (issue #439) - Correctly handles apk's that have have the general access bit enabled for encryption v1.5.3 (TBA) -Updated to smali/baksmali to v1.4.2 diff --git a/brut.apktool.smali/dexlib/build.gradle b/brut.apktool.smali/dexlib/build.gradle index e708d652..b0144d17 100644 --- a/brut.apktool.smali/dexlib/build.gradle +++ b/brut.apktool.smali/dexlib/build.gradle @@ -30,6 +30,7 @@ */ dependencies { + compile project(':brut.j.dir') compile 'com.google.code.findbugs:jsr305:1.3.9' compile 'com.google.collections:google-collections:1.0' } \ No newline at end of file diff --git a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java index 80f25f87..0101338a 100644 --- a/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java +++ b/brut.apktool.smali/dexlib/src/main/java/org/jf/dexlib/DexFile.java @@ -28,6 +28,7 @@ package org.jf.dexlib; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import org.jf.dexlib.Util.*; import java.io.*; @@ -38,8 +39,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.zip.Adler32; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; +import brut.directory.ZipExtFile; /** *

Main use cases

@@ -287,13 +287,13 @@ public class DexFile InputStream inputStream = null; Input in = null; - ZipFile zipFile = null; + ZipExtFile zipFile = null; try { //do we have a zip file? if (magic[0] == 0x50 && magic[1] == 0x4B) { - zipFile = new ZipFile(file); - ZipEntry zipEntry = zipFile.getEntry("classes.dex"); + zipFile = new ZipExtFile(file); + ZipArchiveEntry zipEntry = zipFile.getEntry("classes.dex"); if (zipEntry == null) { throw new NoClassesDexException("zip file " + file.getName() + " does not contain a classes.dex " + "file"); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java index 0eee68b9..42c0613f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/Androlib.java @@ -151,7 +151,7 @@ public class Androlib { // with regular looping of apkFile for easy copy try { Directory unk = apkFile.getDirectory(); - ZipFile apkZipFile = new ZipFile(apkFile.getAbsolutePath()); + ZipExtFile apkZipFile = new ZipExtFile(apkFile.getAbsolutePath()); // loop all items in container recursively, ignoring any that are pre-defined by aapt Set files = unk.getFiles(true); @@ -162,6 +162,8 @@ public class Androlib { // to be re-included on build unk.copyToDir(unknownOut,file); try { + // ignore encryption + apkZipFile.getEntry(file.toString()).getGeneralPurposeBit().useEncryption(false); invZipFile = apkZipFile.getEntry(file.toString()); // lets record the name of the file, and its compression type diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java index 7d6ade68..dc80391d 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkDecoder.java @@ -24,12 +24,13 @@ import brut.androlib.res.data.ResTable; import brut.androlib.res.util.ExtFile; import brut.common.BrutException; import brut.directory.DirectoryException; +import brut.directory.ZipExtFile; import brut.util.OS; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; + import java.io.File; import java.io.IOException; import java.util.*; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; import java.util.zip.ZipEntry; /** @@ -95,18 +96,17 @@ public class ApkDecoder { } if (hasResources()) { - // read the resources.arsc checking for STORED vs DEFLATE // compression // this will determine whether we compress on rebuild or not. - JarFile jf = new JarFile(mApkFile.getAbsoluteFile()); - JarEntry je = jf.getJarEntry("resources.arsc"); - if (je != null) { - int compression = je.getMethod(); + ZipExtFile zef = new ZipExtFile(mApkFile.getAbsolutePath()); + ZipArchiveEntry ze = zef.getEntry("resources.arsc"); + if (ze != null) { + int compression = ze.getMethod(); mCompressResources = (compression != ZipEntry.STORED) && (compression == ZipEntry.DEFLATED); } - jf.close(); + zef.close(); switch (mDecodeResources) { case DECODE_RESOURCES_NONE: diff --git a/brut.j.dir/src/main/java/brut/directory/ZipExtFile.java b/brut.j.dir/src/main/java/brut/directory/ZipExtFile.java new file mode 100644 index 00000000..29c83d6e --- /dev/null +++ b/brut.j.dir/src/main/java/brut/directory/ZipExtFile.java @@ -0,0 +1,62 @@ +/** + * Copyright 2010 Ryszard Wiśniewski + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package brut.directory; + +import org.apache.commons.compress.archivers.zip.*; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.zip.ZipException; + +public class ZipExtFile extends ZipFile { + + public ZipExtFile(File f) throws IOException { + super(f); + } + + public ZipExtFile(String name) throws IOException { + super(name); + } + + public ZipExtFile(String name, String encoding) throws IOException { + super(name, encoding); + } + + public ZipExtFile(File f, String encoding) throws IOException { + super(f, encoding); + } + + public ZipExtFile(File f, String encoding, boolean useUnicodeExtraFields) throws IOException { + super(f, encoding, useUnicodeExtraFields); + } + + @Override + /** + * @author Panxiaobo + */ + public InputStream getInputStream(ZipArchiveEntry ze) + throws IOException, ZipException { + ze.getGeneralPurposeBit().useEncryption(false); + return super.getInputStream(ze); + } + + @Override + public ZipArchiveEntry getEntry(String name) { + return super.getEntry(name); + } + +} diff --git a/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java b/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java index effc4044..4c16febd 100644 --- a/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java +++ b/brut.j.dir/src/main/java/brut/directory/ZipRODirectory.java @@ -16,6 +16,7 @@ package brut.directory; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -23,11 +24,9 @@ import java.io.OutputStream; import java.util.Enumeration; import java.util.LinkedHashMap; import java.util.LinkedHashSet; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; public class ZipRODirectory extends AbstractDirectory { - private ZipFile mZipFile; + private ZipExtFile mZipFile; private String mPath; public ZipRODirectory(String zipFileName) throws DirectoryException { @@ -38,7 +37,7 @@ public class ZipRODirectory extends AbstractDirectory { this(zipFile, ""); } - public ZipRODirectory(ZipFile zipFile) { + public ZipRODirectory(ZipExtFile zipFile) { this(zipFile, ""); } @@ -50,14 +49,14 @@ public class ZipRODirectory extends AbstractDirectory { public ZipRODirectory(File zipFile, String path) throws DirectoryException { super(); try { - mZipFile = new ZipFile(zipFile); + mZipFile = new ZipExtFile(zipFile); } catch (IOException e) { throw new DirectoryException(e); } mPath = path; } - public ZipRODirectory(ZipFile zipFile, String path) { + public ZipRODirectory(ZipExtFile zipFile, String path) { super(); mZipFile = zipFile; mPath = path; @@ -73,7 +72,8 @@ public class ZipRODirectory extends AbstractDirectory { protected InputStream getFileInputLocal(String name) throws DirectoryException { try { - return getZipFile().getInputStream(new ZipEntry(getPath() + name)); + mZipFile.getEntry(getPath() + name).getGeneralPurposeBit().useEncryption(false); + return getZipFile().getInputStream(mZipFile.getEntry(getPath() + name)); } catch (IOException e) { throw new PathNotExist(name, e); } @@ -105,9 +105,12 @@ public class ZipRODirectory extends AbstractDirectory { mDirs = new LinkedHashMap(); int prefixLen = getPath().length(); - Enumeration entries = getZipFile().entries(); + Enumeration entries = getZipFile().getEntries(); while (entries.hasMoreElements()) { - ZipEntry entry = entries.nextElement(); + ZipArchiveEntry entry = entries.nextElement(); + + // ignore general purpose bit, since AOSP does + entry.getGeneralPurposeBit().useEncryption(false); String name = entry.getName(); if (name.equals(getPath()) || ! name.startsWith(getPath())) { @@ -137,7 +140,7 @@ public class ZipRODirectory extends AbstractDirectory { return mPath; } - private ZipFile getZipFile() { + private ZipExtFile getZipFile() { return mZipFile; }