mirror of
https://github.com/revanced/Apktool.git
synced 2024-12-05 02:22:55 +01:00
fixes #439
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:
parent
51013d9e0a
commit
42f69fd745
3
CHANGES
3
CHANGES
@ -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
|
||||||
|
@ -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'
|
||||||
}
|
}
|
@ -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");
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
62
brut.j.dir/src/main/java/brut/directory/ZipExtFile.java
Normal file
62
brut.j.dir/src/main/java/brut/directory/ZipExtFile.java
Normal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user