diff --git a/brut.apktool/apktool-cli/build.gradle b/brut.apktool/apktool-cli/build.gradle index c8ea405d..5d8a7dd3 100644 --- a/brut.apktool/apktool-cli/build.gradle +++ b/brut.apktool/apktool-cli/build.gradle @@ -89,7 +89,6 @@ tasks.register('proguard', ProGuardTask) { dontwarn 'javax.xml.xpath.**' dontnote '**' // between Java 1.8 and 1.9, the signature of `flip()` changed, which trips up proguard. - dontwarn 'org.yaml.snakeyaml.scanner.ScannerImpl' def outPath = jar.getDestinationDirectory().getAsFile().get().toString() def extension = jar.archiveExtension.get().toString() diff --git a/brut.apktool/apktool-lib/build.gradle b/brut.apktool/apktool-lib/build.gradle index 080ffb77..dcfa8ac5 100644 --- a/brut.apktool/apktool-lib/build.gradle +++ b/brut.apktool/apktool-lib/build.gradle @@ -39,7 +39,6 @@ dependencies { implementation depends.baksmali implementation depends.smali - implementation depends.snakeyaml implementation depends.xmlpull implementation depends.guava implementation depends.commons_lang 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 ba1379c6..1d9417de 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 @@ -165,7 +165,7 @@ public class ApkDecoder { copyRawFiles(outDir); copyUnknownFiles(apkInfo, outDir); - Collection mUncompressedFiles = new ArrayList<>(); + List mUncompressedFiles = new ArrayList<>(); recordUncompressedFiles(apkInfo, resourcesDecoder.getResFileMapping(), mUncompressedFiles); copyOriginalFiles(outDir); writeApkInfo(apkInfo, outDir); @@ -220,11 +220,7 @@ public class ApkDecoder { } private void writeApkInfo(ApkInfo apkInfo, File outDir) throws AndrolibException { - try { - apkInfo.save(new File(outDir, "apktool.yml")); - } catch (IOException ex) { - throw new AndrolibException(ex); - } + apkInfo.save(new File(outDir, "apktool.yml")); } private void copyManifestRaw(File outDir) @@ -376,7 +372,7 @@ public class ApkDecoder { private void recordUncompressedFiles(ApkInfo apkInfo, Map resFileMapping, - Collection uncompressedFilesOrExts) + List uncompressedFilesOrExts) throws AndrolibException { try { Directory unk = mApkFile.getDirectory(); diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java index 4ec70c23..0d674ab0 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ApkInfo.java @@ -21,18 +21,14 @@ import brut.androlib.exceptions.AndrolibException; import brut.androlib.res.data.ResConfigFlags; import brut.directory.DirectoryException; import brut.directory.FileDirectory; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.introspector.PropertyUtils; import java.io.*; -import java.nio.charset.StandardCharsets; -import java.util.Collection; +import java.util.ArrayList; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; -public class ApkInfo { +public class ApkInfo implements YamlSerializable { public String version; private String apkFileName; @@ -45,7 +41,7 @@ public class ApkInfo { public boolean sharedLibrary; public boolean sparseResources; public Map unknownFiles; - public Collection doNotCompress; + public List doNotCompress; /** @deprecated use {@link #resourcesAreCompressed} */ public boolean compressionType; @@ -54,26 +50,6 @@ public class ApkInfo { this.version = ApktoolProperties.getVersion(); } - private static Yaml getYaml() { - DumperOptions dumpOptions = new DumperOptions(); - dumpOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - - EscapedStringRepresenter representer = new EscapedStringRepresenter(); - PropertyUtils propertyUtils = representer.getPropertyUtils(); - propertyUtils.setSkipMissingProperties(true); - - LoaderOptions loaderOptions = new LoaderOptions(); - loaderOptions.setCodePointLimit(10 * 1024 * 1024); // 10mb - - return new Yaml(new ClassSafeConstructor(), representer, dumpOptions, loaderOptions); - } - - public void save(Writer output) { - DumperOptions options = new DumperOptions(); - options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - getYaml().dump(this, output); - } - public String checkTargetSdkVersionBounds() { int target = mapSdkShorthandToVersion(getTargetSdkVersion()); @@ -157,28 +133,111 @@ public class ApkInfo { } } - public void save(File file) throws IOException { - try( - FileOutputStream fos = new FileOutputStream(file); - OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8); - Writer writer = new BufferedWriter(outputStreamWriter) + public void save(File file) throws AndrolibException { + try ( + YamlWriter writer = new YamlWriter(new FileOutputStream(file)); ) { - save(writer); + write(writer); + } catch (FileNotFoundException e) { + throw new AndrolibException("File not found"); + } catch (Exception e) { + throw new AndrolibException(e); } } - public static ApkInfo load(InputStream is) { - return getYaml().loadAs(is, ApkInfo.class); + public static ApkInfo load(InputStream is) throws AndrolibException { + // return getYaml().loadAs(is, ApkInfo.class); + YamlReader reader = new YamlReader(is); + ApkInfo apkInfo = new ApkInfo(); + reader.readRoot(apkInfo); + return apkInfo; } public static ApkInfo load(File appDir) throws AndrolibException { try( - InputStream in = new FileDirectory(appDir).getFileInput("apktool.yml") + InputStream in = new FileDirectory(appDir).getFileInput("apktool.yml"); ) { return ApkInfo.load(in); } catch (DirectoryException | IOException ex) { throw new AndrolibException(ex); } } + + @Override + public void readItem(YamlReader reader) throws AndrolibException { + YamlLine line = reader.getLine(); + switch (line.getKey()) { + case "version": { + this.version = line.getValue(); + break; + } + case "apkFileName": { + this.apkFileName = line.getValue(); + break; + } + case "isFrameworkApk": { + this.isFrameworkApk = line.getValueBool(); + break; + } + case "usesFramework": { + this.usesFramework = new UsesFramework(); + reader.readObject(usesFramework); + break; + } + case "sdkInfo": { + reader.readMap(sdkInfo); + break; + } + case "packageInfo": { + this.packageInfo = new PackageInfo(); + reader.readObject(packageInfo); + break; + } + case "versionInfo": { + this.versionInfo = new VersionInfo(); + reader.readObject(versionInfo); + break; + } + case "compressionType": + case "resourcesAreCompressed": { + this.resourcesAreCompressed = line.getValueBool(); + break; + } + case "sharedLibrary": { + this.sharedLibrary = line.getValueBool(); + break; + } + case "sparseResources": { + this.sparseResources = line.getValueBool(); + break; + } + case "unknownFiles": { + this.unknownFiles = new LinkedHashMap<>(); + reader.readMap(unknownFiles); + break; + } + case "doNotCompress": { + this.doNotCompress = new ArrayList<>(); + reader.readStringList(doNotCompress); + break; + } + } + } + + @Override + public void write(YamlWriter writer) { + writer.writeString("version", version); + writer.writeString("apkFileName", apkFileName); + writer.writeBool("isFrameworkApk", isFrameworkApk); + writer.writeObject("usesFramework", usesFramework); + writer.writeStringMap("sdkInfo", sdkInfo); + writer.writeObject("packageInfo", packageInfo); + writer.writeObject("versionInfo", versionInfo); + writer.writeBool("resourcesAreCompressed", resourcesAreCompressed); + writer.writeBool("sharedLibrary", sharedLibrary); + writer.writeBool("sparseResources", sparseResources); + writer.writeStringMap("unknownFiles", unknownFiles); + writer.writeList("doNotCompress", doNotCompress); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ClassSafeConstructor.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ClassSafeConstructor.java deleted file mode 100644 index d1849ec0..00000000 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/ClassSafeConstructor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * 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 - * - * https://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.apk; - -import org.yaml.snakeyaml.constructor.AbstractConstruct; -import org.yaml.snakeyaml.constructor.Constructor; -import org.yaml.snakeyaml.error.YAMLException; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.nodes.ScalarNode; -import org.yaml.snakeyaml.nodes.Tag; -import java.util.ArrayList; -import java.util.List; - -public class ClassSafeConstructor extends Constructor { - protected final List> allowableClasses = new ArrayList<>(); - - public ClassSafeConstructor() { - super(new LoaderOptions()); - this.yamlConstructors.put(Tag.STR, new ConstructStringEx()); - - this.allowableClasses.add(ApkInfo.class); - this.allowableClasses.add(PackageInfo.class); - this.allowableClasses.add(UsesFramework.class); - this.allowableClasses.add(VersionInfo.class); - } - - protected Object newInstance(Node node) { - if (this.yamlConstructors.containsKey(node.getTag()) || this.allowableClasses.contains(node.getType())) { - return super.newInstance(node); - } - throw new YAMLException("Invalid Class attempting to be constructed: " + node.getTag()); - } - - protected Object finalizeConstruction(Node node, Object data) { - if (this.yamlConstructors.containsKey(node.getTag()) || this.allowableClasses.contains(node.getType())) { - return super.finalizeConstruction(node, data); - } - - return this.newInstance(node); - } - - private class ConstructStringEx extends AbstractConstruct { - public Object construct(Node node) { - String val = constructScalar((ScalarNode) node); - return YamlStringEscapeUtils.unescapeString(val); - } - } -} diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/PackageInfo.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/PackageInfo.java index 364a9afc..3ba489a8 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/PackageInfo.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/PackageInfo.java @@ -16,7 +16,31 @@ */ package brut.androlib.apk; -public class PackageInfo { +import brut.androlib.exceptions.AndrolibException; + +public class PackageInfo implements YamlSerializable { public String forcedPackageId; public String renameManifestPackage; + + @Override + public void readItem(YamlReader reader) throws AndrolibException { + YamlLine line = reader.getLine(); + switch (line.getKey()) { + case "forcedPackageId": { + forcedPackageId = line.getValue(); + break; + } + case "renameManifestPackage": { + renameManifestPackage = line.getValue(); + break; + } + } + } + + @Override + public void write(YamlWriter writer) { + writer.writeString("forcedPackageId", forcedPackageId); + writer.writeString("renameManifestPackage", renameManifestPackage); + } + } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/UsesFramework.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/UsesFramework.java index c3bfb2da..a8582b03 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/UsesFramework.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/UsesFramework.java @@ -16,9 +16,34 @@ */ package brut.androlib.apk; +import brut.androlib.exceptions.AndrolibException; + +import java.util.ArrayList; import java.util.List; -public class UsesFramework { +public class UsesFramework implements YamlSerializable { public List ids; public String tag; + + @Override + public void readItem(YamlReader reader) throws AndrolibException { + YamlLine line = reader.getLine(); + switch (line.getKey()) { + case "ids": { + ids = new ArrayList<>(); + reader.readIntList(ids); + break; + } + case "tag": { + tag = line.getValue(); + break; + } + } + } + + @Override + public void write(YamlWriter writer) { + writer.writeList("ids", ids); + writer.writeString("tag", tag); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java index 3fd488bf..54b6319e 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/VersionInfo.java @@ -16,7 +16,30 @@ */ package brut.androlib.apk; -public class VersionInfo { +import brut.androlib.exceptions.AndrolibException; + +public class VersionInfo implements YamlSerializable { public String versionCode; public String versionName; + + @Override + public void readItem(YamlReader reader) throws AndrolibException { + YamlLine line = reader.getLine(); + switch (line.getKey()) { + case "versionCode": { + versionCode = line.getValue(); + break; + } + case "versionName": { + versionName = line.getValue(); + break; + } + } + } + + @Override + public void write(YamlWriter writer) { + writer.writeString("versionCode", versionCode); + writer.writeString("versionName", versionName); + } } diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlLine.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlLine.java new file mode 100644 index 00000000..f31dd62a --- /dev/null +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlLine.java @@ -0,0 +1,92 @@ +package brut.androlib.apk; + +import java.util.Objects; + +public class YamlLine { + + public int indent = 0; + private String key = ""; + private String value = ""; + public boolean isComment; + public boolean isEmpty; + public boolean hasColon; + public boolean isNull; + public boolean isItem; + + public YamlLine(String line) { + // special end line marker + isNull = Objects.isNull(line); + if (isNull) { + return; + } + isEmpty = line.trim().isEmpty(); + if (isEmpty) { + return; + } + // count indent - space only + for (int i = 0; i < line.length(); i++) { + if (line.charAt(i) == ' ') { + indent++; + } else { + break; + } + } + // remove whitespace + line = line.trim(); + char first = line.charAt(0); + + isComment = first == '#' || first == '!'; + isItem = first == '-'; + if (isComment) { + // for comment fill value + value = line.substring(1).trim(); + } else { + // value line + hasColon = line.contains(":"); + if (isItem) { + // array item line has only the value + value = line.substring(1).trim(); + } else { + // split line to key - value + String[] parts = line.split(":"); + if (parts.length > 0) { + key = parts[0].trim(); + if (parts.length > 1) { + value = parts[1].trim(); + } + } + } + } + } + + public static String unescape(String value) { + return YamlStringEscapeUtils.unescapeString(value); + } + + public String getValue() { + if (value.equals("null")) { + return null; + } + String res = unescape(value); + // remove quotation marks + res = res.replaceAll("^\"|\"$", ""); + res = res.replaceAll("^'|'$", ""); + return res; + } + + public String getKey() { + String res = unescape(key); + // remove quotation marks + res = res.replaceAll("^\"|\"$", ""); + res = res.replaceAll("^'|'$", ""); + return res; + } + + public boolean getValueBool() { + return Objects.equals(value, "true"); + } + + public int getValueInt() { + return Integer.parseInt(value); + } +} diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlReader.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlReader.java new file mode 100644 index 00000000..a75bd8ef --- /dev/null +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlReader.java @@ -0,0 +1,204 @@ +package brut.androlib.apk; + +import brut.androlib.exceptions.AndrolibException; + +import java.io.InputStream; +import java.util.*; + +public class YamlReader { + + private ArrayList mLines; + private int mCurrent = 0; + + public YamlReader(InputStream in) { + mLines = new ArrayList<>(); + mLines.add(new YamlLine(null)); + read(in); + } + + public void pushLine() { + if (mCurrent > 0) { + mCurrent--; + } + } + + public void read(InputStream in) { + Scanner scanner = new Scanner(in); + mLines = new ArrayList<>(); + while (scanner.hasNextLine()) { + mLines.add(new YamlLine(scanner.nextLine())); + } + mLines.add(new YamlLine(null)); + } + + public YamlLine getLine() { + return mLines.get(mCurrent); + } + + public int getIndent() { + return getLine().indent; + } + + public boolean isEnd() { + return getLine().isNull; + } + + public boolean isCommentOrEmpty() { + YamlLine line = getLine(); + return line.isEmpty || line.isComment; + } + + public void skipInsignificant() { + if (isEnd()) { + return; + } + while (isCommentOrEmpty()) { + mCurrent++; + if (isEnd()) { + break; + } + } + } + + public boolean nextLine() { + if (isEnd()) { + return false; + } + while (true) { + mCurrent++; + if (isCommentOrEmpty()) { + continue; + } + return !isEnd(); + } + } + + interface Checker { + boolean check(YamlLine line); + } + + interface Updater { + void update(T items, YamlReader reader) throws AndrolibException; + } + + /** + * Read root object from start to end + */ + public void readRoot(T obj) throws AndrolibException { + if (isEnd()) { + return; + } + int objIndent = 0; + skipInsignificant(); + while (true) { + if (isEnd()) { + return; + } + YamlLine line = getLine(); + // skip don't checked line or lines with other indent + if (objIndent != line.indent || !line.hasColon) { + nextLine(); + continue; + } + obj.readItem(this); + nextLine(); + } + } + + /** + * Read object. Reader stand on the object name. + * The object data should be placed on the next line + * and have indent. + */ + public void readObject(T obj, + Checker check, + Updater updater) throws AndrolibException { + if (isEnd()) { + return; + } + int prevIndent = getIndent(); + // detect indent for the object data + nextLine(); + YamlLine line = getLine(); + int objIndent = line.indent; + // object data must have indent + // otherwise stop reading + if (objIndent <= prevIndent || !check.check(line)) { + pushLine(); + return; + } + updater.update(obj, this); + while (nextLine()) { + if (isEnd()) { + return; + } + line = getLine(); + if (objIndent != line.indent || !check.check(line)) { + pushLine(); + return; + } + updater.update(obj, this); + } + } + + void readObject(T obj) throws AndrolibException { + readObject(obj, + line -> line.hasColon, + YamlSerializable::readItem); + } + + /** + * Read list. Reader stand on the object name. + * The list data should be placed on the next line. + * Data should have same indent. May by same with name. + */ + public void readList(List list, + Updater> updater) throws AndrolibException { + if (isEnd()) { + return; + } + int listIndent = getIndent(); + nextLine(); + int dataIndent = getIndent(); + while (true) { + if (isEnd()) { + return; + } + // check incorrect data indent + if (dataIndent < listIndent) { + pushLine(); + return; + } + YamlLine line = getLine(); + if (dataIndent != line.indent || !line.isItem) { + pushLine(); + return; + } + updater.update(list, this); + nextLine(); + } + } + + public void readStringList(List list) throws AndrolibException { + readList(list, + (items, reader) -> { + items.add(reader.getLine().getValue()); + }); + }; + + public void readIntList(List list) throws AndrolibException { + readList(list, + (items, reader) -> { + items.add(reader.getLine().getValueInt()); + }); + }; + + public void readMap(Map map) throws AndrolibException { + readObject(map, + line -> line.hasColon, + (items, reader) -> { + YamlLine line = reader.getLine(); + items.put(line.getKey(), line.getValue()); + }); + }; +} diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlSerializable.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlSerializable.java new file mode 100644 index 00000000..2ff10760 --- /dev/null +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlSerializable.java @@ -0,0 +1,8 @@ +package brut.androlib.apk; + +import brut.androlib.exceptions.AndrolibException; + +public interface YamlSerializable { + void readItem(YamlReader reader) throws AndrolibException; + void write(YamlWriter writer); +} diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlWriter.java b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlWriter.java new file mode 100644 index 00000000..6750212b --- /dev/null +++ b/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/YamlWriter.java @@ -0,0 +1,105 @@ +package brut.androlib.apk; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.*; + +public class YamlWriter implements Closeable { + + private int mIndent = 0; + private final PrintWriter mWriter; + private final String QUOTE = "'"; + + public YamlWriter(OutputStream out) { + mWriter = new PrintWriter(new BufferedWriter( + new OutputStreamWriter(out, StandardCharsets.UTF_8))); + } + + @Override + public void close() throws IOException { + mWriter.close(); + } + + public String getIndentString() { + // for java 11 + // return " ".repeat(mIndent); + // for java 8 + return String.join("", Collections.nCopies(mIndent, " ")); + } + + public static String escape(String value) { + return YamlStringEscapeUtils.escapeString(value); + } + + public void nextIndent() { + mIndent += 2; + } + + public void prevIndent() { + if (mIndent != 0) { + mIndent -= 2; + } + } + + public void writeIndent() { + mWriter.print(getIndentString()); + } + + public void writeBool(String key, boolean value) { + writeIndent(); + String val = value ? "true": "false"; + mWriter.println(escape(key) + ": " + val); + } + + public void writeString(String key, String value, boolean quoted) { + writeIndent(); + if (Objects.isNull(value)) { + mWriter.println(escape(key) + ": null"); + } else { + if (quoted) { + value = QUOTE + value + QUOTE; + } + mWriter.println(escape(key) + ": " + escape(value)); + } + } + + public void writeString(String key, String value) { + writeString(key, value, false); + } + + public void writeList(String key, List list) { + if (Objects.isNull(list)) { + return; + } + writeIndent(); + mWriter.println(escape(key) + ":"); + for (T item: list) { + writeIndent(); + mWriter.println("- " + item); + } + } + + public void writeStringMap(String key, Map map) { + if (Objects.isNull(map)) { + return; + } + writeIndent(); + mWriter.println(escape(key) + ":"); + nextIndent(); + for (String mapKey: map.keySet()) { + writeString(mapKey, map.get(mapKey)); + } + prevIndent(); + } + + public void writeObject(String key, T obj) { + if (Objects.isNull(obj)) { + return; + } + writeIndent(); + mWriter.println(escape(key) + ":"); + nextIndent(); + obj.write(this); + prevIndent(); + } +} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoReaderTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoReaderTest.java new file mode 100644 index 00000000..419b7a3d --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoReaderTest.java @@ -0,0 +1,132 @@ +package brut.androlib.apk; + +import brut.androlib.exceptions.AndrolibException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class ApkInfoReaderTest { + + private void checkStandard(ApkInfo apkInfo) { + assertEquals("standard.apk", apkInfo.getApkFileName()); + assertFalse(apkInfo.resourcesAreCompressed); + assertEquals(1, apkInfo.doNotCompress.size()); + assertEquals("resources.arsc", apkInfo.doNotCompress.iterator().next()); + assertFalse(apkInfo.isFrameworkApk); + assertNotNull(apkInfo.packageInfo); + assertEquals("127", apkInfo.packageInfo.forcedPackageId); + assertNull(apkInfo.packageInfo.renameManifestPackage); + assertNotNull(apkInfo.getSdkInfo()); + assertEquals(2, apkInfo.getSdkInfo().size()); + assertEquals("25", apkInfo.getSdkInfo().get("minSdkVersion")); + assertEquals("30", apkInfo.getSdkInfo().get("targetSdkVersion")); + assertFalse(apkInfo.sharedLibrary); + assertFalse(apkInfo.sparseResources); + assertNotNull(apkInfo.usesFramework); + assertNotNull(apkInfo.usesFramework.ids); + assertEquals(1, apkInfo.usesFramework.ids.size()); + assertEquals(1, (long)apkInfo.usesFramework.ids.get(0)); + assertNull(apkInfo.usesFramework.tag); + assertNotNull(apkInfo.versionInfo); + assertNull(apkInfo.versionInfo.versionCode); + assertNull(apkInfo.versionInfo.versionName); + } + + @Test + public void testStandard() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/standard.yml")); + checkStandard(apkInfo); + assertEquals("2.8.1", apkInfo.version); + } + + @Test + public void testUnknownFields() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/unknown_fields.yml")); + checkStandard(apkInfo); + assertEquals("2.8.1", apkInfo.version); + } + + @Test + public void testSkipIncorrectIndent() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/skip_incorrect_indent.yml")); + checkStandard(apkInfo); + assertNotEquals("2.0.0", apkInfo.version); + } + + @Test + public void testFirstIncorrectIndent() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/first_incorrect_indent.yml")); + checkStandard(apkInfo); + assertNotEquals("2.0.0", apkInfo.version); + } + + @Test + public void testUnknownFiles() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/unknown_files.yml")); + assertEquals("2.0.0", apkInfo.version); + assertEquals("testapp.apk", apkInfo.getApkFileName()); + assertFalse(apkInfo.isFrameworkApk); + assertNotNull(apkInfo.usesFramework); + assertEquals(1, apkInfo.usesFramework.ids.size()); + assertEquals(1, (long)apkInfo.usesFramework.ids.get(0)); + assertNotNull(apkInfo.packageInfo); + assertEquals("127", apkInfo.packageInfo.forcedPackageId); + assertNotNull(apkInfo.versionInfo); + assertEquals("1", apkInfo.versionInfo.versionCode); + assertEquals("1.0", apkInfo.versionInfo.versionName); + assertFalse(apkInfo.resourcesAreCompressed); + assertNotNull(apkInfo.doNotCompress); + assertEquals(4, apkInfo.doNotCompress.size()); + assertEquals("assets/0byte_file.jpg", apkInfo.doNotCompress.get(0)); + assertEquals("arsc", apkInfo.doNotCompress.get(1)); + assertEquals("png", apkInfo.doNotCompress.get(2)); + assertEquals("mp3", apkInfo.doNotCompress.get(3)); + assertNotNull(apkInfo.unknownFiles); + assertEquals(7, apkInfo.unknownFiles.size()); + assertEquals("8", apkInfo.unknownFiles.get("AssetBundle/assets/a.txt")); + assertEquals("8", apkInfo.unknownFiles.get("AssetBundle/b.txt")); + assertEquals("8", apkInfo.unknownFiles.get("hidden.file")); + assertEquals("8", apkInfo.unknownFiles.get("non\u007Fprintable.file")); + assertEquals("0", apkInfo.unknownFiles.get("stored.file")); + assertEquals("8", apkInfo.unknownFiles.get("unk_folder/unknown_file")); + assertEquals("8", apkInfo.unknownFiles.get("lib_bug603/bug603")); + } + + @Test + public void testUlist_with_indent() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/list_with_indent.yml")); + assertEquals("2.8.0", apkInfo.version); + assertEquals("basic.apk", apkInfo.getApkFileName()); + assertFalse(apkInfo.isFrameworkApk); + assertNotNull(apkInfo.usesFramework); + assertEquals(1, apkInfo.usesFramework.ids.size()); + assertEquals(1, (long)apkInfo.usesFramework.ids.get(0)); + assertEquals("tag", apkInfo.usesFramework.tag); + assertNotNull(apkInfo.packageInfo); + assertEquals("127", apkInfo.packageInfo.forcedPackageId); + assertEquals("com.test.basic", apkInfo.packageInfo.renameManifestPackage); + assertNotNull(apkInfo.getSdkInfo()); + assertEquals(3, apkInfo.getSdkInfo().size()); + assertEquals("4", apkInfo.getSdkInfo().get("minSdkVersion")); + assertEquals("30", apkInfo.getSdkInfo().get("maxSdkVersion")); + assertEquals("22", apkInfo.getSdkInfo().get("targetSdkVersion")); + assertFalse(apkInfo.sharedLibrary); + assertTrue(apkInfo.sparseResources); + assertNotNull(apkInfo.unknownFiles); + assertEquals(1, apkInfo.unknownFiles.size()); + assertEquals("1", apkInfo.unknownFiles.get("hidden.file")); + assertNotNull(apkInfo.versionInfo); + assertEquals("71", apkInfo.versionInfo.versionCode); + assertEquals("1.0.70", apkInfo.versionInfo.versionName); + assertNotNull(apkInfo.doNotCompress); + assertEquals(2, apkInfo.doNotCompress.size()); + assertEquals("resources.arsc", apkInfo.doNotCompress.get(0)); + assertEquals("png", apkInfo.doNotCompress.get(1)); + } +} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoSerializationTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoSerializationTest.java new file mode 100644 index 00000000..9c9b9739 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ApkInfoSerializationTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 Ryszard Wiśniewski + * Copyright (C) 2010 Connor Tumbleson + * + * 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 + * + * https://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.apk; + +import brut.androlib.exceptions.AndrolibException; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; + +import java.io.*; + +import static org.junit.Assert.*; + +public class ApkInfoSerializationTest { + + @Rule + public TemporaryFolder folder = new TemporaryFolder(); + + @Test + public void checkApkInfoSerialization() throws IOException, AndrolibException { + ApkInfo control = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/unknown_files.yml")); + check(control); + + File savedApkInfo = folder.newFile( "saved.yml" ); + control.save(savedApkInfo); + try ( + FileInputStream fis = new FileInputStream(savedApkInfo); + ) { + ApkInfo saved = ApkInfo.load(fis); + check(saved); + } + } + + private void check(ApkInfo apkInfo) { + assertEquals("2.0.0", apkInfo.version); + assertEquals("testapp.apk", apkInfo.getApkFileName()); + assertFalse(apkInfo.isFrameworkApk); + assertNotNull(apkInfo.usesFramework); + assertEquals(1, apkInfo.usesFramework.ids.size()); + assertEquals(1, (long)apkInfo.usesFramework.ids.get(0)); + assertNotNull(apkInfo.packageInfo); + assertEquals("127", apkInfo.packageInfo.forcedPackageId); + assertNotNull(apkInfo.versionInfo); + assertEquals("1", apkInfo.versionInfo.versionCode); + assertEquals("1.0", apkInfo.versionInfo.versionName); + assertFalse(apkInfo.resourcesAreCompressed); + assertNotNull(apkInfo.doNotCompress); + assertEquals(4, apkInfo.doNotCompress.size()); + assertEquals("assets/0byte_file.jpg", apkInfo.doNotCompress.get(0)); + assertEquals("arsc", apkInfo.doNotCompress.get(1)); + assertEquals("png", apkInfo.doNotCompress.get(2)); + assertEquals("mp3", apkInfo.doNotCompress.get(3)); + assertNotNull(apkInfo.unknownFiles); + assertEquals(7, apkInfo.unknownFiles.size()); + assertEquals("8", apkInfo.unknownFiles.get("AssetBundle/assets/a.txt")); + assertEquals("8", apkInfo.unknownFiles.get("AssetBundle/b.txt")); + assertEquals("8", apkInfo.unknownFiles.get("hidden.file")); + assertEquals("8", apkInfo.unknownFiles.get("non\u007Fprintable.file")); + assertEquals("0", apkInfo.unknownFiles.get("stored.file")); + assertEquals("8", apkInfo.unknownFiles.get("unk_folder/unknown_file")); + assertEquals("8", apkInfo.unknownFiles.get("lib_bug603/bug603")); + } +} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ConsistentPropertyTest.java similarity index 70% rename from brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java rename to brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ConsistentPropertyTest.java index 618b5ba7..cca483bb 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/ConsistentPropertyTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/ConsistentPropertyTest.java @@ -14,35 +14,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package brut.androlib.yaml; +package brut.androlib.apk; -import brut.androlib.BaseTest; -import brut.androlib.TestUtils; -import brut.androlib.apk.ApkInfo; -import brut.common.BrutException; -import brut.directory.ExtFile; -import brut.util.OS; -import org.junit.BeforeClass; +import brut.androlib.exceptions.AndrolibException; import org.junit.Test; -import java.io.File; import static org.junit.Assert.*; -public class ConsistentPropertyTest extends BaseTest { - - @BeforeClass - public static void beforeClass() throws Exception { - TestUtils.cleanFrameworkFile(); - - sTmpDir = new ExtFile(OS.createTempDirectory()); - sTestNewDir = new ExtFile(sTmpDir, "yaml"); - LOGGER.info("Unpacking yaml files..."); - TestUtils.copyResourceDir(ConsistentPropertyTest.class, "decode/yaml/", sTestNewDir); - } +public class ConsistentPropertyTest { @Test - public void testAssertingAllKnownApkInfoProperties() throws BrutException { - ApkInfo apkInfo = ApkInfo.load(new File(sTestNewDir, "basic")); + public void testAssertingAllKnownApkInfoProperties() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/basic.yml")); assertEquals("2.8.0", apkInfo.version); assertEquals("basic.apk", apkInfo.getApkFileName()); diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/DoNotCompressHieroglyphTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/DoNotCompressHieroglyphTest.java new file mode 100644 index 00000000..ff116eaf --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/DoNotCompressHieroglyphTest.java @@ -0,0 +1,20 @@ +package brut.androlib.apk; + +import brut.androlib.exceptions.AndrolibException; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class DoNotCompressHieroglyphTest { + + @Test + public void testHieroglyph() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/donotcompress_with_hieroglyph.yml")); + assertEquals("2.0.0", apkInfo.version); + assertEquals("testapp.apk", apkInfo.getApkFileName()); + assertEquals(2, apkInfo.doNotCompress.size()); + assertEquals("assets/AllAssetBundles/Andriod/tx_1001_冰原1", apkInfo.doNotCompress.get(0)); + assertEquals("assets/AllAssetBundles/Andriod/tx_1001_冰原1.manifest", apkInfo.doNotCompress.get(1)); + } +} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/InvalidSdkBoundingTest.java similarity index 95% rename from brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java rename to brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/InvalidSdkBoundingTest.java index f9130f44..d3f4c850 100644 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/androlib/InvalidSdkBoundingTest.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/InvalidSdkBoundingTest.java @@ -14,17 +14,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package brut.androlib.androlib; +package brut.androlib.apk; -import brut.androlib.BaseTest; -import brut.androlib.apk.ApkInfo; import org.junit.Test; import java.util.LinkedHashMap; import java.util.Map; + import static org.junit.Assert.assertEquals; -public class InvalidSdkBoundingTest extends BaseTest { +public class InvalidSdkBoundingTest { @Test public void checkIfInvalidValuesPass() { diff --git a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/EscapedStringRepresenter.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/MaliciousYamlTest.java similarity index 51% rename from brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/EscapedStringRepresenter.java rename to brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/MaliciousYamlTest.java index c2b13f9e..66a53c6a 100644 --- a/brut.apktool/apktool-lib/src/main/java/brut/androlib/apk/EscapedStringRepresenter.java +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/MaliciousYamlTest.java @@ -16,23 +16,17 @@ */ package brut.androlib.apk; -import org.yaml.snakeyaml.DumperOptions; -import org.yaml.snakeyaml.nodes.Node; -import org.yaml.snakeyaml.representer.Representer; +import brut.androlib.exceptions.AndrolibException; +import org.junit.Test; -public class EscapedStringRepresenter extends Representer { - public EscapedStringRepresenter() { - super(new DumperOptions()); - RepresentStringEx representStringEx = new RepresentStringEx(); - multiRepresenters.put(String.class, representStringEx); - representers.put(String.class, representStringEx); - } +import static org.junit.Assert.assertEquals; - private class RepresentStringEx extends RepresentString { +public class MaliciousYamlTest { - @Override - public Node representData(Object data) { - return super.representData(YamlStringEscapeUtils.escapeString(data.toString())); - } + @Test + public void testMaliciousYaml() throws AndrolibException { + ApkInfo apkInfo = ApkInfo.load( + this.getClass().getResourceAsStream("/apk/cve20220476.yml")); + assertEquals("2.6.1-ddc4bb-SNAPSHOT", apkInfo.version); } } diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/YamlLineTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/YamlLineTest.java new file mode 100644 index 00000000..1e261a17 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/java/brut/androlib/apk/YamlLineTest.java @@ -0,0 +1,104 @@ +package brut.androlib.apk; + +import org.junit.Test; + +import static org.junit.Assert.*; + +public class YamlLineTest { + + @Test + public void testEmptyLine() { + YamlLine line = new YamlLine(""); + assertEquals(0, line.indent); + assertTrue(line.isEmpty); + + line = new YamlLine(" "); + assertEquals(0, line.indent); + assertTrue(line.isEmpty); + } + + @Test + public void testComment() { + YamlLine line = new YamlLine("!ApkInfo.class"); + assertTrue(line.isComment); + + line = new YamlLine("# This is comment"); + assertEquals(0, line.indent); + assertTrue(line.isComment); + assertEquals("", line.getKey()); + assertEquals("This is comment", line.getValue()); + + line = new YamlLine(" # This is comment"); + assertEquals(2, line.indent); + assertTrue(line.isComment); + assertEquals("", line.getKey()); + assertEquals("This is comment", line.getValue()); + } + + @Test + public void testKeyLine() { + YamlLine line = new YamlLine("name:"); + assertFalse(line.isComment); + assertEquals(0, line.indent); + assertEquals("name", line.getKey()); + assertEquals("", line.getValue()); + + line = new YamlLine(" name:"); + assertFalse(line.isComment); + assertEquals(2, line.indent); + assertEquals("name", line.getKey()); + assertEquals("", line.getValue()); + + line = new YamlLine(":value"); + assertFalse(line.isComment); + assertEquals(0, line.indent); + assertEquals("", line.getKey()); + assertEquals("value", line.getValue()); + + line = new YamlLine(" : value "); + assertFalse(line.isComment); + assertEquals(2, line.indent); + assertEquals("", line.getKey()); + assertEquals("value", line.getValue()); + + line = new YamlLine("name : value "); + assertFalse(line.isComment); + assertEquals(0, line.indent); + assertEquals("name", line.getKey()); + assertEquals("value", line.getValue()); + + line = new YamlLine(" name : value "); + assertFalse(line.isComment); + assertEquals(2, line.indent); + assertEquals("name", line.getKey()); + assertEquals("value", line.getValue()); + + line = new YamlLine(" name : value ::"); + assertFalse(line.isComment); + assertEquals(2, line.indent); + assertEquals("name", line.getKey()); + assertEquals("value", line.getValue()); + + // split this gives parts.length = 0!! + line = new YamlLine(":::"); + assertFalse(line.isComment); + assertEquals(0, line.indent); + assertEquals("", line.getKey()); + assertEquals("", line.getValue()); + } + + @Test + public void testItemLine() { + YamlLine line = new YamlLine("- val1"); + assertTrue(line.isItem); + assertEquals(0, line.indent); + assertEquals("", line.getKey()); + assertEquals("val1", line.getValue()); + + line = new YamlLine(" - val1: ff"); + assertTrue(line.isItem); + assertEquals(2, line.indent); + assertEquals("", line.getKey()); + assertEquals("val1: ff", line.getValue()); + } +} diff --git a/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java b/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java deleted file mode 100644 index 314e8d1c..00000000 --- a/brut.apktool/apktool-lib/src/test/java/brut/androlib/yaml/MaliciousYamlTest.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2010 Ryszard Wiśniewski - * Copyright (C) 2010 Connor Tumbleson - * - * 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 - * - * https://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.yaml; - -import brut.androlib.ApkBuilder; -import brut.androlib.BaseTest; -import brut.androlib.TestUtils; -import brut.androlib.Config; -import brut.common.BrutException; -import brut.directory.ExtFile; -import brut.util.OS; -import org.junit.BeforeClass; -import org.junit.Test; -import org.yaml.snakeyaml.constructor.ConstructorException; - -import java.io.File; - -public class MaliciousYamlTest extends BaseTest { - - @BeforeClass - public static void beforeClass() throws Exception { - TestUtils.cleanFrameworkFile(); - - sTmpDir = new ExtFile(OS.createTempDirectory()); - sTestNewDir = new ExtFile(sTmpDir, "cve20220476"); - LOGGER.info("Unpacking cve20220476..."); - TestUtils.copyResourceDir(MaliciousYamlTest.class, "yaml/cve20220476/", sTestNewDir); - } - - @Test(expected = ConstructorException.class) - public void testMaliciousYamlNotLoaded() throws BrutException { - Config config = Config.getDefaultConfig(); - File testApk = new File(sTmpDir, "cve20220476.apk"); - new ApkBuilder(config, sTestNewDir).build(testApk); - } -} diff --git a/brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/apk/basic.yml similarity index 100% rename from brut.apktool/apktool-lib/src/test/resources/decode/yaml/basic/apktool.yml rename to brut.apktool/apktool-lib/src/test/resources/apk/basic.yml diff --git a/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml b/brut.apktool/apktool-lib/src/test/resources/apk/cve20220476.yml similarity index 100% rename from brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/apktool.yml rename to brut.apktool/apktool-lib/src/test/resources/apk/cve20220476.yml diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/donotcompress_with_hieroglyph.yml b/brut.apktool/apktool-lib/src/test/resources/apk/donotcompress_with_hieroglyph.yml new file mode 100644 index 00000000..f3ff13da --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/donotcompress_with_hieroglyph.yml @@ -0,0 +1,6 @@ +version: 2.0.0 +apkFileName: testapp.apk +doNotCompress: +- assets/AllAssetBundles/Andriod/tx_1001_冰原1 +- assets/AllAssetBundles/Andriod/tx_1001_冰原1.manifest + diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/first_incorrect_indent.yml b/brut.apktool/apktool-lib/src/test/resources/apk/first_incorrect_indent.yml new file mode 100644 index 00000000..49e9b669 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/first_incorrect_indent.yml @@ -0,0 +1,22 @@ +!!brut.androlib.meta.MetaInfo + version: 2.0.0 +apkFileName: standard.apk +compressionType: false +doNotCompress: +- resources.arsc +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: null +sdkInfo: + minSdkVersion: '25' + targetSdkVersion: '30' +sharedLibrary: false +sparseResources: false +usesFramework: + ids: + - 1 + tag: null +versionInfo: + versionCode: null + versionName: null diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/list_with_indent.yml b/brut.apktool/apktool-lib/src/test/resources/apk/list_with_indent.yml new file mode 100644 index 00000000..b51612c6 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/list_with_indent.yml @@ -0,0 +1,26 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: basic.apk +compressionType: false +doNotCompress: + - resources.arsc + - png +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: 'com.test.basic' +sdkInfo: + minSdkVersion: '4' + maxSdkVersion: '30' + targetSdkVersion: '22' +sharedLibrary: false +sparseResources: true +unknownFiles: + hidden.file: 1 +usesFramework: + ids: + - 1 + tag: 'tag' +version: 2.8.0 +versionInfo: + versionCode: '71' + versionName: 1.0.70 diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/skip_incorrect_indent.yml b/brut.apktool/apktool-lib/src/test/resources/apk/skip_incorrect_indent.yml new file mode 100644 index 00000000..cfdc2d78 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/skip_incorrect_indent.yml @@ -0,0 +1,22 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: standard.apk + version: 2.0.0 +compressionType: false +doNotCompress: +- resources.arsc +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: null +sdkInfo: + minSdkVersion: '25' + targetSdkVersion: '30' +sharedLibrary: false +sparseResources: false +usesFramework: + ids: + - 1 + tag: null +versionInfo: + versionCode: null + versionName: null diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/standard.yml b/brut.apktool/apktool-lib/src/test/resources/apk/standard.yml new file mode 100644 index 00000000..6aa78ecb --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/standard.yml @@ -0,0 +1,22 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: standard.apk +compressionType: false +doNotCompress: +- resources.arsc +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: null +sdkInfo: + minSdkVersion: '25' + targetSdkVersion: '30' +sharedLibrary: false +sparseResources: false +usesFramework: + ids: + - 1 + tag: null +version: 2.8.1 +versionInfo: + versionCode: null + versionName: null diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/unknown_fields.yml b/brut.apktool/apktool-lib/src/test/resources/apk/unknown_fields.yml new file mode 100644 index 00000000..876e9fca --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/unknown_fields.yml @@ -0,0 +1,25 @@ +!!brut.androlib.meta.MetaInfo +apkFileName: standard.apk +compressionType: false +test: test +doNotCompress: +- resources.arsc +isFrameworkApk: false +packageInfo: + forcedPackageId: '127' + renameManifestPackage: null + test2: test2 +sdkInfo: + minSdkVersion: '25' + targetSdkVersion: '30' +sharedLibrary: false +sparseResources: false +usesFramework: + ids: + - 1 + tag: null + test3: test3 +version: 2.8.1 +versionInfo: + versionCode: null + versionName: null diff --git a/brut.apktool/apktool-lib/src/test/resources/apk/unknown_files.yml b/brut.apktool/apktool-lib/src/test/resources/apk/unknown_files.yml new file mode 100644 index 00000000..8362ef05 --- /dev/null +++ b/brut.apktool/apktool-lib/src/test/resources/apk/unknown_files.yml @@ -0,0 +1,25 @@ +version: 2.0.0 +apkFileName: testapp.apk +isFrameworkApk: false +usesFramework: + ids: + - 1 +packageInfo: + forcedPackageId: '127' +versionInfo: + versionCode: '1' + versionName: '1.0' +compressionType: false +doNotCompress: +- assets/0byte_file.jpg +- arsc +- png +- mp3 +unknownFiles: + AssetBundle/assets/a.txt: '8' + AssetBundle/b.txt: '8' + hidden.file: '8' + non\u007Fprintable.file: '8' + stored.file: '0' + unk_folder/unknown_file: '8' + lib_bug603/bug603: '8' diff --git a/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml b/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml deleted file mode 100644 index 11a1a7a8..00000000 --- a/brut.apktool/apktool-lib/src/test/resources/yaml/cve20220476/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/build.gradle b/build.gradle index 8d8a78fb..35928076 100644 --- a/build.gradle +++ b/build.gradle @@ -26,7 +26,6 @@ buildscript { guava : 'com.google.guava:guava:32.0.1-jre', junit : 'junit:junit:4.13.2', proguard_gradle: 'com.guardsquare:proguard-gradle:7.3.2', - snakeyaml : 'org.yaml:snakeyaml:1.32:android', smali : 'com.android.tools.smali:smali:3.0.3', xmlpull : 'xpp3:xpp3:1.1.4c', xmlunit : 'xmlunit:xmlunit:1.6',