From 87315af36e900b5a87d9b5bc3e5ce7730e4bc20e Mon Sep 17 00:00:00 2001 From: Connor Tumbleson Date: Thu, 28 Apr 2016 08:31:36 -0400 Subject: [PATCH] Remove previous android:debuggable value to allow changing - adds unit test - normalizeNewlines moved to TestUtils --- .../src/main/java/brut/androlib/Androlib.java | 5 +- .../brut/androlib/res/xml/ResXmlPatcher.java | 29 ++++++ .../brut/androlib/DebugTagRetainedTest.java | 90 +++++++++++++++++++ .../brut/androlib/ProviderAttributeTest.java | 8 +- .../test/java/brut/androlib/TestUtils.java | 4 + .../apktool/issue1235/AndroidManifest.xml | 4 + .../brut/apktool/issue1235/apktool.yml | 12 +++ .../apktool/issue1235/res/values/strings.xml | 4 + 8 files changed, 149 insertions(+), 7 deletions(-) create mode 100644 brut.apktool/apktool-lib/src/test/java/brut/androlib/DebugTagRetainedTest.java create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/AndroidManifest.xml create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/apktool.yml create mode 100644 brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/res/values/strings.xml 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 f11ba5d5..0aae3938 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 @@ -409,6 +409,10 @@ public class Androlib { newFiles(APK_RESOURCES_FILENAMES, apkDir))) { LOGGER.info("Building resources..."); + if (apkOptions.debugMode) { + ResXmlPatcher.removeApplicationDebugTag(new File(appDir, "AndroidManifest.xml")); + } + File apkFile = File.createTempFile("APKTOOL", null); apkFile.delete(); @@ -476,7 +480,6 @@ public class Androlib { Directory tmpDir = new ExtFile(apkFile).getDirectory(); tmpDir.copyToDir(apkDir, APK_MANIFEST_FILENAMES); - } return true; } catch (IOException | DirectoryException ex) { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java index e63a83aa..4e989aa1 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/res/xml/ResXmlPatcher.java @@ -40,6 +40,35 @@ import java.io.IOException; * @author Connor Tumbleson */ public final class ResXmlPatcher { + + /** + * Removes "debug" tag from file + * + * @param file AndroidManifest file + * @throws AndrolibException + */ + public static void removeApplicationDebugTag(File file) throws AndrolibException { + if (file.exists()) { + try { + Document doc = loadDocument(file); + Node application = doc.getElementsByTagName("application").item(0); + + // load attr + NamedNodeMap attr = application.getAttributes(); + Node debugAttr = attr.getNamedItem("android:debuggable"); + + // remove application:debuggable + if (debugAttr != null) { + attr.removeNamedItem("android:debuggable"); + } + + saveDocument(file, doc); + + } catch (SAXException | ParserConfigurationException | IOException | TransformerException ignored) { + } + } + } + /** * Any @string reference in a value in AndroidManifest.xml will break on * build, thus preventing the application from installing. This is from a bug/error diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/DebugTagRetainedTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/DebugTagRetainedTest.java new file mode 100644 index 00000000..7cde0856 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/DebugTagRetainedTest.java @@ -0,0 +1,90 @@ +/** + * Copyright 2014 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.androlib; + +import brut.androlib.res.util.ExtFile; +import brut.common.BrutException; +import brut.util.OS; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.logging.Logger; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * @author Connor Tumbleson + */ +public class DebugTagRetainedTest { + + @BeforeClass + public static void beforeClass() throws Exception, BrutException { + TestUtils.cleanFrameworkFile(); + sTmpDir = new ExtFile(OS.createTempDirectory()); + sTestOrigDir = new ExtFile(sTmpDir, "issue1235-orig"); + sTestNewDir = new ExtFile(sTmpDir, "issue1235-new"); + LOGGER.info("Unpacking issue1235..."); + TestUtils.copyResourceDir(BuildAndDecodeJarTest.class, "brut/apktool/issue1235/", sTestOrigDir); + + LOGGER.info("Building issue1235.apk..."); + ApkOptions apkOptions = new ApkOptions(); + apkOptions.debugMode = true; + + File testApk = new File(sTmpDir, "issue1235.apk"); + new Androlib(apkOptions).build(sTestOrigDir, testApk); + + LOGGER.info("Decoding issue1235.apk..."); + ApkDecoder apkDecoder = new ApkDecoder(testApk); + apkDecoder.setOutDir(sTestNewDir); + apkDecoder.decode(); + } + + @AfterClass + public static void afterClass() throws BrutException { + OS.rmdir(sTmpDir); + } + + @Test + public void buildAndDecodeTest() throws BrutException { + assertTrue(sTestNewDir.isDirectory()); + } + + @Test + public void DebugIsTruePriorToBeingFalseTest() throws BrutException, IOException { + String apk = "issue1235-new"; + + String expected = TestUtils.replaceNewlines("\n" + + "\n" + + " " + + ""); + + byte[] encoded = Files.readAllBytes(Paths.get(sTmpDir + File.separator + apk + File.separator + "AndroidManifest.xml")); + String obtained = TestUtils.replaceNewlines(new String(encoded)); + assertEquals(expected, obtained); + } + + private static ExtFile sTmpDir; + private static ExtFile sTestOrigDir; + private static ExtFile sTestNewDir; + + private final static Logger LOGGER = Logger.getLogger(BuildAndDecodeJarTest.class.getName()); +} \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/ProviderAttributeTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/ProviderAttributeTest.java index d8eb7ec8..0d19efef 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/ProviderAttributeTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/ProviderAttributeTest.java @@ -66,7 +66,7 @@ public class ProviderAttributeTest { apkDecoder.setOutDir(new File(sTmpDir + File.separator + apk + ".out.two")); apkDecoder.decode(); - String expected = replaceNewlines("\n" + + String expected = TestUtils.replaceNewlines("\n" + "\n" + " \n" + " \n" + @@ -76,7 +76,7 @@ public class ProviderAttributeTest { byte[] encoded = Files.readAllBytes(Paths.get(sTmpDir + File.separator + apk + ".out.two" + File.separator + "AndroidManifest.xml")); - String obtained = replaceNewlines(new String(encoded)); + String obtained = TestUtils.replaceNewlines(new String(encoded)); assertEquals(expected, obtained); } @@ -84,9 +84,5 @@ public class ProviderAttributeTest { return Files.exists(Paths.get(sTmpDir.getAbsolutePath() + File.separator + filepath)); } - private String replaceNewlines(String value) { - return value.replace("\n", "").replace("\r", ""); - } - private static ExtFile sTmpDir; } diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java index c5a9747d..d62d1d8b 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/TestUtils.java @@ -159,4 +159,8 @@ public abstract class TestUtils { return controlType.equals(testType) && control.getAttribute("name").equals(test.getAttribute("name")); } } + + public static String replaceNewlines(String value) { + return value.replace("\n", "").replace("\r", ""); + } } diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/AndroidManifest.xml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/AndroidManifest.xml new file mode 100644 index 00000000..f770201e --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/apktool.yml new file mode 100644 index 00000000..55bbffe5 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/apktool.yml @@ -0,0 +1,12 @@ +version: 2.0.0 +apkFileName: issue1235.apk +isFrameworkApk: false +usesFramework: + ids: + - 1 +packageInfo: + forced-package-id: '127' +versionInfo: + versionCode: '1' + versionName: '1.0' +compressionType: false \ No newline at end of file diff --git a/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/res/values/strings.xml b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/res/values/strings.xml new file mode 100644 index 00000000..9999efc0 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/brut/apktool/issue1235/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Hello World +