15a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver/* 25a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * Copyright 2016, Google Inc. 35a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * All rights reserved. 45a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * 55a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * Redistribution and use in source and binary forms, with or without 65a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * modification, are permitted provided that the following conditions are 75a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * met: 85a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * 95a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * * Redistributions of source code must retain the above copyright 105a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * notice, this list of conditions and the following disclaimer. 115a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * * Redistributions in binary form must reproduce the above 125a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * copyright notice, this list of conditions and the following disclaimer 135a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * in the documentation and/or other materials provided with the 145a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * distribution. 155a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * * Neither the name of Google Inc. nor the names of its 165a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * contributors may be used to endorse or promote products derived from 175a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * this software without specific prior written permission. 185a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * 195a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver */ 315a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 325a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverpackage org.jf.baksmali; 335a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 345a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.beust.jcommander.JCommander; 355a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.beust.jcommander.Parameter; 365a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.beust.jcommander.Parameters; 379f794030da3ca3c18d7955a78edf0257c7c5dad9Ben Gruverimport com.beust.jcommander.ParametersDelegate; 385a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.beust.jcommander.validators.PositiveInteger; 395a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.google.common.collect.Lists; 405a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport com.google.common.collect.Maps; 415a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport org.jf.dexlib2.util.SyntheticAccessorResolver; 42f66362d0733217d5a98860b1729b669539c1dc26Ben Gruverimport org.jf.util.StringWrapper; 43ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruverimport org.jf.util.jcommander.ExtendedParameter; 44ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruverimport org.jf.util.jcommander.ExtendedParameters; 4599394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruverimport org.xml.sax.SAXException; 465a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 475a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport javax.annotation.Nonnull; 485a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport java.io.File; 4999394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruverimport java.io.IOException; 505a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport java.util.List; 515a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruverimport java.util.Map; 525a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 535a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver@Parameters(commandDescription = "Disassembles a dex file.") 54ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver@ExtendedParameters( 55ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver commandName = "disassemble", 56ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver commandAliases = { "dis", "d" }) 5790cacb9d0d153c06dcf5dd6c4887eeb50c8e93c2Ben Gruverpublic class DisassembleCommand extends DexInputCommand { 585a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 595a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver @Parameter(names = {"-h", "-?", "--help"}, help = true, 605a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "Show usage information for this command.") 615a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean help; 625a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 639f794030da3ca3c18d7955a78edf0257c7c5dad9Ben Gruver @ParametersDelegate 6430bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver protected AnalysisArguments analysisArguments = new AnalysisArguments(); 655a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 6630bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--debug-info", "--di"}, arity = 1, 6730bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver description = "Whether to include debug information in the output (.local, .param, .line, etc.). True " + 6830bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver "by default, use --debug-info=false to disable.") 69ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "boolean") 705a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean debugInfo = true; 715a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 7230bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--code-offsets", "--offsets", "--off"}, 73ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver description = "Add a comment before each instruction with it's code offset within the method.") 745a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean codeOffsets = false; 755a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 7699394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver @Parameter(names = {"--resolve-resources", "--rr"}, arity = 2, 775a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "This will attempt to find any resource id references within the bytecode and add a " + 7899394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver "comment with the name of the resource being referenced. The parameter accepts 2 values:" + 7999394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver "an arbitrary resource prefix and the path to a public.xml file. For example: " + 8099394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver "--resolve-resources android.R framework/res/values/public.xml. This option can be specified " + 8199394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver "multiple times to provide resources from multiple packages.") 8299394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver @ExtendedParameter(argumentNames = {"resource prefix", "public.xml file"}) 835a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private List<String> resourceIdFiles = Lists.newArrayList(); 845a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 855a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver @Parameter(names = {"-j", "--jobs"}, 865a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "The number of threads to use. Defaults to the number of cores available.", 875a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver validateWith = PositiveInteger.class) 88ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "n") 895a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private int jobs = Runtime.getRuntime().availableProcessors(); 905a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 915a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver @Parameter(names = {"-l", "--use-locals"}, 925a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "When disassembling, output the .locals directive with the number of non-parameter " + 935a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "registers instead of the .registers directive with the total number of registers.") 945a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean localsDirective = false; 955a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 9630bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--accessor-comments", "--ac"}, arity = 1, 9730bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver description = "Generate helper comments for synthetic accessors. True by default, use " + 9830bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver "--accessor-comments=false to disable.") 99ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "boolean") 1005a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean accessorComments = true; 1015a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 10230bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--normalize-virtual-methods", "--norm", "--nvm"}, 1035a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "Normalize virtual method references to use the base class where the method is " + 1045a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "originally declared.") 1055a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean normalizeVirtualMethods = false; 1065a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1075a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver @Parameter(names = {"-o", "--output"}, 1085a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "The directory to write the disassembled files to.") 109ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "dir") 1105a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private String outputDir = "out"; 1115a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 11230bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--parameter-registers", "--preg", "--pr"}, arity = 1, 11330bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver description = "Use the pNN syntax for registers that refer to a method parameter on method entry. True " + 11430bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver "by default, use --parameter-registers=false to disable.") 115ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "boolean") 1165a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean parameterRegisters = true; 1175a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 11830bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"-r", "--register-info"}, 1195a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "Add comments before/after each instruction with information about register types. " + 1205a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "The value is a comma-separated list of any of ALL, ALLPRE, ALLPOST, ARGS, DEST, MERGE and " + 1215a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "FULLMERGE. See \"baksmali help register-info\" for more information.") 122ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver @ExtendedParameter(argumentNames = "register info specifier") 1235a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private List<String> registerInfoTypes = Lists.newArrayList(); 1245a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 12530bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--sequential-labels", "--seq", "--sl"}, 1265a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver description = "Create label names using a sequential numbering scheme per label type, rather than " + 1275a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "using the bytecode address.") 1285a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean sequentialLabels = false; 1295a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 13030bdb7fda9aa4cbd088ea053bd909e0bbeca26faBen Gruver @Parameter(names = {"--implicit-references", "--implicit", "--ir"}, 131ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver description = "Use implicit method and field references (without the class name) for methods and " + 1325a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver "fields from the current class.") 1335a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver private boolean implicitReferences = false; 1345a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 13522e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver @Parameter(names = "--classes", 13622e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver description = "A comma separated list of classes. Only disassemble these classes") 13722e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver @ExtendedParameter(argumentNames = "classes") 13822e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver private List<String> classes = null; 13922e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver 140ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver public DisassembleCommand(@Nonnull List<JCommander> commandAncestors) { 141ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver super(commandAncestors); 1425a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1435a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1445a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver public void run() { 1455a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (help || inputList == null || inputList.isEmpty()) { 146ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver usage(); 1475a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver return; 1485a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1495a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1505a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (inputList.size() > 1) { 1515a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.err.println("Too many files specified"); 152ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver usage(); 1535a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver return; 1545a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1555a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 156e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver String input = inputList.get(0); 1578e1afdda32a3c6572e44ccba9150f18627bf834dBen Gruver loadDexFile(input); 1585a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 159f66362d0733217d5a98860b1729b669539c1dc26Ben Gruver if (showDeodexWarning() && dexFile.hasOdexOpcodes()) { 1608a5a6e3fc57adffebd9c9b717af85b66159a1208Ben Gruver StringWrapper.printWrappedString(System.err, 1618a5a6e3fc57adffebd9c9b717af85b66159a1208Ben Gruver "Warning: You are disassembling an odex/oat file without deodexing it. You won't be able to " + 1628a5a6e3fc57adffebd9c9b717af85b66159a1208Ben Gruver "re-assemble the results unless you deodex it. See \"baksmali help deodex\""); 1635a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1645a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1655a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver File outputDirectoryFile = new File(outputDir); 1665a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (!outputDirectoryFile.exists()) { 1675a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (!outputDirectoryFile.mkdirs()) { 1685a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.err.println("Can't create the output directory " + outputDir); 1695a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.exit(-1); 1705a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1715a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1725a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 173158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver if (analysisArguments.classPathDirectories == null || analysisArguments.classPathDirectories.isEmpty()) { 1746f8366a7a352a661d11bffc84424b0a77d77eb3cBen Gruver analysisArguments.classPathDirectories = Lists.newArrayList(inputFile.getAbsoluteFile().getParent()); 175158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver } 176158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver 17722e85fc3ff3d85e8a30fc42438ccb942fc5d80dfBen Gruver if (!Baksmali.disassembleDexFile(dexFile, outputDirectoryFile, jobs, getOptions(), classes)) { 178158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver System.exit(-1); 179158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver } 1805a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1815a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1825a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver protected boolean needsClassPath() { 1835a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver return !registerInfoTypes.isEmpty() || normalizeVirtualMethods; 1845a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1855a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 1865a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver protected boolean shouldCheckPackagePrivateAccess() { 1875a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver return false; 1885a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 1895a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 190f66362d0733217d5a98860b1729b669539c1dc26Ben Gruver protected boolean showDeodexWarning() { 191f66362d0733217d5a98860b1729b669539c1dc26Ben Gruver return true; 192f66362d0733217d5a98860b1729b669539c1dc26Ben Gruver } 193f66362d0733217d5a98860b1729b669539c1dc26Ben Gruver 194158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver protected BaksmaliOptions getOptions() { 195158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver if (dexFile == null) { 196158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver throw new IllegalStateException("You must call loadDexFile first"); 197158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver } 198158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver 1995a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver final BaksmaliOptions options = new BaksmaliOptions(); 2005a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2015a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (needsClassPath()) { 2025a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver try { 203158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver options.classPath = analysisArguments.loadClassPathForDexFile( 204158f6b0b44326dd374cb8576d9238677a7b73401Ben Gruver inputFile.getAbsoluteFile().getParentFile(), dexFile, shouldCheckPackagePrivateAccess()); 2055a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } catch (Exception ex) { 2065a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.err.println("\n\nError occurred while loading class path files. Aborting."); 2075a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver ex.printStackTrace(System.err); 208e474301e60b89d33343586b896efd8e4b0a10b37Ben Gruver System.exit(-1); 2095a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2105a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2115a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2125a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (!resourceIdFiles.isEmpty()) { 2135a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver Map<String, File> resourceFiles = Maps.newHashMap(); 2145a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 21599394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver assert (resourceIdFiles.size() % 2) == 0; 21699394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver for (int i=0; i<resourceIdFiles.size(); i+=2) { 21799394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver String resourcePrefix = resourceIdFiles.get(i); 21899394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver String publicXml = resourceIdFiles.get(i+1); 21999394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver 22099394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver File publicXmlFile = new File(publicXml); 2215a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 22299394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver if (!publicXmlFile.exists()) { 22399394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver System.err.println(String.format("Can't find file: %s", publicXmlFile)); 2245a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.exit(-1); 2255a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2265a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 22799394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver resourceFiles.put(resourcePrefix, publicXmlFile); 2285a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2295a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 23099394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver try { 23199394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver options.loadResourceIds(resourceFiles); 23299394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver } catch (IOException ex) { 23399394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver System.err.println("Error while loading resource files:"); 23499394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver ex.printStackTrace(System.err); 23599394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver System.exit(-1); 23699394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver } catch (SAXException ex) { 23799394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver System.err.println("Error while loading resource files:"); 23899394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver ex.printStackTrace(System.err); 23999394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver System.exit(-1); 24099394b3daf52591d0f74a9f1dab91ead5c558f05Ben Gruver } 2415a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2425a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2435a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.parameterRegisters = parameterRegisters; 2445a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.localsDirective = localsDirective; 2455a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.sequentialLabels = sequentialLabels; 2465a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.debugInfo = debugInfo; 2475a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.codeOffsets = codeOffsets; 2485a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.accessorComments = accessorComments; 2495a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.implicitReferences = implicitReferences; 2505a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.normalizeVirtualMethods = normalizeVirtualMethods; 2515a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2525a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo = 0; 2535a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2545a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver for (String registerInfoType: registerInfoTypes) { 2555a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (registerInfoType.equalsIgnoreCase("ALL")) { 2565a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.ALL; 2575a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("ALLPRE")) { 2585a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.ALLPRE; 2595a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("ALLPOST")) { 2605a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.ALLPOST; 2615a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("ARGS")) { 2625a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.ARGS; 2635a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("DEST")) { 2645a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.DEST; 2655a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("MERGE")) { 2665a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.MERGE; 2675a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else if (registerInfoType.equalsIgnoreCase("FULLMERGE")) { 2685a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo |= BaksmaliOptions.FULLMERGE; 2695a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } else { 2705a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.err.println(String.format("Invalid register info type: %s", registerInfoType)); 271ca48e6f7d06931039352ebe3acda81457bcefcccBen Gruver usage(); 2725a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver System.exit(-1); 2735a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2745a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2755a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if ((options.registerInfo & BaksmaliOptions.FULLMERGE) != 0) { 2765a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.registerInfo &= ~BaksmaliOptions.MERGE; 2775a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2785a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2795a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2805a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver if (accessorComments) { 2815a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver options.syntheticAccessorResolver = new SyntheticAccessorResolver(dexFile.getOpcodes(), 2825a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver dexFile.getClasses()); 2835a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2845a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver 2855a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver return options; 2865a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver } 2875a5eafb818cc18baeef8bdae1940401da3735f25Ben Gruver} 288