Skip to content

Commit e26b172

Browse files
committed
Added support for decompile action in addition to the default rewrite action
1 parent 6049a74 commit e26b172

File tree

2 files changed

+72
-17
lines changed

2 files changed

+72
-17
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ You can download `apk-instrumentation.jar` from the [Releases section](https://g
1010

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

13-
java -jar apk-instrumentation.jar [/path/to/config.properties]
13+
java -jar apk-instrumentation.jar [--config /path/to/config.properties] [action]
14+
15+
`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.
1416

1517
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.
1618

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

src/info/palant/apkInstrumentation/Main.java

Lines changed: 67 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,34 @@ public class Main
3737

3838
public static void main(String[] args) throws IOException
3939
{
40-
String configPath = (args.length >= 1 ? args[0] : "config.properties");
40+
String action = "rewrite";
41+
String configPath = "config.properties";
42+
for (int i = 0; i < args.length; i++)
43+
{
44+
if (args[i].startsWith("-"))
45+
{
46+
if (args[i].equals("-c") || args[i].equals("--config"))
47+
{
48+
if (i + 1 >= args.length)
49+
{
50+
System.err.println("Configuration file path has to follow --config option.");
51+
System.exit(-1);
52+
}
53+
configPath = args[++i];
54+
}
55+
else
56+
{
57+
System.err.println("Unsupported option: " + args[i]);
58+
System.exit(-2);
59+
}
60+
}
61+
else
62+
{
63+
action = args[i];
64+
break;
65+
}
66+
}
67+
4168
Properties config = readConfig(configPath);
4269
if (config == null)
4370
{
@@ -63,34 +90,48 @@ public static void main(String[] args) throws IOException
6390
System.exit(3);
6491
}
6592

66-
String output = config.getProperty("output");
93+
String outputOption = action.equals("rewrite") ? "output" : "decompileDir";
94+
String output = config.getProperty(outputOption);
6795
if (output == null)
6896
{
69-
System.err.println("Please add output option to config file.");
97+
System.err.println("Please add " + outputOption + " option to config file.");
7098
System.exit(4);
7199
}
72100

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

78104
String platformVersion = config.getProperty("platformVersion");
79105
String platformsPath = sdkDir + File.separator + "platforms";
80-
File tempDir = Files.createTempDirectory(null).toFile();
81-
try
106+
if (action.equals("rewrite"))
107+
{
108+
if (keystore == null || keypass == null)
109+
System.err.println("Warning: keystore or keypass missing in the config file, package will not be signed.");
110+
111+
File tempDir = Files.createTempDirectory(null).toFile();
112+
try
113+
{
114+
transformAPK(config, input, output, tempDir.getPath(), platformsPath, platformVersion);
115+
}
116+
finally
117+
{
118+
for (String entry: tempDir.list())
119+
new File(tempDir, entry).delete();
120+
tempDir.delete();
121+
}
122+
123+
if (keystore != null && keypass != null)
124+
signAPK(sdkDir, keystore, keypass, output);
125+
}
126+
else if (action.equals("decompile"))
82127
{
83-
transformAPK(config, input, output, tempDir.getPath(), platformsPath, platformVersion);
128+
decompileAPK(input, output, platformsPath, platformVersion);
84129
}
85-
finally
130+
else
86131
{
87-
for (String entry: tempDir.list())
88-
new File(tempDir, entry).delete();
89-
tempDir.delete();
132+
System.err.println("Unsupported action: " + action);
133+
System.exit(5);
90134
}
91-
92-
if (keystore != null && keypass != null)
93-
signAPK(sdkDir, keystore, keypass, output);
94135
}
95136

96137
private static Properties readConfig(String configPath) throws IOException
@@ -142,6 +183,7 @@ private static void setupSoot(String platformsPath, String platformVersion, Stri
142183
Options.v().set_soot_classpath(getJARPath());
143184
Options.v().set_include_all(true);
144185
Options.v().set_ignore_resolving_levels(true);
186+
Options.v().set_process_multiple_dex(true);
145187

146188
// Write (APK Generation) Options
147189
Options.v().set_output_format(Options.output_format_dex);
@@ -304,4 +346,14 @@ private static void signAPK(String sdkDir, String keystore, String keypass, Stri
304346
output
305347
});
306348
}
349+
350+
private static void decompileAPK(String input, String output, String platformsPath, String platformVersion) throws IOException
351+
{
352+
setupSoot(platformsPath, platformVersion, output, input);
353+
Options.v().set_output_format(Options.output_format_jimple);
354+
Options.v().set_hierarchy_dirs(true);
355+
356+
PackManager.v().runPacks();
357+
PackManager.v().writeOutput();
358+
}
307359
}

0 commit comments

Comments
 (0)