Extends ZipFile using apache commons compress ZipFile, to have finer control over the header allowing some parts to be ignored,
ex: the general access bit
This commit is contained in:
Connor Tumbleson 2013-04-06 12:50:42 -05:00
parent 51013d9e0a
commit 42f69fd745
7 changed files with 94 additions and 25 deletions

View File

@ -1,9 +1,10 @@
v2.0.0 (TBA) v2.0.0 (TBA)
-Fixed (issue #8) - Correctly uses -c to retain original manifest and META-INF. Thanks M1cha -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 #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 #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 #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) v1.5.3 (TBA)
-Updated to smali/baksmali to v1.4.2 -Updated to smali/baksmali to v1.4.2

View File

@ -30,6 +30,7 @@
*/ */
dependencies { dependencies {
compile project(':brut.j.dir')
compile 'com.google.code.findbugs:jsr305:1.3.9' compile 'com.google.code.findbugs:jsr305:1.3.9'
compile 'com.google.collections:google-collections:1.0' compile 'com.google.collections:google-collections:1.0'
} }

View File

@ -28,6 +28,7 @@
package org.jf.dexlib; package org.jf.dexlib;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.jf.dexlib.Util.*; import org.jf.dexlib.Util.*;
import java.io.*; import java.io.*;
@ -38,8 +39,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.zip.Adler32; import java.util.zip.Adler32;
import java.util.zip.ZipEntry; import brut.directory.ZipExtFile;
import java.util.zip.ZipFile;
/** /**
* <h3>Main use cases</h3> * <h3>Main use cases</h3>
@ -287,13 +287,13 @@ public class DexFile
InputStream inputStream = null; InputStream inputStream = null;
Input in = null; Input in = null;
ZipFile zipFile = null; ZipExtFile zipFile = null;
try { try {
//do we have a zip file? //do we have a zip file?
if (magic[0] == 0x50 && magic[1] == 0x4B) { if (magic[0] == 0x50 && magic[1] == 0x4B) {
zipFile = new ZipFile(file); zipFile = new ZipExtFile(file);
ZipEntry zipEntry = zipFile.getEntry("classes.dex"); ZipArchiveEntry zipEntry = zipFile.getEntry("classes.dex");
if (zipEntry == null) { if (zipEntry == null) {
throw new NoClassesDexException("zip file " + file.getName() + " does not contain a classes.dex " + throw new NoClassesDexException("zip file " + file.getName() + " does not contain a classes.dex " +
"file"); "file");

View File

@ -151,7 +151,7 @@ public class Androlib {
// with regular looping of apkFile for easy copy // with regular looping of apkFile for easy copy
try { try {
Directory unk = apkFile.getDirectory(); 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 // loop all items in container recursively, ignoring any that are pre-defined by aapt
Set<String> files = unk.getFiles(true); Set<String> files = unk.getFiles(true);
@ -162,6 +162,8 @@ public class Androlib {
// to be re-included on build // to be re-included on build
unk.copyToDir(unknownOut,file); unk.copyToDir(unknownOut,file);
try { try {
// ignore encryption
apkZipFile.getEntry(file.toString()).getGeneralPurposeBit().useEncryption(false);
invZipFile = apkZipFile.getEntry(file.toString()); invZipFile = apkZipFile.getEntry(file.toString());
// lets record the name of the file, and its compression type // lets record the name of the file, and its compression type

View File

@ -24,12 +24,13 @@ import brut.androlib.res.data.ResTable;
import brut.androlib.res.util.ExtFile; import brut.androlib.res.util.ExtFile;
import brut.common.BrutException; import brut.common.BrutException;
import brut.directory.DirectoryException; import brut.directory.DirectoryException;
import brut.directory.ZipExtFile;
import brut.util.OS; import brut.util.OS;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.*; import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
/** /**
@ -95,18 +96,17 @@ public class ApkDecoder {
} }
if (hasResources()) { if (hasResources()) {
// read the resources.arsc checking for STORED vs DEFLATE // read the resources.arsc checking for STORED vs DEFLATE
// compression // compression
// this will determine whether we compress on rebuild or not. // this will determine whether we compress on rebuild or not.
JarFile jf = new JarFile(mApkFile.getAbsoluteFile()); ZipExtFile zef = new ZipExtFile(mApkFile.getAbsolutePath());
JarEntry je = jf.getJarEntry("resources.arsc"); ZipArchiveEntry ze = zef.getEntry("resources.arsc");
if (je != null) { if (ze != null) {
int compression = je.getMethod(); int compression = ze.getMethod();
mCompressResources = (compression != ZipEntry.STORED) mCompressResources = (compression != ZipEntry.STORED)
&& (compression == ZipEntry.DEFLATED); && (compression == ZipEntry.DEFLATED);
} }
jf.close(); zef.close();
switch (mDecodeResources) { switch (mDecodeResources) {
case DECODE_RESOURCES_NONE: case DECODE_RESOURCES_NONE:

View File

@ -0,0 +1,62 @@
/**
* Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>
*
* 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);
}
}

View File

@ -16,6 +16,7 @@
package brut.directory; package brut.directory;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -23,11 +24,9 @@ import java.io.OutputStream;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
public class ZipRODirectory extends AbstractDirectory { public class ZipRODirectory extends AbstractDirectory {
private ZipFile mZipFile; private ZipExtFile mZipFile;
private String mPath; private String mPath;
public ZipRODirectory(String zipFileName) throws DirectoryException { public ZipRODirectory(String zipFileName) throws DirectoryException {
@ -38,7 +37,7 @@ public class ZipRODirectory extends AbstractDirectory {
this(zipFile, ""); this(zipFile, "");
} }
public ZipRODirectory(ZipFile zipFile) { public ZipRODirectory(ZipExtFile zipFile) {
this(zipFile, ""); this(zipFile, "");
} }
@ -50,14 +49,14 @@ public class ZipRODirectory extends AbstractDirectory {
public ZipRODirectory(File zipFile, String path) throws DirectoryException { public ZipRODirectory(File zipFile, String path) throws DirectoryException {
super(); super();
try { try {
mZipFile = new ZipFile(zipFile); mZipFile = new ZipExtFile(zipFile);
} catch (IOException e) { } catch (IOException e) {
throw new DirectoryException(e); throw new DirectoryException(e);
} }
mPath = path; mPath = path;
} }
public ZipRODirectory(ZipFile zipFile, String path) { public ZipRODirectory(ZipExtFile zipFile, String path) {
super(); super();
mZipFile = zipFile; mZipFile = zipFile;
mPath = path; mPath = path;
@ -73,7 +72,8 @@ public class ZipRODirectory extends AbstractDirectory {
protected InputStream getFileInputLocal(String name) protected InputStream getFileInputLocal(String name)
throws DirectoryException { throws DirectoryException {
try { 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) { } catch (IOException e) {
throw new PathNotExist(name, e); throw new PathNotExist(name, e);
} }
@ -105,9 +105,12 @@ public class ZipRODirectory extends AbstractDirectory {
mDirs = new LinkedHashMap<String, AbstractDirectory>(); mDirs = new LinkedHashMap<String, AbstractDirectory>();
int prefixLen = getPath().length(); int prefixLen = getPath().length();
Enumeration<? extends ZipEntry> entries = getZipFile().entries(); Enumeration<? extends ZipArchiveEntry> entries = getZipFile().getEntries();
while (entries.hasMoreElements()) { 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(); String name = entry.getName();
if (name.equals(getPath()) || ! name.startsWith(getPath())) { if (name.equals(getPath()) || ! name.startsWith(getPath())) {
@ -137,7 +140,7 @@ public class ZipRODirectory extends AbstractDirectory {
return mPath; return mPath;
} }
private ZipFile getZipFile() { private ZipExtFile getZipFile() {
return mZipFile; return mZipFile;
} }