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