mirror of
https://github.com/revanced/Apktool.git
synced 2025-01-07 10:35:52 +01:00
updated to isAdvanceMode() and updated spacing on file
This commit is contained in:
parent
a48c11dc1c
commit
9a6fd7de63
@ -45,476 +45,476 @@ import org.jf.util.ConsoleUtil;
|
|||||||
* @author Connor Tumbleson <connor.tumbleson@gmail.com>
|
* @author Connor Tumbleson <connor.tumbleson@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) throws IOException,
|
public static void main(String[] args) throws IOException,
|
||||||
InterruptedException, BrutException {
|
InterruptedException, BrutException {
|
||||||
|
|
||||||
// set verbosity default
|
// set verbosity default
|
||||||
Verbosity verbosity = Verbosity.NORMAL;
|
Verbosity verbosity = Verbosity.NORMAL;
|
||||||
|
|
||||||
// cli parser
|
// cli parser
|
||||||
CommandLineParser parser = new PosixParser();
|
CommandLineParser parser = new PosixParser();
|
||||||
CommandLine commandLine = null;
|
CommandLine commandLine = null;
|
||||||
|
|
||||||
// load options
|
// load options
|
||||||
_Options();
|
_Options();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
commandLine = parser.parse(allOptions, args, false);
|
commandLine = parser.parse(allOptions, args, false);
|
||||||
} catch (ParseException ex) {
|
} catch (ParseException ex) {
|
||||||
System.out.println(ex.getMessage());
|
System.out.println(ex.getMessage());
|
||||||
usage(commandLine);
|
usage(commandLine);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check for verbose / quiet
|
// check for verbose / quiet
|
||||||
if (commandLine.hasOption("-v") || commandLine.hasOption("--verbose")) {
|
if (commandLine.hasOption("-v") || commandLine.hasOption("--verbose")) {
|
||||||
verbosity = Verbosity.VERBOSE;
|
verbosity = Verbosity.VERBOSE;
|
||||||
} else if (commandLine.hasOption("-q") || commandLine.hasOption("--quiet")) {
|
} else if (commandLine.hasOption("-q") || commandLine.hasOption("--quiet")) {
|
||||||
verbosity = Verbosity.QUIET;
|
verbosity = Verbosity.QUIET;
|
||||||
}
|
}
|
||||||
setupLogging(verbosity);
|
setupLogging(verbosity);
|
||||||
|
|
||||||
// check for advance mode
|
// check for advance mode
|
||||||
if (commandLine.hasOption("advance") || commandLine.hasOption("advanced")) {
|
if (commandLine.hasOption("advance") || commandLine.hasOption("advanced")) {
|
||||||
setAdvanceMode(true);
|
setAdvanceMode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo use new ability of apache-commons-cli to check hasOption for non-prefixed items
|
// @todo use new ability of apache-commons-cli to check hasOption for non-prefixed items
|
||||||
boolean cmdFound = false;
|
boolean cmdFound = false;
|
||||||
for (String opt : commandLine.getArgs()) {
|
for (String opt : commandLine.getArgs()) {
|
||||||
if (opt.equalsIgnoreCase("d") || opt.equalsIgnoreCase("decode")) {
|
if (opt.equalsIgnoreCase("d") || opt.equalsIgnoreCase("decode")) {
|
||||||
cmdDecode(commandLine);
|
cmdDecode(commandLine);
|
||||||
cmdFound = true;
|
cmdFound = true;
|
||||||
} else if (opt.equalsIgnoreCase("b") || opt.equalsIgnoreCase("build")) {
|
} else if (opt.equalsIgnoreCase("b") || opt.equalsIgnoreCase("build")) {
|
||||||
cmdBuild(commandLine);
|
cmdBuild(commandLine);
|
||||||
cmdFound = true;
|
cmdFound = true;
|
||||||
} else if (opt.equalsIgnoreCase("if") || opt.equalsIgnoreCase("install-framework")) {
|
} else if (opt.equalsIgnoreCase("if") || opt.equalsIgnoreCase("install-framework")) {
|
||||||
cmdInstallFramework(commandLine);
|
cmdInstallFramework(commandLine);
|
||||||
cmdFound = true;
|
cmdFound = true;
|
||||||
} else if (opt.equalsIgnoreCase("publicize-resources")) {
|
} else if (opt.equalsIgnoreCase("publicize-resources")) {
|
||||||
cmdPublicizeResources(commandLine);
|
cmdPublicizeResources(commandLine);
|
||||||
cmdFound = true;
|
cmdFound = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// if no commands ran, run the version / usage check.
|
// if no commands ran, run the version / usage check.
|
||||||
if (cmdFound == false) {
|
if (cmdFound == false) {
|
||||||
if (commandLine.hasOption("version") || commandLine.hasOption("version")) {
|
if (commandLine.hasOption("version") || commandLine.hasOption("version")) {
|
||||||
_version();
|
_version();
|
||||||
} else {
|
} else {
|
||||||
usage(commandLine);
|
usage(commandLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private static void cmdDecode(CommandLine cli) throws AndrolibException {
|
|
||||||
ApkDecoder decoder = new ApkDecoder();
|
|
||||||
|
|
||||||
int paraCount = cli.getArgList().size();
|
|
||||||
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
|
||||||
File outDir = null;
|
|
||||||
|
|
||||||
// check for options
|
|
||||||
if (cli.hasOption("s") || cli.hasOption("no-src")) {
|
|
||||||
decoder.setDecodeSources(ApkDecoder.DECODE_SOURCES_NONE);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("d") || cli.hasOption("debug")) {
|
|
||||||
decoder.setDebugMode(true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("b") || cli.hasOption("no-debug-info")) {
|
|
||||||
decoder.setBaksmaliDebugMode(false);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("t") || cli.hasOption("frame-tag")) {
|
|
||||||
decoder.setFrameworkTag(cli.getOptionValue("t"));
|
|
||||||
}
|
|
||||||
if (cli.hasOption("f") || cli.hasOption("force")) {
|
|
||||||
decoder.setForceDelete(true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("r") || cli.hasOption("no-res")) {
|
|
||||||
decoder.setDecodeResources(ApkDecoder.DECODE_RESOURCES_NONE);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("k") || cli.hasOption("keep-broken-res")) {
|
|
||||||
decoder.setKeepBrokenResources(true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
|
||||||
decoder.setFrameworkDir(cli.getOptionValue("p"));
|
|
||||||
}
|
|
||||||
if (cli.hasOption("o") || cli.hasOption("output")) {
|
|
||||||
decoder.setOutDir(new File(cli.getOptionValue("o")));
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// make out folder manually using name of apk
|
|
||||||
String outName = apkName;
|
|
||||||
outName = outName.endsWith(".apk") ? outName.substring(0,
|
|
||||||
outName.length() - 4) : outName + ".out";
|
|
||||||
|
|
||||||
// make file from path
|
|
||||||
outName = new File(outName).getName();
|
|
||||||
outDir = new File(outName);
|
|
||||||
decoder.setOutDir(outDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
decoder.setApkFile(new File(apkName));
|
|
||||||
|
|
||||||
try {
|
|
||||||
decoder.decode();
|
|
||||||
} catch (OutDirExistsException ex) {
|
|
||||||
System.out
|
|
||||||
.println("Destination directory ("
|
|
||||||
+ outDir.getAbsolutePath()
|
|
||||||
+ ") "
|
|
||||||
+ "already exists. Use -f switch if you want to overwrite it.");
|
|
||||||
System.exit(1);
|
|
||||||
} catch (InFileNotFoundException ex) {
|
|
||||||
System.out.println("Input file (" + apkName + ") " + "was not found or was not readable.");
|
|
||||||
System.exit(1);
|
|
||||||
} catch (CantFindFrameworkResException ex) {
|
|
||||||
System.out
|
|
||||||
.println("Can't find framework resources for package of id: "
|
|
||||||
+ String.valueOf(ex.getPkgId())
|
|
||||||
+ ". You must install proper "
|
|
||||||
+ "framework files, see project website for more info.");
|
|
||||||
System.exit(1);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.out.println("Could not modify file. Please ensure you have permission.");
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void cmdBuild(CommandLine cli) throws BrutException {
|
|
||||||
int paraCount = cli.getArgList().size();
|
|
||||||
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
|
||||||
String mAaptPath = "";
|
|
||||||
String appDirName = ".";
|
|
||||||
File outFile = null;
|
|
||||||
Androlib instance = new Androlib();
|
|
||||||
|
|
||||||
// hold all the fields
|
|
||||||
HashMap<String, Boolean> flags = new HashMap<String, Boolean>();
|
|
||||||
flags.put("forceBuildAll", false);
|
|
||||||
flags.put("debug", false);
|
|
||||||
flags.put("verbose", false);
|
|
||||||
flags.put("framework", false);
|
|
||||||
flags.put("update", false);
|
|
||||||
flags.put("copyOriginal", false);
|
|
||||||
|
|
||||||
// check for build options
|
|
||||||
if (cli.hasOption("f") || cli.hasOption("force-all")) {
|
|
||||||
flags.put("forceBuildAll", true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("d") || cli.hasOption("debug")) {
|
|
||||||
flags.put("debug", true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("v") || cli.hasOption("verbose")) {
|
|
||||||
flags.put("verbose", true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("a") || cli.hasOption("aapt")) {
|
|
||||||
mAaptPath = cli.getOptionValue("a");
|
|
||||||
}
|
|
||||||
if (cli.hasOption("c") || cli.hasOption("copy-original")) {
|
|
||||||
flags.put("copyOriginal", true);
|
|
||||||
}
|
|
||||||
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
|
||||||
instance.setFrameworkFolder(cli.getOptionValue("p"));
|
|
||||||
}
|
|
||||||
if (cli.hasOption("o") || cli.hasOption("output")) {
|
|
||||||
outFile = new File(cli.getOptionValue("o"));
|
|
||||||
} else {
|
|
||||||
outFile = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (apkName != null) {
|
|
||||||
appDirName = apkName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// try and build apk
|
|
||||||
instance.build(new File(appDirName), outFile, flags,mAaptPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void cmdInstallFramework(CommandLine cli)
|
|
||||||
throws AndrolibException {
|
|
||||||
int paraCount = cli.getArgList().size();
|
|
||||||
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
|
||||||
String tag = null;
|
|
||||||
String frame_path = null;
|
|
||||||
|
|
||||||
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
|
||||||
frame_path = cli.getOptionValue("p");
|
|
||||||
}
|
|
||||||
if (cli.hasOption("t") || cli.hasOption("tag")) {
|
|
||||||
tag = cli.getOptionValue("t");
|
|
||||||
}
|
|
||||||
new Androlib().installFramework(new File(apkName), tag, frame_path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void cmdPublicizeResources(CommandLine cli)
|
|
||||||
throws AndrolibException {
|
|
||||||
int paraCount = cli.getArgList().size();
|
|
||||||
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
|
||||||
|
|
||||||
new Androlib().publicizeResources(new File(apkName));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void _version() {
|
|
||||||
System.out.println(Androlib.getVersion());
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("static-access")
|
|
||||||
private static void _Options() {
|
|
||||||
|
|
||||||
// create options
|
|
||||||
Option versionOption = OptionBuilder.withLongOpt("version")
|
|
||||||
.withDescription("prints the version then exits")
|
|
||||||
.create("version");
|
|
||||||
|
|
||||||
Option advanceOption = OptionBuilder.withLongOpt("advanced")
|
|
||||||
.withDescription("prints advance information.")
|
|
||||||
.create("advance");
|
|
||||||
|
|
||||||
Option noSrcOption = OptionBuilder.withLongOpt("no-src")
|
|
||||||
.withDescription("Do not decode sources.")
|
|
||||||
.create("s");
|
|
||||||
|
|
||||||
Option noResOption = OptionBuilder.withLongOpt("no-res")
|
|
||||||
.withDescription("Do not decode resources.")
|
|
||||||
.create("r");
|
|
||||||
|
|
||||||
Option debugDecOption = OptionBuilder.withLongOpt("debug")
|
|
||||||
.withDescription("Decode in debug mode. Check project page for more info.")
|
|
||||||
.create("d");
|
|
||||||
|
|
||||||
Option debugBuiOption = OptionBuilder.withLongOpt("debug")
|
|
||||||
.withDescription("Builds in debug mode. Check project page for more info.")
|
|
||||||
.create("d");
|
|
||||||
|
|
||||||
Option noDbgOption = OptionBuilder.withLongOpt("no-debug-info")
|
|
||||||
.withDescription("don't write out debug info (.local, .param, .line, etc.)")
|
|
||||||
.create("b");
|
|
||||||
|
|
||||||
Option forceDecOption = OptionBuilder.withLongOpt("force")
|
|
||||||
.withDescription("Force delete destination directory.")
|
|
||||||
.create("f");
|
|
||||||
|
|
||||||
Option frameTagOption = OptionBuilder.withLongOpt("frame-tag")
|
|
||||||
.withDescription("Uses framework files tagged by <tag>.")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("tag")
|
|
||||||
.create("t");
|
|
||||||
|
|
||||||
Option frameDirOption = OptionBuilder.withLongOpt("frame-path")
|
|
||||||
.withDescription("Uses framework files located in <dir>.")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("dir")
|
|
||||||
.create("p");
|
|
||||||
|
|
||||||
Option keepResOption = OptionBuilder.withLongOpt("keep-broken-res")
|
|
||||||
.withDescription("Use if there was an error and some resources were dropped, e.g.\n"
|
|
||||||
+ " \"Invalid config flags detected. Dropping resources\", but you\n"
|
|
||||||
+ " want to decode them anyway, even with errors. You will have to\n"
|
|
||||||
+ " fix them manually before building.")
|
|
||||||
.create("k");
|
|
||||||
|
|
||||||
Option forceBuiOption = OptionBuilder.withLongOpt("force-all")
|
|
||||||
.withDescription("Skip changes detection and build all files.")
|
|
||||||
.create("f");
|
|
||||||
|
|
||||||
Option aaptOption = OptionBuilder.withLongOpt("aapt")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("loc")
|
|
||||||
.withDescription("Loads aapt from specified location.")
|
|
||||||
.create("a");
|
|
||||||
|
|
||||||
Option originalOption = OptionBuilder.withLongOpt("copy-original")
|
|
||||||
.withDescription("Copies original AndroidManifest.xml and META-INF. See project page for more info.")
|
|
||||||
.create("c");
|
|
||||||
|
|
||||||
Option tagOption = OptionBuilder.withLongOpt("tag")
|
|
||||||
.withDescription("Tag frameworks using <tag>.")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("tag")
|
|
||||||
.create("t");
|
|
||||||
|
|
||||||
Option outputBuiOption = OptionBuilder.withLongOpt("output")
|
|
||||||
.withDescription("The name of apk that gets written. Default is dist/name.apk")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("dir")
|
|
||||||
.create("o");
|
|
||||||
|
|
||||||
Option outputDecOption = OptionBuilder.withLongOpt("output")
|
|
||||||
.withDescription("The name of folder that gets written. Default is apk.out")
|
|
||||||
.hasArg(true)
|
|
||||||
.withArgName("dir")
|
|
||||||
.create("o");
|
|
||||||
|
|
||||||
Option quietOption = OptionBuilder.withLongOpt("quiet")
|
|
||||||
.create("q");
|
|
||||||
|
|
||||||
Option verboseOption = OptionBuilder.withLongOpt("verbose")
|
|
||||||
.create("v");
|
|
||||||
|
|
||||||
// check for advance mode
|
|
||||||
if (advanceMode) {
|
|
||||||
DecodeOptions.addOption(debugDecOption);
|
|
||||||
DecodeOptions.addOption(noDbgOption);
|
|
||||||
DecodeOptions.addOption(keepResOption);
|
|
||||||
|
|
||||||
BuildOptions.addOption(debugBuiOption);
|
|
||||||
BuildOptions.addOption(aaptOption);
|
|
||||||
BuildOptions.addOption(originalOption);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add global options
|
private static void cmdDecode(CommandLine cli) throws AndrolibException {
|
||||||
normalOptions.addOption(versionOption);
|
ApkDecoder decoder = new ApkDecoder();
|
||||||
normalOptions.addOption(advanceOption);
|
|
||||||
|
|
||||||
// add basic decode options
|
int paraCount = cli.getArgList().size();
|
||||||
DecodeOptions.addOption(frameTagOption);
|
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
||||||
DecodeOptions.addOption(outputDecOption);
|
File outDir = null;
|
||||||
DecodeOptions.addOption(frameDirOption);
|
|
||||||
DecodeOptions.addOption(forceDecOption);
|
|
||||||
DecodeOptions.addOption(noSrcOption);
|
|
||||||
DecodeOptions.addOption(noResOption);
|
|
||||||
|
|
||||||
// add basic build options
|
// check for options
|
||||||
BuildOptions.addOption(outputBuiOption);
|
if (cli.hasOption("s") || cli.hasOption("no-src")) {
|
||||||
BuildOptions.addOption(frameDirOption);
|
decoder.setDecodeSources(ApkDecoder.DECODE_SOURCES_NONE);
|
||||||
BuildOptions.addOption(forceBuiOption);
|
}
|
||||||
|
if (cli.hasOption("d") || cli.hasOption("debug")) {
|
||||||
|
decoder.setDebugMode(true);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("b") || cli.hasOption("no-debug-info")) {
|
||||||
|
decoder.setBaksmaliDebugMode(false);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("t") || cli.hasOption("frame-tag")) {
|
||||||
|
decoder.setFrameworkTag(cli.getOptionValue("t"));
|
||||||
|
}
|
||||||
|
if (cli.hasOption("f") || cli.hasOption("force")) {
|
||||||
|
decoder.setForceDelete(true);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("r") || cli.hasOption("no-res")) {
|
||||||
|
decoder.setDecodeResources(ApkDecoder.DECODE_RESOURCES_NONE);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("k") || cli.hasOption("keep-broken-res")) {
|
||||||
|
decoder.setKeepBrokenResources(true);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
||||||
|
decoder.setFrameworkDir(cli.getOptionValue("p"));
|
||||||
|
}
|
||||||
|
if (cli.hasOption("o") || cli.hasOption("output")) {
|
||||||
|
decoder.setOutDir(new File(cli.getOptionValue("o")));
|
||||||
|
} else {
|
||||||
|
|
||||||
// add basic framework options
|
// make out folder manually using name of apk
|
||||||
frameOptions.addOption(tagOption);
|
String outName = apkName;
|
||||||
frameOptions.addOption(frameDirOption);
|
outName = outName.endsWith(".apk") ? outName.substring(0,
|
||||||
|
outName.length() - 4) : outName + ".out";
|
||||||
|
|
||||||
// add all, loop existing cats then manually add advance
|
// make file from path
|
||||||
for (Object op : normalOptions.getOptions()) {
|
outName = new File(outName).getName();
|
||||||
allOptions.addOption((Option)op);
|
outDir = new File(outName);
|
||||||
}
|
decoder.setOutDir(outDir);
|
||||||
for (Object op : DecodeOptions.getOptions()) {
|
}
|
||||||
allOptions.addOption((Option)op);
|
|
||||||
}
|
|
||||||
for (Object op : BuildOptions.getOptions()) {
|
|
||||||
allOptions.addOption((Option)op);
|
|
||||||
}
|
|
||||||
for (Object op : frameOptions.getOptions()) {
|
|
||||||
allOptions.addOption((Option)op);
|
|
||||||
}
|
|
||||||
allOptions.addOption(debugDecOption);
|
|
||||||
allOptions.addOption(noDbgOption);
|
|
||||||
allOptions.addOption(keepResOption);
|
|
||||||
allOptions.addOption(debugBuiOption);
|
|
||||||
allOptions.addOption(aaptOption);
|
|
||||||
allOptions.addOption(originalOption);
|
|
||||||
allOptions.addOption(verboseOption);
|
|
||||||
allOptions.addOption(quietOption);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String verbosityHelp() {
|
decoder.setApkFile(new File(apkName));
|
||||||
if (advanceMode) {
|
|
||||||
return "[-q|--quiet OR -v|--verbose] ";
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void usage(CommandLine commandLine) {
|
try {
|
||||||
|
decoder.decode();
|
||||||
|
} catch (OutDirExistsException ex) {
|
||||||
|
System.out
|
||||||
|
.println("Destination directory ("
|
||||||
|
+ outDir.getAbsolutePath()
|
||||||
|
+ ") "
|
||||||
|
+ "already exists. Use -f switch if you want to overwrite it.");
|
||||||
|
System.exit(1);
|
||||||
|
} catch (InFileNotFoundException ex) {
|
||||||
|
System.out.println("Input file (" + apkName + ") " + "was not found or was not readable.");
|
||||||
|
System.exit(1);
|
||||||
|
} catch (CantFindFrameworkResException ex) {
|
||||||
|
System.out
|
||||||
|
.println("Can't find framework resources for package of id: "
|
||||||
|
+ String.valueOf(ex.getPkgId())
|
||||||
|
+ ". You must install proper "
|
||||||
|
+ "framework files, see project website for more info.");
|
||||||
|
System.exit(1);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.out.println("Could not modify file. Please ensure you have permission.");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// load basicOptions
|
}
|
||||||
_Options();
|
|
||||||
HelpFormatter formatter = new HelpFormatter();
|
|
||||||
|
|
||||||
// max their window to 120, if small.
|
private static void cmdBuild(CommandLine cli) throws BrutException {
|
||||||
int consoleWidth = ConsoleUtil.getConsoleWidth();
|
int paraCount = cli.getArgList().size();
|
||||||
if (consoleWidth <= 0) {
|
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
||||||
consoleWidth = 120;
|
String mAaptPath = "";
|
||||||
}
|
String appDirName = ".";
|
||||||
formatter.setWidth(consoleWidth);
|
File outFile = null;
|
||||||
|
Androlib instance = new Androlib();
|
||||||
|
|
||||||
// print out license info prior to formatter.
|
// hold all the fields
|
||||||
System.out.println(
|
HashMap<String, Boolean> flags = new HashMap<String, Boolean>();
|
||||||
"Apktool v" + Androlib.getVersion() + " - a tool for reengineering Android apk files\n" +
|
flags.put("forceBuildAll", false);
|
||||||
"with smali v" + ApktoolProperties.get("smaliVersion") +
|
flags.put("debug", false);
|
||||||
" and baksmali v" + ApktoolProperties.get("baksmaliVersion") + "\n" +
|
flags.put("verbose", false);
|
||||||
"Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>\n" +
|
flags.put("framework", false);
|
||||||
"Updated by Connor Tumbleson <connor.tumbleson@gmail.com>" );
|
flags.put("update", false);
|
||||||
if (advanceMode) {
|
flags.put("copyOriginal", false);
|
||||||
System.out.println("Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n");
|
|
||||||
}else {
|
|
||||||
System.out.println("");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4 usage outputs (general, frameworks, decode, build)
|
// check for build options
|
||||||
formatter.printHelp("apktool " + verbosityHelp(), normalOptions);
|
if (cli.hasOption("f") || cli.hasOption("force-all")) {
|
||||||
formatter.printHelp("apktool " + verbosityHelp() + "if|install-framework [options] <framework.apk>", frameOptions);
|
flags.put("forceBuildAll", true);
|
||||||
formatter.printHelp("apktool " + verbosityHelp() + "d[ecode] [options] <file_apk>", DecodeOptions);
|
}
|
||||||
formatter.printHelp("apktool " + verbosityHelp() + "b[uild] [options] <app_path>", BuildOptions);
|
if (cli.hasOption("d") || cli.hasOption("debug")) {
|
||||||
if (advanceMode) {
|
flags.put("debug", true);
|
||||||
formatter.printHelp("apktool " + verbosityHelp() + "publicize-resources <file_path>",
|
}
|
||||||
"Make all framework resources public.", emptyOptions, null);
|
if (cli.hasOption("v") || cli.hasOption("verbose")) {
|
||||||
} else {
|
flags.put("verbose", true);
|
||||||
System.out.println("");
|
}
|
||||||
}
|
if (cli.hasOption("a") || cli.hasOption("aapt")) {
|
||||||
|
mAaptPath = cli.getOptionValue("a");
|
||||||
|
}
|
||||||
|
if (cli.hasOption("c") || cli.hasOption("copy-original")) {
|
||||||
|
flags.put("copyOriginal", true);
|
||||||
|
}
|
||||||
|
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
||||||
|
instance.setFrameworkFolder(cli.getOptionValue("p"));
|
||||||
|
}
|
||||||
|
if (cli.hasOption("o") || cli.hasOption("output")) {
|
||||||
|
outFile = new File(cli.getOptionValue("o"));
|
||||||
|
} else {
|
||||||
|
outFile = null;
|
||||||
|
}
|
||||||
|
|
||||||
// print out more information
|
if (apkName != null) {
|
||||||
System.out.println(
|
appDirName = apkName;
|
||||||
"For additional info, see: http://code.google.com/p/android-apktool/ \n"
|
}
|
||||||
+ "For smali/baksmali info, see: http://code.google.com/p/smali/");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void setupLogging(Verbosity verbosity) {
|
// try and build apk
|
||||||
Logger logger = Logger.getLogger("");
|
instance.build(new File(appDirName), outFile, flags,mAaptPath);
|
||||||
for (Handler handler : logger.getHandlers()) {
|
}
|
||||||
logger.removeHandler(handler);
|
|
||||||
}
|
|
||||||
if (verbosity == Verbosity.QUIET) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Handler handler = new ConsoleHandler();
|
private static void cmdInstallFramework(CommandLine cli)
|
||||||
logger.addHandler(handler);
|
throws AndrolibException {
|
||||||
|
int paraCount = cli.getArgList().size();
|
||||||
|
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
||||||
|
String tag = null;
|
||||||
|
String frame_path = null;
|
||||||
|
|
||||||
if (verbosity == Verbosity.VERBOSE) {
|
if (cli.hasOption("p") || cli.hasOption("frame-path")) {
|
||||||
handler.setLevel(Level.ALL);
|
frame_path = cli.getOptionValue("p");
|
||||||
logger.setLevel(Level.ALL);
|
}
|
||||||
} else {
|
if (cli.hasOption("t") || cli.hasOption("tag")) {
|
||||||
handler.setFormatter(new Formatter() {
|
tag = cli.getOptionValue("t");
|
||||||
@Override
|
}
|
||||||
public String format(LogRecord record) {
|
new Androlib().installFramework(new File(apkName), tag, frame_path);
|
||||||
return record.getLevel().toString().charAt(0) + ": "
|
}
|
||||||
+ record.getMessage()
|
|
||||||
+ System.getProperty("line.separator");
|
private static void cmdPublicizeResources(CommandLine cli)
|
||||||
}
|
throws AndrolibException {
|
||||||
});
|
int paraCount = cli.getArgList().size();
|
||||||
}
|
String apkName = (String) cli.getArgList().get(paraCount - 1);
|
||||||
}
|
|
||||||
|
new Androlib().publicizeResources(new File(apkName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void _version() {
|
||||||
|
System.out.println(Androlib.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("static-access")
|
||||||
|
private static void _Options() {
|
||||||
|
|
||||||
|
// create options
|
||||||
|
Option versionOption = OptionBuilder.withLongOpt("version")
|
||||||
|
.withDescription("prints the version then exits")
|
||||||
|
.create("version");
|
||||||
|
|
||||||
|
Option advanceOption = OptionBuilder.withLongOpt("advanced")
|
||||||
|
.withDescription("prints advance information.")
|
||||||
|
.create("advance");
|
||||||
|
|
||||||
|
Option noSrcOption = OptionBuilder.withLongOpt("no-src")
|
||||||
|
.withDescription("Do not decode sources.")
|
||||||
|
.create("s");
|
||||||
|
|
||||||
|
Option noResOption = OptionBuilder.withLongOpt("no-res")
|
||||||
|
.withDescription("Do not decode resources.")
|
||||||
|
.create("r");
|
||||||
|
|
||||||
|
Option debugDecOption = OptionBuilder.withLongOpt("debug")
|
||||||
|
.withDescription("Decode in debug mode. Check project page for more info.")
|
||||||
|
.create("d");
|
||||||
|
|
||||||
|
Option debugBuiOption = OptionBuilder.withLongOpt("debug")
|
||||||
|
.withDescription("Builds in debug mode. Check project page for more info.")
|
||||||
|
.create("d");
|
||||||
|
|
||||||
|
Option noDbgOption = OptionBuilder.withLongOpt("no-debug-info")
|
||||||
|
.withDescription("don't write out debug info (.local, .param, .line, etc.)")
|
||||||
|
.create("b");
|
||||||
|
|
||||||
|
Option forceDecOption = OptionBuilder.withLongOpt("force")
|
||||||
|
.withDescription("Force delete destination directory.")
|
||||||
|
.create("f");
|
||||||
|
|
||||||
|
Option frameTagOption = OptionBuilder.withLongOpt("frame-tag")
|
||||||
|
.withDescription("Uses framework files tagged by <tag>.")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("tag")
|
||||||
|
.create("t");
|
||||||
|
|
||||||
|
Option frameDirOption = OptionBuilder.withLongOpt("frame-path")
|
||||||
|
.withDescription("Uses framework files located in <dir>.")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("dir")
|
||||||
|
.create("p");
|
||||||
|
|
||||||
|
Option keepResOption = OptionBuilder.withLongOpt("keep-broken-res")
|
||||||
|
.withDescription("Use if there was an error and some resources were dropped, e.g.\n"
|
||||||
|
+ " \"Invalid config flags detected. Dropping resources\", but you\n"
|
||||||
|
+ " want to decode them anyway, even with errors. You will have to\n"
|
||||||
|
+ " fix them manually before building.")
|
||||||
|
.create("k");
|
||||||
|
|
||||||
|
Option forceBuiOption = OptionBuilder.withLongOpt("force-all")
|
||||||
|
.withDescription("Skip changes detection and build all files.")
|
||||||
|
.create("f");
|
||||||
|
|
||||||
|
Option aaptOption = OptionBuilder.withLongOpt("aapt")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("loc")
|
||||||
|
.withDescription("Loads aapt from specified location.")
|
||||||
|
.create("a");
|
||||||
|
|
||||||
|
Option originalOption = OptionBuilder.withLongOpt("copy-original")
|
||||||
|
.withDescription("Copies original AndroidManifest.xml and META-INF. See project page for more info.")
|
||||||
|
.create("c");
|
||||||
|
|
||||||
|
Option tagOption = OptionBuilder.withLongOpt("tag")
|
||||||
|
.withDescription("Tag frameworks using <tag>.")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("tag")
|
||||||
|
.create("t");
|
||||||
|
|
||||||
|
Option outputBuiOption = OptionBuilder.withLongOpt("output")
|
||||||
|
.withDescription("The name of apk that gets written. Default is dist/name.apk")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("dir")
|
||||||
|
.create("o");
|
||||||
|
|
||||||
|
Option outputDecOption = OptionBuilder.withLongOpt("output")
|
||||||
|
.withDescription("The name of folder that gets written. Default is apk.out")
|
||||||
|
.hasArg(true)
|
||||||
|
.withArgName("dir")
|
||||||
|
.create("o");
|
||||||
|
|
||||||
|
Option quietOption = OptionBuilder.withLongOpt("quiet")
|
||||||
|
.create("q");
|
||||||
|
|
||||||
|
Option verboseOption = OptionBuilder.withLongOpt("verbose")
|
||||||
|
.create("v");
|
||||||
|
|
||||||
|
// check for advance mode
|
||||||
|
if (isAdvanceMode()) {
|
||||||
|
DecodeOptions.addOption(debugDecOption);
|
||||||
|
DecodeOptions.addOption(noDbgOption);
|
||||||
|
DecodeOptions.addOption(keepResOption);
|
||||||
|
|
||||||
|
BuildOptions.addOption(debugBuiOption);
|
||||||
|
BuildOptions.addOption(aaptOption);
|
||||||
|
BuildOptions.addOption(originalOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add global options
|
||||||
|
normalOptions.addOption(versionOption);
|
||||||
|
normalOptions.addOption(advanceOption);
|
||||||
|
|
||||||
|
// add basic decode options
|
||||||
|
DecodeOptions.addOption(frameTagOption);
|
||||||
|
DecodeOptions.addOption(outputDecOption);
|
||||||
|
DecodeOptions.addOption(frameDirOption);
|
||||||
|
DecodeOptions.addOption(forceDecOption);
|
||||||
|
DecodeOptions.addOption(noSrcOption);
|
||||||
|
DecodeOptions.addOption(noResOption);
|
||||||
|
|
||||||
|
// add basic build options
|
||||||
|
BuildOptions.addOption(outputBuiOption);
|
||||||
|
BuildOptions.addOption(frameDirOption);
|
||||||
|
BuildOptions.addOption(forceBuiOption);
|
||||||
|
|
||||||
|
// add basic framework options
|
||||||
|
frameOptions.addOption(tagOption);
|
||||||
|
frameOptions.addOption(frameDirOption);
|
||||||
|
|
||||||
|
// add all, loop existing cats then manually add advance
|
||||||
|
for (Object op : normalOptions.getOptions()) {
|
||||||
|
allOptions.addOption((Option)op);
|
||||||
|
}
|
||||||
|
for (Object op : DecodeOptions.getOptions()) {
|
||||||
|
allOptions.addOption((Option)op);
|
||||||
|
}
|
||||||
|
for (Object op : BuildOptions.getOptions()) {
|
||||||
|
allOptions.addOption((Option)op);
|
||||||
|
}
|
||||||
|
for (Object op : frameOptions.getOptions()) {
|
||||||
|
allOptions.addOption((Option)op);
|
||||||
|
}
|
||||||
|
allOptions.addOption(debugDecOption);
|
||||||
|
allOptions.addOption(noDbgOption);
|
||||||
|
allOptions.addOption(keepResOption);
|
||||||
|
allOptions.addOption(debugBuiOption);
|
||||||
|
allOptions.addOption(aaptOption);
|
||||||
|
allOptions.addOption(originalOption);
|
||||||
|
allOptions.addOption(verboseOption);
|
||||||
|
allOptions.addOption(quietOption);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String verbosityHelp() {
|
||||||
|
if (isAdvanceMode()) {
|
||||||
|
return "[-q|--quiet OR -v|--verbose] ";
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void usage(CommandLine commandLine) {
|
||||||
|
|
||||||
|
// load basicOptions
|
||||||
|
_Options();
|
||||||
|
HelpFormatter formatter = new HelpFormatter();
|
||||||
|
|
||||||
|
// max their window to 120, if small.
|
||||||
|
int consoleWidth = ConsoleUtil.getConsoleWidth();
|
||||||
|
if (consoleWidth <= 0) {
|
||||||
|
consoleWidth = 120;
|
||||||
|
}
|
||||||
|
formatter.setWidth(consoleWidth);
|
||||||
|
|
||||||
|
// print out license info prior to formatter.
|
||||||
|
System.out.println(
|
||||||
|
"Apktool v" + Androlib.getVersion() + " - a tool for reengineering Android apk files\n" +
|
||||||
|
"with smali v" + ApktoolProperties.get("smaliVersion") +
|
||||||
|
" and baksmali v" + ApktoolProperties.get("baksmaliVersion") + "\n" +
|
||||||
|
"Copyright 2010 Ryszard Wiśniewski <brut.alll@gmail.com>\n" +
|
||||||
|
"Updated by Connor Tumbleson <connor.tumbleson@gmail.com>" );
|
||||||
|
if (isAdvanceMode()) {
|
||||||
|
System.out.println("Apache License 2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n");
|
||||||
|
}else {
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4 usage outputs (general, frameworks, decode, build)
|
||||||
|
formatter.printHelp("apktool " + verbosityHelp(), normalOptions);
|
||||||
|
formatter.printHelp("apktool " + verbosityHelp() + "if|install-framework [options] <framework.apk>", frameOptions);
|
||||||
|
formatter.printHelp("apktool " + verbosityHelp() + "d[ecode] [options] <file_apk>", DecodeOptions);
|
||||||
|
formatter.printHelp("apktool " + verbosityHelp() + "b[uild] [options] <app_path>", BuildOptions);
|
||||||
|
if (isAdvanceMode()) {
|
||||||
|
formatter.printHelp("apktool " + verbosityHelp() + "publicize-resources <file_path>",
|
||||||
|
"Make all framework resources public.", emptyOptions, null);
|
||||||
|
} else {
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// print out more information
|
||||||
|
System.out.println(
|
||||||
|
"For additional info, see: http://code.google.com/p/android-apktool/ \n"
|
||||||
|
+ "For smali/baksmali info, see: http://code.google.com/p/smali/");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setupLogging(Verbosity verbosity) {
|
||||||
|
Logger logger = Logger.getLogger("");
|
||||||
|
for (Handler handler : logger.getHandlers()) {
|
||||||
|
logger.removeHandler(handler);
|
||||||
|
}
|
||||||
|
if (verbosity == Verbosity.QUIET) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Handler handler = new ConsoleHandler();
|
||||||
|
logger.addHandler(handler);
|
||||||
|
|
||||||
|
if (verbosity == Verbosity.VERBOSE) {
|
||||||
|
handler.setLevel(Level.ALL);
|
||||||
|
logger.setLevel(Level.ALL);
|
||||||
|
} else {
|
||||||
|
handler.setFormatter(new Formatter() {
|
||||||
|
@Override
|
||||||
|
public String format(LogRecord record) {
|
||||||
|
return record.getLevel().toString().charAt(0) + ": "
|
||||||
|
+ record.getMessage()
|
||||||
|
+ System.getProperty("line.separator");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isAdvanceMode() {
|
public static boolean isAdvanceMode() {
|
||||||
return advanceMode;
|
return advanceMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setAdvanceMode(boolean advanceMode) {
|
public static void setAdvanceMode(boolean advanceMode) {
|
||||||
Main.advanceMode = advanceMode;
|
Main.advanceMode = advanceMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum Verbosity {
|
private static enum Verbosity {
|
||||||
NORMAL, VERBOSE, QUIET;
|
NORMAL, VERBOSE, QUIET;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean advanceMode = false;
|
private static boolean advanceMode = false;
|
||||||
|
|
||||||
private final static Options normalOptions;
|
private final static Options normalOptions;
|
||||||
private final static Options DecodeOptions;
|
private final static Options DecodeOptions;
|
||||||
private final static Options BuildOptions;
|
private final static Options BuildOptions;
|
||||||
private final static Options frameOptions;
|
private final static Options frameOptions;
|
||||||
private final static Options allOptions;
|
private final static Options allOptions;
|
||||||
private final static Options emptyOptions;
|
private final static Options emptyOptions;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
//normal and advance usage output
|
//normal and advance usage output
|
||||||
normalOptions = new Options();
|
normalOptions = new Options();
|
||||||
BuildOptions = new Options();
|
BuildOptions = new Options();
|
||||||
DecodeOptions = new Options();
|
DecodeOptions = new Options();
|
||||||
frameOptions = new Options();
|
frameOptions = new Options();
|
||||||
allOptions = new Options();
|
allOptions = new Options();
|
||||||
emptyOptions = new Options();
|
emptyOptions = new Options();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user