From a7236053bfe8d66e18fd0422a1277165ffc43d28 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Fri, 3 May 2013 19:16:34 -0500 Subject: [PATCH] add unit-test and support for handling unknown files --- CHANGES | 1 + .../src/main/java/brut/androlib/Androlib.java | 49 +++++++++++++++---- .../brut/apktool/testapp/AndroidManifest.xml | 3 +- .../brut/apktool/testapp/apktool.yml | 9 +++- .../brut/apktool/testapp/unknown/hidden.file | 1 + .../testapp/unknown/unk_folder/unknown_file | 1 + 6 files changed, 51 insertions(+), 13 deletions(-) create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/hidden.file create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/unk_folder/unknown_file diff --git a/CHANGES b/CHANGES index b399d8a2..0bda95a8 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ v2.0.0 (TBA) -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 +-Fixed (issue #63) - Correctly handles apk's that have unknown files outside of the standard aapt allowed resources. v1.5.3 (TBA) -Updated to smali/baksmali to v1.4.2 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 2e2a8e2d..acae7f1d 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 @@ -23,15 +23,21 @@ import brut.androlib.res.data.ResTable; import brut.androlib.res.util.ExtFile; import brut.androlib.src.SmaliBuilder; import brut.androlib.src.SmaliDecoder; +import brut.androlib.src.TypeName; import brut.common.BrutException; import brut.directory.*; import brut.util.BrutIO; import brut.util.OS; import java.io.*; +import java.net.URI; +import java.nio.charset.Charset; +import java.nio.file.*; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; import java.util.*; import java.util.logging.Logger; import java.util.zip.ZipEntry; - +import java.nio.file.Files; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; @@ -529,31 +535,53 @@ public class Androlib { public void buildUnknownFiles(File appDir, File outFile, Map meta) throws AndrolibException { + File file; + mPath = Paths.get(appDir.getPath() + File.separatorChar + UNK_DIRNAME); - // confirm we have unknown files to inject if (meta.containsKey("unknownFiles")) { LOGGER.info("Copying unknown files/dir..."); Map files = (Map)meta.get("unknownFiles"); try { - ZipExtFile apkZipFile = new ZipExtFile(outFile.getAbsolutePath()); + // set our filesystem options + Map zip_properties = new HashMap<>(); + zip_properties.put("create", "false"); + zip_properties.put("encoding", "UTF-8"); - // loop through files inside - for (Map.Entry entry : files.entrySet()) { + // create filesystem + URI apkFileSystem = URI.create("jar:file:" + outFile.getAbsolutePath()); + try(FileSystem zipFS = FileSystems.newFileSystem(apkFileSystem, zip_properties)) { - // check if file exists - if (new File(appDir,entry.getKey()).isFile()) { + // loop through files inside + for (Map.Entry entry : files.entrySet()) { - // @todo read ZipFile and inject file into - // might need to use Zip4j + // check if file exists + file = new File(mPath.toFile(), entry.getKey()); + if (file.isFile() && file.exists()) { + insertFile(zipFS, file, entry.getValue(),mPath.toAbsolutePath()); + } } + zipFS.close(); } - apkZipFile.close(); } catch (IOException ex) { throw new AndrolibException(ex); } } + + } + + public void insertFile(FileSystem zipfs, File insert, String method, Path root) + throws AndrolibException, IOException { + Path zipRoot = zipfs.getPath(zipfs.getSeparator()); + Path zipPath = zipfs.getPath(zipRoot + insert.getAbsolutePath().replace(root.toString(),"")); + Path tmp = zipPath.normalize().getParent(); + + if (!Files.isDirectory(tmp, LinkOption.NOFOLLOW_LINKS)) { + Files.createDirectories(tmp); + } + Path newFile = Paths.get(insert.getAbsolutePath()); + Files.copy(newFile,zipPath, StandardCopyOption.REPLACE_EXISTING); } public void buildApk(File appDir, File outApk, @@ -652,6 +680,7 @@ public class Androlib { } private String mAaptPath = null; + private Path mPath = null; private final static Logger LOGGER = Logger.getLogger(Androlib.class .getName()); diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/AndroidManifest.xml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/AndroidManifest.xml index d79f6186..6863df42 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/AndroidManifest.xml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/AndroidManifest.xml @@ -1,3 +1,2 @@ - + diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml index dbe200bc..92fd3b17 100644 --- a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/apktool.yml @@ -1,6 +1,13 @@ -version: 1.5.0 +version: 2.0.0 apkFileName: testapp.apk isFrameworkApk: false usesFramework: ids: - 1 +versionInfo: + versionCode: '1' + versionName: '1.0' +compressionType: false +unknownFiles: + hidden.file: '8' + unk_folder/unknown_file: '8' \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/hidden.file b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/hidden.file new file mode 100644 index 00000000..d90f2a13 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/hidden.file @@ -0,0 +1 @@ +This file is unknown. \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/unk_folder/unknown_file b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/unk_folder/unknown_file new file mode 100644 index 00000000..70066423 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/testapp/unknown/unk_folder/unknown_file @@ -0,0 +1 @@ +I am a hidden file. Put here by a developer to make recompilation difficult. \ No newline at end of file