From 9db742618bb045246d952c4cf911d299a59c1420 Mon Sep 17 00:00:00 2001 From: Sven Marquardt Date: Wed, 12 Oct 2022 12:55:29 +0200 Subject: [PATCH 01/18] Fixes #2900 (#2901) Fastst way to fix empty key value splitting for styled strings. Signed-off-by: Sven Marquardt Signed-off-by: Sven Marquardt --- .../src/main/java/brut/androlib/res/decoder/StyledString.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StyledString.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StyledString.java index 540ca0ba..057d1d2e 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StyledString.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/StyledString.java @@ -50,7 +50,7 @@ public class StyledString { public static class Span implements Comparable { private static final MapSplitter ATTRIBUTES_SPLITTER = - Splitter.on(';').withKeyValueSeparator(Splitter.on('=').limit(2)); + Splitter.on(';').omitEmptyStrings().withKeyValueSeparator(Splitter.on('=').limit(2)); private final String tag; private final int firstChar; From f8df056a2c6707b95348313ab71098858d3e3a10 Mon Sep 17 00:00:00 2001 From: Dominic Lemire Date: Wed, 2 Nov 2022 03:56:49 -0700 Subject: [PATCH 02/18] fix: overlay spec parsing (#2805) (#2917) --- .../brut/androlib/res/decoder/ARSCDecoder.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java index a650ec19..351470a8 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ARSCDecoder.java @@ -178,7 +178,19 @@ public class ARSCDecoder { nextChunk(); } - private void readOverlaySpec() throws IOException { + private void readOverlaySpec() throws AndrolibException, IOException { + checkChunkType(Header.XML_TYPE_OVERLAY); + String name = mIn.readNullEndedString(128, true); + String actor = mIn.readNullEndedString(128, true); + LOGGER.fine(String.format("Overlay name: \"%s\", actor: \"%s\")", name, actor)); + + while(nextChunk().type == Header.XML_TYPE_OVERLAY_POLICY) { + readOverlayPolicySpec(); + } + } + + private void readOverlayPolicySpec() throws AndrolibException, IOException { + checkChunkType(Header.XML_TYPE_OVERLAY_POLICY); /* policyFlags */mIn.skipInt(); int count = mIn.readInt(); From c4e8f88499222036c3cbe0964e038fe189bdaa98 Mon Sep 17 00:00:00 2001 From: Kirlif Date: Mon, 7 Nov 2022 14:06:22 +0100 Subject: [PATCH 03/18] =?UTF-8?q?Fix=20=C2=AB=20doNotCompress=20=C2=BB=20i?= =?UTF-8?q?n=20case=20of=20obfuscated=20resources.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/brut/androlib/Androlib.java | 3 +++ .../main/java/brut/androlib/res/AndrolibResources.java | 4 +++- .../java/brut/androlib/res/decoder/ResFileDecoder.java | 9 ++++++++- 3 files changed, 14 insertions(+), 2 deletions(-) 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 4077ca6f..8c197131 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 @@ -184,6 +184,9 @@ public class Androlib { if (ext.isEmpty() || !NO_COMPRESS_PATTERN.matcher(ext).find()) { ext = file; + if (mAndRes.ObfFiles.containsKey(ext)) { + ext = mAndRes.ObfFiles.get(ext); + } } if (!uncompressedFilesOrExts.contains(ext)) { uncompressedFilesOrExts.add(ext); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index a4492dc4..59b18213 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -247,7 +247,7 @@ final public class AndrolibResources { LOGGER.info("Decoding file-resources..."); for (ResResource res : pkg.listFiles()) { - fileDecoder.decode(res, in, out); + fileDecoder.decode(res, in, out, ObfFiles); } LOGGER.info("Decoding values */* XMLs..."); @@ -1041,6 +1041,8 @@ final public class AndrolibResources { public BuildOptions buildOptions; + public Map ObfFiles = new HashMap(); + // TODO: dirty static hack. I have to refactor decoding mechanisms. public static boolean sKeepBroken = false; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java index 7d32581d..351a6819 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java @@ -27,6 +27,7 @@ import brut.directory.Directory; import brut.directory.DirectoryException; import java.io.*; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -37,10 +38,11 @@ public class ResFileDecoder { this.mDecoders = decoders; } - public void decode(ResResource res, Directory inDir, Directory outDir) + public void decode(ResResource res, Directory inDir, Directory outDir, Map obfFiles) throws AndrolibException { ResFileValue fileValue = (ResFileValue) res.getValue(); + String inFileFullName = fileValue.toString(); String inFileName = fileValue.getStrippedPath(); String outResName = res.getFilePath(); String typeName = res.getResSpec().getType().getName(); @@ -55,6 +57,11 @@ public class ResFileDecoder { outFileName = outResName + ext; } + String outFileFullName = "res/"+outFileName; + if (!inFileFullName.equals(outFileFullName)) { + obfFiles.put(inFileFullName, outFileFullName); + } + try { if (typeName.equals("raw")) { decode(inDir, inFileName, outDir, outFileName, "raw"); From 6a70be6c268b040149835eb1934e8aacc8a8b50a Mon Sep 17 00:00:00 2001 From: Miepee <38186597+Miepee@users.noreply.github.com> Date: Tue, 8 Nov 2022 11:54:36 +0100 Subject: [PATCH 04/18] make default framework detection on linux xdg-compliant (#2924) On Linux, check first if $XDG_DATA_HOME is set, if not use path as it was before (~/.local/share/apktool) --- .../src/main/java/brut/androlib/res/AndrolibResources.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index a4492dc4..9ed36078 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -974,7 +974,12 @@ final public class AndrolibResources { } else if (OSDetection.isWindows()) { path = parentPath.getAbsolutePath() + String.format("%1$sAppData%1$sLocal%1$sapktool%1$sframework", File.separatorChar); } else { - path = parentPath.getAbsolutePath() + String.format("%1$s.local%1$sshare%1$sapktool%1$sframework", File.separatorChar); + String xdgDataFolder = System.getenv("XDG_DATA_HOME"); + if (xdgDataFolder != null) { + path = xdgDataFolder + String.format("%1$sapktool%1$sframework", File.separatorChar); + } else { + path = parentPath.getAbsolutePath() + String.format("%1$s.local%1$sshare%1$sapktool%1$sframework", File.separatorChar); + } } } From b32be8ca2a4e9b59654a481c1e017692943d4c00 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Tue, 8 Nov 2022 06:24:41 -0500 Subject: [PATCH 05/18] refactor: rename attributes for storing obfuscated filepath --- .../src/main/java/brut/androlib/Androlib.java | 16 ++++++++-------- .../brut/androlib/res/AndrolibResources.java | 4 ++-- .../androlib/res/decoder/ResFileDecoder.java | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) 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 8c197131..a36468ae 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 @@ -177,19 +177,19 @@ public class Androlib { for (String file : files) { if (isAPKFileNames(file) && unk.getCompressionLevel(file) == 0) { - String ext = ""; + String extOrFile = ""; if (unk.getSize(file) != 0) { - ext = FilenameUtils.getExtension(file); + extOrFile = FilenameUtils.getExtension(file); } - if (ext.isEmpty() || !NO_COMPRESS_PATTERN.matcher(ext).find()) { - ext = file; - if (mAndRes.ObfFiles.containsKey(ext)) { - ext = mAndRes.ObfFiles.get(ext); + if (extOrFile.isEmpty() || !NO_COMPRESS_PATTERN.matcher(extOrFile).find()) { + extOrFile = file; + if (mAndRes.mResFileMapping.containsKey(extOrFile)) { + extOrFile = mAndRes.mResFileMapping.get(extOrFile); } } - if (!uncompressedFilesOrExts.contains(ext)) { - uncompressedFilesOrExts.add(ext); + if (!uncompressedFilesOrExts.contains(extOrFile)) { + uncompressedFilesOrExts.add(extOrFile); } } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index 59b18213..e9415efe 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -247,7 +247,7 @@ final public class AndrolibResources { LOGGER.info("Decoding file-resources..."); for (ResResource res : pkg.listFiles()) { - fileDecoder.decode(res, in, out, ObfFiles); + fileDecoder.decode(res, in, out, mResFileMapping); } LOGGER.info("Decoding values */* XMLs..."); @@ -1041,7 +1041,7 @@ final public class AndrolibResources { public BuildOptions buildOptions; - public Map ObfFiles = new HashMap(); + public Map mResFileMapping = new HashMap(); // TODO: dirty static hack. I have to refactor decoding mechanisms. public static boolean sKeepBroken = false; diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java index 351a6819..75f67a8c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java @@ -38,11 +38,11 @@ public class ResFileDecoder { this.mDecoders = decoders; } - public void decode(ResResource res, Directory inDir, Directory outDir, Map obfFiles) + public void decode(ResResource res, Directory inDir, Directory outDir, Map resFileMapping) throws AndrolibException { ResFileValue fileValue = (ResFileValue) res.getValue(); - String inFileFullName = fileValue.toString(); + String inFilePath = fileValue.toString(); String inFileName = fileValue.getStrippedPath(); String outResName = res.getFilePath(); String typeName = res.getResSpec().getType().getName(); @@ -57,9 +57,9 @@ public class ResFileDecoder { outFileName = outResName + ext; } - String outFileFullName = "res/"+outFileName; - if (!inFileFullName.equals(outFileFullName)) { - obfFiles.put(inFileFullName, outFileFullName); + String outFilePath = "res/" + outFileName; + if (!inFilePath.equals(outFilePath)) { + resFileMapping.put(inFilePath, outFilePath); } try { From ef83dc2f04f4bfa7d7e68f37123ef428928e5b95 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Tue, 8 Nov 2022 06:56:05 -0500 Subject: [PATCH 06/18] fix: don't assume a referent exists on ReferenceValue (#2926) --- .../src/main/java/brut/androlib/res/data/value/ResEnumAttr.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java index 50e7f615..64e51f0c 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/value/ResEnumAttr.java @@ -71,7 +71,7 @@ public class ResEnumAttr extends ResAttr { break; } } - if (ref != null) { + if (ref != null && !ref.referentIsNull()) { value2 = ref.getReferent().getName(); mItemsCache.put(value, value2); } From 07d15e82007b13760ad13b535ae77c468e7c8110 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Wed, 9 Nov 2022 06:03:44 -0500 Subject: [PATCH 07/18] Squashed commit of the following: commit 66a7167079caafd2e805dcd9e3dd1a883b92493b Author: Connor Tumbleson Date: Wed Nov 9 06:02:23 2022 -0500 refactor: add message when pairing --only-main-classes w/ --no-src commit 565a4dbe33e69e0da775ad8678a29fd7e117fe3c Author: surendrajat Date: Wed Nov 9 12:12:28 2022 +0530 fix: --no-src should take precedence over --only-main-classes --- .../apktool-lib/src/main/java/brut/androlib/ApkDecoder.java | 4 ++++ 1 file changed, 4 insertions(+) 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 4e186f18..bd8ad964 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 @@ -180,6 +180,10 @@ public class ApkDecoder { if (mode != DECODE_SOURCES_NONE && mode != DECODE_SOURCES_SMALI && mode != DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES) { throw new AndrolibException("Invalid decode sources mode: " + mode); } + if (mDecodeSources == DECODE_SOURCES_NONE && mode == DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES) { + LOGGER.info("--only-main-classes cannot be paired with -s/--no-src. Ignoring."); + return; + } mDecodeSources = mode; } From e46f779b871a5f78869f5781f9f4501672de6efd Mon Sep 17 00:00:00 2001 From: Build-0-Matic <42479555+Build-0-Matic@users.noreply.github.com> Date: Sat, 12 Nov 2022 06:16:07 -0500 Subject: [PATCH 08/18] Update apktool.bat (#2930) Added missing quotes required for the file to work in Windows --- scripts/windows/apktool.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/windows/apktool.bat b/scripts/windows/apktool.bat index f0d14869..afc2a8a0 100755 --- a/scripts/windows/apktool.bat +++ b/scripts/windows/apktool.bat @@ -6,7 +6,7 @@ chcp 65001 2>nul >nul set java_exe=java.exe if defined JAVA_HOME ( -set "java_exe=%JAVA_HOME%\bin\java.exe" +set "java_exe"="%JAVA_HOME%\bin\java.exe" ) rem Find the highest version .jar available in the same directory as the script From d66db22564cd480d681c674af249c34893656445 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sat, 12 Nov 2022 11:35:40 -0500 Subject: [PATCH 09/18] Revert "Update apktool.bat (#2930)" (#2931) This reverts commit e46f779b871a5f78869f5781f9f4501672de6efd. --- scripts/windows/apktool.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/windows/apktool.bat b/scripts/windows/apktool.bat index afc2a8a0..f0d14869 100755 --- a/scripts/windows/apktool.bat +++ b/scripts/windows/apktool.bat @@ -6,7 +6,7 @@ chcp 65001 2>nul >nul set java_exe=java.exe if defined JAVA_HOME ( -set "java_exe"="%JAVA_HOME%\bin\java.exe" +set "java_exe=%JAVA_HOME%\bin\java.exe" ) rem Find the highest version .jar available in the same directory as the script From 22f2e6fb23cd2789459a86e67691f2f1adf28e6a Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 13 Nov 2022 18:06:25 -0500 Subject: [PATCH 10/18] fix: support properly mapping r/R/res resources during disassemble (#2936) --- .../brut/androlib/res/AndrolibResources.java | 14 ++------- .../androlib/res/decoder/ResFileDecoder.java | 30 +++++++++---------- 2 files changed, 16 insertions(+), 28 deletions(-) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java index ded97b98..9f2499e3 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/AndrolibResources.java @@ -221,22 +221,12 @@ final public class AndrolibResources { ResAttrDecoder attrDecoder = duo.m2.getAttrDecoder(); attrDecoder.setCurrentPackage(resTable.listMainPackages().iterator().next()); - Directory inApk, in = null, out; + Directory in, out; try { out = new FileDirectory(outDir); - - inApk = apkFile.getDirectory(); + in = apkFile.getDirectory(); out = out.createDir("res"); - if (inApk.containsDir("res")) { - in = inApk.getDir("res"); - } - if (in == null && inApk.containsDir("r")) { - in = inApk.getDir("r"); - } - if (in == null && inApk.containsDir("R")) { - in = inApk.getDir("R"); - } } catch (DirectoryException ex) { throw new AndrolibException(ex); } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java index 75f67a8c..a3174411 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/decoder/ResFileDecoder.java @@ -64,11 +64,11 @@ public class ResFileDecoder { try { if (typeName.equals("raw")) { - decode(inDir, inFileName, outDir, outFileName, "raw"); + decode(inDir, inFilePath, outDir, outFileName, "raw"); return; } if (typeName.equals("font") && !".xml".equals(ext)) { - decode(inDir, inFileName, outDir, outFileName, "raw"); + decode(inDir, inFilePath, outDir, outFileName, "raw"); return; } if (typeName.equals("drawable") || typeName.equals("mipmap")) { @@ -83,26 +83,24 @@ public class ResFileDecoder { // check for raw 9patch images for (String extension : RAW_9PATCH_IMAGE_EXTENSIONS) { if (inFileName.toLowerCase().endsWith("." + extension)) { - copyRaw(inDir, outDir, inFileName, outFileName); + copyRaw(inDir, outDir, inFilePath, outFileName); return; } } // check for xml 9 patches which are just xml files if (inFileName.toLowerCase().endsWith(".xml")) { - decode(inDir, inFileName, outDir, outFileName, "xml"); + decode(inDir, inFilePath, outDir, outFileName, "xml"); return; } try { - decode(inDir, inFileName, outDir, outFileName, "9patch"); + decode(inDir, inFilePath, outDir, outFileName, "9patch"); return; } catch (CantFind9PatchChunkException ex) { - LOGGER.log( - Level.WARNING, - String.format( - "Cant find 9patch chunk in file: \"%s\". Renaming it to *.png.", - inFileName), ex); + LOGGER.log(Level.WARNING, String.format( + "Cant find 9patch chunk in file: \"%s\". Renaming it to *.png.", inFileName + ), ex); outDir.removeFile(outFileName); outFileName = outResName + ext; } @@ -111,27 +109,27 @@ public class ResFileDecoder { // check for raw image for (String extension : RAW_IMAGE_EXTENSIONS) { if (inFileName.toLowerCase().endsWith("." + extension)) { - copyRaw(inDir, outDir, inFileName, outFileName); + copyRaw(inDir, outDir, inFilePath, outFileName); return; } } if (!".xml".equals(ext)) { - decode(inDir, inFileName, outDir, outFileName, "raw"); + decode(inDir, inFilePath, outDir, outFileName, "raw"); return; } } - decode(inDir, inFileName, outDir, outFileName, "xml"); + decode(inDir, inFilePath, outDir, outFileName, "xml"); } catch (RawXmlEncounteredException ex) { // If we got an error to decode XML, lets assume the file is in raw format. // This is a large assumption, that might increase runtime, but will save us for situations where // XSD files are AXML`d on aapt1, but left in plaintext in aapt2. - decode(inDir, inFileName, outDir, outFileName, "raw"); + decode(inDir, inFilePath, outDir, outFileName, "raw"); } catch (AndrolibException ex) { LOGGER.log(Level.SEVERE, String.format( - "Could not decode file, replacing by FALSE value: %s", - inFileName), ex); + "Could not decode file, replacing by FALSE value: %s", + inFileName), ex); res.replace(new ResBoolValue(false, 0, null)); } } From 8749e2a6c4d0548808f5a92ccd7a1b744da0b4a3 Mon Sep 17 00:00:00 2001 From: Danealau <57352065+Danealau@users.noreply.github.com> Date: Thu, 17 Nov 2022 03:52:55 +0300 Subject: [PATCH 11/18] fix: support (name removed) res items. (#2940) * fix: res/layout/(name removed).xml: Invalid file name: must contain only [a-zA-Z0-9$_.] error * refactored fix --- .../src/main/java/brut/androlib/res/data/ResResSpec.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java index 88cded09..32b4065f 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/data/ResResSpec.java @@ -36,6 +36,8 @@ public class ResResSpec { this.mId = id; String cleanName; + name = (("(name removed)".equals(name)) ? null : name); + ResResSpec resResSpec = type.getResSpecUnsafe(name); if (resResSpec != null) { cleanName = String.format("APKTOOL_DUPLICATE_%s_%s", type, id.toString()); From e32309c96f31d1ca287189c125e809022fd176b6 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Fri, 18 Nov 2022 07:19:53 -0500 Subject: [PATCH 12/18] build: update to non-vulnerable commons_text/snakeyaml (#2942) --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 0a286fc6..55415c67 100644 --- a/build.gradle +++ b/build.gradle @@ -22,11 +22,11 @@ buildscript { commons_cli : 'commons-cli:commons-cli:1.5.0', commons_io : 'commons-io:commons-io:2.11.0', commons_lang : 'org.apache.commons:commons-lang3:3.12.0', - commons_text : 'org.apache.commons:commons-text:1.9', + commons_text : 'org.apache.commons:commons-text:1.10.0', guava : 'com.google.guava:guava:31.0.1-jre', junit : 'junit:junit:4.13.2', proguard_gradle: 'com.guardsquare:proguard-gradle:7.1.1', - snakeyaml : 'org.yaml:snakeyaml:1.29:android', + snakeyaml : 'org.yaml:snakeyaml:1.32:android', smali : 'org.smali:smali:2.5.2', xmlpull : 'xpp3:xpp3:1.1.4c', xmlunit : 'xmlunit:xmlunit:1.6', From 35ce8fc061d31e30978c6f65d194fe3c4191b0be Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Sun, 20 Nov 2022 08:08:45 -0500 Subject: [PATCH 13/18] Issue 2943 - Support raw disassembly w/ AndResGuard (#2944) * fix: allow copying r/R if in raw mode * test: assert raw files disassembled from AndResGuard --- .../src/main/java/brut/androlib/Androlib.java | 2 +- .../java/brut/androlib/decode/AndResGuardTest.java | 14 ++++++++++++++ .../src/main/java/brut/directory/DirUtil.java | 8 ++++---- 3 files changed, 19 insertions(+), 5 deletions(-) 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 a36468ae..0158f6a3 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 @@ -842,7 +842,7 @@ public class Androlib { private final static String APK_DIRNAME = "build/apk"; private final static String UNK_DIRNAME = "unknown"; private final static String[] APK_RESOURCES_FILENAMES = new String[] { - "resources.arsc", "AndroidManifest.xml", "res" }; + "resources.arsc", "AndroidManifest.xml", "res", "r", "R" }; private final static String[] APK_RESOURCES_WITHOUT_RES_FILENAMES = new String[] { "resources.arsc", "AndroidManifest.xml" }; private final static String[] APP_RESOURCES_FILENAMES = new String[] { diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java index db78c4c5..ec60e4d4 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/AndResGuardTest.java @@ -56,4 +56,18 @@ public class AndResGuardTest extends BaseTest { File aPng = new File(sTestOrigDir,"res/mipmap-hdpi-v4/a.png"); assertTrue(aPng.isFile()); } + + @Test + public void checkifAndResDecodeRemapsRFolderInRawMode() throws BrutException, IOException { + String apk = "issue1170.apk"; + ApkDecoder apkDecoder = new ApkDecoder(new File(sTmpDir + File.separator + apk)); + sTestOrigDir = new ExtFile(sTmpDir + File.separator + apk + ".raw.out"); + + apkDecoder.setOutDir(new File(sTmpDir + File.separator + apk + ".raw.out")); + apkDecoder.setDecodeResources(ApkDecoder.DECODE_RESOURCES_NONE); + apkDecoder.decode(); + + File aPng = new File(sTestOrigDir,"r/a/a.png"); + assertTrue(aPng.isFile()); + } } diff --git a/brut.j.dir/src/main/java/brut/directory/DirUtil.java b/brut.j.dir/src/main/java/brut/directory/DirUtil.java index b22735a9..53701f59 100644 --- a/brut.j.dir/src/main/java/brut/directory/DirUtil.java +++ b/brut.j.dir/src/main/java/brut/directory/DirUtil.java @@ -23,6 +23,7 @@ import brut.common.TraversalUnknownFileException; import brut.util.BrutIO; import brut.util.OS; import java.io.*; +import java.nio.file.Files; import java.util.logging.Logger; public class DirUtil { @@ -84,14 +85,13 @@ public class DirUtil { if (in.containsDir(fileName)) { OS.rmdir(new File(out, fileName)); in.getDir(fileName).copyToDir(new File(out, fileName)); + } else if (!in.containsDir(fileName) && !in.containsFile(fileName)) { + // Skip copies of directories/files not found. } else { - if (fileName.equals("res") && !in.containsFile(fileName)) { - return; - } String cleanedFilename = BrutIO.sanitizeUnknownFile(out, fileName); File outFile = new File(out, cleanedFilename); outFile.getParentFile().mkdirs(); - BrutIO.copyAndClose(in.getFileInput(fileName), new FileOutputStream(outFile)); + BrutIO.copyAndClose(in.getFileInput(fileName), Files.newOutputStream(outFile.toPath())); } } catch (RootUnknownFileException | InvalidUnknownFileException | TraversalUnknownFileException exception) { LOGGER.warning(String.format("Skipping file %s (%s)", fileName, exception.getMessage())); From 67a936f1c7ab1ff1388904957b82854c6d347156 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 24 Nov 2022 06:15:41 -0500 Subject: [PATCH 14/18] build: include bleeding edge smali from source via jitpack (#2941) * build: include smali from source * refactor: adjust build.gradle for repositories --- brut.apktool/apktool-cli/build.gradle | 9 +++++---- brut.apktool/apktool-lib/build.gradle | 27 +++++++++++++-------------- brut.j.common/build.gradle | 5 ----- brut.j.dir/build.gradle | 7 +++---- brut.j.util/build.gradle | 5 ++--- build.gradle | 17 ++++++++++------- 6 files changed, 33 insertions(+), 37 deletions(-) diff --git a/brut.apktool/apktool-cli/build.gradle b/brut.apktool/apktool-cli/build.gradle index 083c7b52..d115f36d 100644 --- a/brut.apktool/apktool-cli/build.gradle +++ b/brut.apktool/apktool-cli/build.gradle @@ -23,11 +23,12 @@ dependencies { } buildscript { - repositories { - mavenCentral() - } - dependencies { + repositories { + mavenCentral() + gradlePluginPortal() + } + classpath(depends.proguard_gradle) { exclude group: 'com.android.tools.build' } diff --git a/brut.apktool/apktool-lib/build.gradle b/brut.apktool/apktool-lib/build.gradle index 13b69c4e..080ffb77 100644 --- a/brut.apktool/apktool-lib/build.gradle +++ b/brut.apktool/apktool-lib/build.gradle @@ -33,20 +33,19 @@ processResources { } dependencies { + api project(':brut.j.dir') + api project(':brut.j.util') + api project(':brut.j.common') + + implementation depends.baksmali + implementation depends.smali + implementation depends.snakeyaml + implementation depends.xmlpull + implementation depends.guava + implementation depends.commons_lang + implementation depends.commons_io + implementation depends.commons_text + testImplementation depends.junit - - api project(':brut.j.dir'), - project(':brut.j.util'), - project(':brut.j.common') - - implementation depends.baksmali, - depends.smali, - depends.snakeyaml, - depends.xmlpull, - depends.guava, - depends.commons_lang, - depends.commons_io, - depends.commons_text - testImplementation depends.xmlunit } diff --git a/brut.j.common/build.gradle b/brut.j.common/build.gradle index 98929c3f..41a98796 100644 --- a/brut.j.common/build.gradle +++ b/brut.j.common/build.gradle @@ -13,8 +13,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -dependencies { - testImplementation depends.junit -} - diff --git a/brut.j.dir/build.gradle b/brut.j.dir/build.gradle index 0512ffe9..0e5e1cfe 100644 --- a/brut.j.dir/build.gradle +++ b/brut.j.dir/build.gradle @@ -15,8 +15,7 @@ */ dependencies { - implementation project(':brut.j.common'), - project(':brut.j.util'), - depends.commons_io - testImplementation depends.junit + implementation project(':brut.j.common') + implementation project(':brut.j.util') + implementation depends.commons_io } diff --git a/brut.j.util/build.gradle b/brut.j.util/build.gradle index 5e8c7cd5..92d7c923 100644 --- a/brut.j.util/build.gradle +++ b/brut.j.util/build.gradle @@ -15,7 +15,6 @@ */ dependencies { - implementation project(':brut.j.common'), - depends.commons_io - testImplementation depends.junit + implementation project(':brut.j.common') + implementation depends.commons_io } diff --git a/build.gradle b/build.gradle index 55415c67..d7b24581 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,7 @@ import java.nio.charset.StandardCharsets buildscript { ext { depends = [ - baksmali : 'org.smali:baksmali:2.5.2', + baksmali : 'com.github.iBotPeaches.smali:baksmali:403e90375e', commons_cli : 'commons-cli:commons-cli:1.5.0', commons_io : 'commons-io:commons-io:2.11.0', commons_lang : 'org.apache.commons:commons-lang3:3.12.0', @@ -27,14 +27,13 @@ buildscript { junit : 'junit:junit:4.13.2', proguard_gradle: 'com.guardsquare:proguard-gradle:7.1.1', snakeyaml : 'org.yaml:snakeyaml:1.32:android', - smali : 'org.smali:smali:2.5.2', + smali : 'com.github.iBotPeaches.smali:smali:403e90375e', xmlpull : 'xpp3:xpp3:1.1.4c', xmlunit : 'xmlunit:xmlunit:1.6', ] } repositories { - mavenCentral() gradlePluginPortal() } dependencies { @@ -80,6 +79,14 @@ allprojects { "licenseMain", "licenseTest" ] + + repositories { + mavenCentral() + + // Obtain baksmali/smali from source builds - https://github.com/iBotPeaches/smali + // Remove when official smali releases come out again. + maven { url 'https://jitpack.io' } + } } tasks.withType(JavaCompile).configureEach { @@ -136,10 +143,6 @@ task snapshot { subprojects { apply plugin: 'java' - repositories { - mavenCentral() - } - test { testLogging { exceptionFormat = 'full' From c7733c3773f5f69cf3732dbbc094b3d0e23f6bb1 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 24 Nov 2022 06:50:50 -0500 Subject: [PATCH 15/18] build: filter jitpack to only com.github.ibotpeaches.* (#2953) --- build.gradle | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d7b24581..4d3d6b2d 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,12 @@ allprojects { // Obtain baksmali/smali from source builds - https://github.com/iBotPeaches/smali // Remove when official smali releases come out again. - maven { url 'https://jitpack.io' } + maven { + url 'https://jitpack.io' + content { + includeGroup('com.github.iBotPeaches.smali') + } + } } } From 687d2012850584eb2fafcbfaab3811f5fe38898b Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 24 Nov 2022 07:10:30 -0500 Subject: [PATCH 16/18] build: support jdk17 (#2952) --- .github/workflows/build.yml | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4efb8672..c4d70c3e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: fail-fast: true matrix: os: [ ubuntu-latest, macOS-latest, windows-latest ] - java: [ 8, 9, 10, 11, 12, 13, 14, 15, 16 ] + java: [ 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 ] steps: - uses: actions/checkout@v3 - uses: actions/setup-java@v3 diff --git a/build.gradle b/build.gradle index 4d3d6b2d..7e9b74b2 100644 --- a/build.gradle +++ b/build.gradle @@ -25,7 +25,7 @@ buildscript { commons_text : 'org.apache.commons:commons-text:1.10.0', guava : 'com.google.guava:guava:31.0.1-jre', junit : 'junit:junit:4.13.2', - proguard_gradle: 'com.guardsquare:proguard-gradle:7.1.1', + proguard_gradle: 'com.guardsquare:proguard-gradle:7.3.0', snakeyaml : 'org.yaml:snakeyaml:1.32:android', smali : 'com.github.iBotPeaches.smali:smali:403e90375e', xmlpull : 'xpp3:xpp3:1.1.4c', From 32043a2d6e8bda448ce41a79f3b02471f04481e3 Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 24 Nov 2022 07:16:21 -0500 Subject: [PATCH 17/18] build: rename 2.6.2 to 2.7.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7e9b74b2..8c7f2d64 100644 --- a/build.gradle +++ b/build.gradle @@ -44,7 +44,7 @@ buildscript { apply from: 'gradle/functions.gradle' -version = '2.6.2' +version = '2.7.0' def suffix = 'SNAPSHOT' defaultTasks 'build', 'shadowJar', 'proguard' From fedae0b6deeebb369fc9dbd7572b93af7b86fc3a Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 24 Nov 2022 07:16:52 -0500 Subject: [PATCH 18/18] build: version bump (2.7.0) --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8c7f2d64..bae3ff85 100644 --- a/build.gradle +++ b/build.gradle @@ -45,7 +45,7 @@ buildscript { apply from: 'gradle/functions.gradle' version = '2.7.0' -def suffix = 'SNAPSHOT' +def suffix = '' defaultTasks 'build', 'shadowJar', 'proguard'