Skip to content

Commit

Permalink
Added support for decompile action in addition to the default rewrite…
Browse files Browse the repository at this point in the history
… action
  • Loading branch information
palant committed Sep 2, 2021
1 parent 6049a74 commit e26b172
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 17 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ You can download `apk-instrumentation.jar` from the [Releases section](https://g

To start the APK conversion process, use the following command:

java -jar apk-instrumentation.jar [/path/to/config.properties]
java -jar apk-instrumentation.jar [--config /path/to/config.properties] [action]

`action` can be either `rewrite` (default) or `decompile`. It is recommendable to run `decompile` action (produces Jimple code) before configuring rewriting steps, output of other decompilers might be incompatible e.g. when determining call signatures.

If no path to `config.properties` is given on the command line, the file is assumed to be present in the current directory. Its entries determine what code transformations should be performed.

Expand All @@ -21,7 +23,8 @@ The following configuration options are independent of the components enabled:
* `sdk`: (optional) directory where the Android SDK is installed. If omitted, `ANDROID_HOME` environment variable has to be set.
* `platformVersion`: (optional) platform version to be loaded in Android SDK. If omitted, will be detected automatically.
* `input`: path to the input APK file
* `output`: path of the instrumented APK file to be written
* `output`: path of the rewritten APK file to be written
* `decompileDir`: path to write decompiled Jimple code to
* `keystore`: (optional) path to the key store containing the signing key
* `keypass`: (optional) password protecting the key store

Expand Down
82 changes: 67 additions & 15 deletions src/info/palant/apkInstrumentation/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,34 @@ public class Main

public static void main(String[] args) throws IOException
{
String configPath = (args.length >= 1 ? args[0] : "config.properties");
String action = "rewrite";
String configPath = "config.properties";
for (int i = 0; i < args.length; i++)
{
if (args[i].startsWith("-"))
{
if (args[i].equals("-c") || args[i].equals("--config"))
{
if (i + 1 >= args.length)
{
System.err.println("Configuration file path has to follow --config option.");
System.exit(-1);
}
configPath = args[++i];
}
else
{
System.err.println("Unsupported option: " + args[i]);
System.exit(-2);
}
}
else
{
action = args[i];
break;
}
}

Properties config = readConfig(configPath);
if (config == null)
{
Expand All @@ -63,34 +90,48 @@ public static void main(String[] args) throws IOException
System.exit(3);
}

String output = config.getProperty("output");
String outputOption = action.equals("rewrite") ? "output" : "decompileDir";
String output = config.getProperty(outputOption);
if (output == null)
{
System.err.println("Please add output option to config file.");
System.err.println("Please add " + outputOption + " option to config file.");
System.exit(4);
}

String keystore = config.getProperty("keystore");
String keypass = config.getProperty("keypass");
if (keystore == null || keypass == null)
System.err.println("Warning: keystore or keypass missing in the config file, package will not be signed.");

String platformVersion = config.getProperty("platformVersion");
String platformsPath = sdkDir + File.separator + "platforms";
File tempDir = Files.createTempDirectory(null).toFile();
try
if (action.equals("rewrite"))
{
if (keystore == null || keypass == null)
System.err.println("Warning: keystore or keypass missing in the config file, package will not be signed.");

File tempDir = Files.createTempDirectory(null).toFile();
try
{
transformAPK(config, input, output, tempDir.getPath(), platformsPath, platformVersion);
}
finally
{
for (String entry: tempDir.list())
new File(tempDir, entry).delete();
tempDir.delete();
}

if (keystore != null && keypass != null)
signAPK(sdkDir, keystore, keypass, output);
}
else if (action.equals("decompile"))
{
transformAPK(config, input, output, tempDir.getPath(), platformsPath, platformVersion);
decompileAPK(input, output, platformsPath, platformVersion);
}
finally
else
{
for (String entry: tempDir.list())
new File(tempDir, entry).delete();
tempDir.delete();
System.err.println("Unsupported action: " + action);
System.exit(5);
}

if (keystore != null && keypass != null)
signAPK(sdkDir, keystore, keypass, output);
}

private static Properties readConfig(String configPath) throws IOException
Expand Down Expand Up @@ -142,6 +183,7 @@ private static void setupSoot(String platformsPath, String platformVersion, Stri
Options.v().set_soot_classpath(getJARPath());
Options.v().set_include_all(true);
Options.v().set_ignore_resolving_levels(true);
Options.v().set_process_multiple_dex(true);

// Write (APK Generation) Options
Options.v().set_output_format(Options.output_format_dex);
Expand Down Expand Up @@ -304,4 +346,14 @@ private static void signAPK(String sdkDir, String keystore, String keypass, Stri
output
});
}

private static void decompileAPK(String input, String output, String platformsPath, String platformVersion) throws IOException
{
setupSoot(platformsPath, platformVersion, output, input);
Options.v().set_output_format(Options.output_format_jimple);
Options.v().set_hierarchy_dirs(true);

PackManager.v().runPacks();
PackManager.v().writeOutput();
}
}

0 comments on commit e26b172

Please sign in to comment.