Skip to content

Commit 51b81f8

Browse files
authored
refactor: nested dex + replace --only-main-classes with -a/--all-src (#4069)
1 parent 7169d20 commit 51b81f8

File tree

27 files changed

+225
-237
lines changed

27 files changed

+225
-237
lines changed

brut.apktool/apktool-cli/src/main/java/brut/apktool/Main.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,16 @@ private enum Verbosity { NORMAL, VERBOSE, QUIET }
9191
.desc("Force delete destination directory.")
9292
.get();
9393

94+
private static final Option decodeAllSrcOption = Option.builder("a")
95+
.longOpt("all-src")
96+
.desc("Decode all sources in the apk (includes unknown dex files).")
97+
.get();
98+
9499
private static final Option decodeNoSrcOption = Option.builder("s")
95100
.longOpt("no-src")
96101
.desc("Do not decode sources.")
97102
.get();
98103

99-
private static final Option decodeOnlyMainClassesOption = Option.builder()
100-
.longOpt("only-main-classes")
101-
.desc("Only disassemble the main dex classes (classes[0-9]*.dex) in the root.")
102-
.get();
103-
104104
private static final Option decodeNoDebugInfoOption = Option.builder()
105105
.longOpt("no-debug-info")
106106
.desc("Do not include debug info in sources (.local, .param, .line, etc.)")
@@ -242,11 +242,11 @@ private static void loadOptions(Options options, boolean advanced) {
242242
decodeOptions.addOption(jobsOption);
243243
decodeOptions.addOption(libOption);
244244
if (advanced) {
245+
decodeOptions.addOption(decodeAllSrcOption);
245246
decodeOptions.addOption(decodeKeepBrokenResOption);
246247
decodeOptions.addOption(decodeMatchOriginalOption);
247248
decodeOptions.addOption(decodeNoAssetsOption);
248249
decodeOptions.addOption(decodeNoDebugInfoOption);
249-
decodeOptions.addOption(decodeOnlyMainClassesOption);
250250
decodeOptions.addOption(decodeOnlyManifestOption);
251251
decodeOptions.addOption(decodeResResolveModeOption);
252252
}
@@ -424,14 +424,14 @@ private static void cmdDecode(String[] args) throws AndrolibException {
424424
if (cli.hasOption(decodeForceOption)) {
425425
config.setForced(true);
426426
}
427-
if (cli.hasOption(decodeNoSrcOption)) {
428-
config.setDecodeSources(Config.DecodeSources.NONE);
427+
if (cli.hasOption(decodeAllSrcOption)) {
428+
config.setDecodeSources(Config.DecodeSources.FULL);
429429
}
430-
if (cli.hasOption(decodeOnlyMainClassesOption)) {
431-
if (cli.hasOption(decodeNoSrcOption)) {
432-
printOptionConflict(decodeOnlyMainClassesOption, decodeNoSrcOption);
430+
if (cli.hasOption(decodeNoSrcOption)) {
431+
if (cli.hasOption(decodeAllSrcOption)) {
432+
printOptionConflict(decodeNoSrcOption, decodeAllSrcOption);
433433
} else {
434-
config.setDecodeSources(Config.DecodeSources.ONLY_MAIN_CLASSES);
434+
config.setDecodeSources(Config.DecodeSources.NONE);
435435
}
436436
}
437437
if (cli.hasOption(decodeNoDebugInfoOption)) {

brut.apktool/apktool-lib/src/main/java/brut/androlib/ApkBuilder.java

Lines changed: 25 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,14 @@ public class ApkBuilder {
5050
private final AtomicReference<AndrolibException> mFirstError;
5151

5252
private ApkInfo mApkInfo;
53-
private int mMinSdkVersion;
53+
private SmaliBuilder mSmaliBuilder;
54+
private AaptInvoker mAaptInvoker;
5455
private BackgroundWorker mWorker;
5556

5657
public ApkBuilder(ExtFile apkDir, Config config) {
5758
mApkDir = apkDir;
5859
mConfig = config;
59-
mFirstError = new AtomicReference<>(null);
60+
mFirstError = new AtomicReference<>();
6061
}
6162

6263
public void build(File outApk) throws AndrolibException {
@@ -65,11 +66,10 @@ public void build(File outApk) throws AndrolibException {
6566
}
6667
try {
6768
mApkInfo = ApkInfo.load(mApkDir);
68-
6969
String minSdkVersion = mApkInfo.getSdkInfo().getMinSdkVersion();
70-
if (minSdkVersion != null) {
71-
mMinSdkVersion = SdkInfo.parseSdkInt(minSdkVersion);
72-
}
70+
mSmaliBuilder = new SmaliBuilder(minSdkVersion != null
71+
? SdkInfo.parseSdkInt(minSdkVersion) : 0);
72+
mAaptInvoker = new AaptInvoker(mApkInfo, mConfig);
7373

7474
String apkName = mApkInfo.getApkFileName();
7575
if (apkName == null) {
@@ -141,7 +141,8 @@ private void buildSources(File outDir) throws AndrolibException {
141141
if (dirName.equals("smali")) {
142142
fileName = "classes.dex";
143143
} else if (dirName.startsWith("smali_")) {
144-
fileName = dirName.substring(dirName.indexOf('_') + 1) + ".dex";
144+
fileName = dirName.substring(dirName.indexOf('_') + 1)
145+
.replace('@', File.separatorChar) + ".dex";
145146
} else {
146147
continue;
147148
}
@@ -157,11 +158,8 @@ private void buildSources(File outDir) throws AndrolibException {
157158

158159
private void copySourcesRaw(File outDir, String fileName) throws AndrolibException {
159160
File inFile = new File(mApkDir, fileName);
160-
if (!inFile.isFile()) {
161-
return;
162-
}
163-
164161
File outFile = new File(outDir, fileName);
162+
165163
if (!mConfig.isForced() && !isFileNewer(inFile, outFile)) {
166164
LOGGER.info("File " + fileName + " has not changed.");
167165
return;
@@ -193,20 +191,15 @@ private void buildSourcesSmali(File outDir, String dirName, String fileName) thr
193191

194192
private void buildSourcesSmaliJob(File outDir, String dirName, String fileName) throws AndrolibException {
195193
File smaliDir = new File(mApkDir, dirName);
196-
if (!smaliDir.isDirectory()) {
197-
return;
198-
}
199-
200194
File dexFile = new File(outDir, fileName);
195+
201196
if (!mConfig.isForced() && !isFileNewer(smaliDir, dexFile)) {
202197
LOGGER.info("Sources in " + dirName + " have not changed.");
203198
return;
204199
}
205-
OS.rmfile(dexFile);
206200

207201
LOGGER.info("Smaling " + dirName + " folder into " + fileName + "...");
208-
SmaliBuilder builder = new SmaliBuilder(smaliDir, mMinSdkVersion);
209-
builder.build(dexFile);
202+
mSmaliBuilder.build(smaliDir, dexFile);
210203
}
211204

212205
private void backupManifestFile(File manifest, File manifestOrig) throws AndrolibException {
@@ -219,8 +212,6 @@ private void backupManifestFile(File manifest, File manifestOrig) throws Androli
219212
return;
220213
}
221214

222-
OS.rmfile(manifestOrig);
223-
224215
try {
225216
OS.cpfile(manifest, manifestOrig);
226217
ResXmlUtils.fixingPublicAttrsInProviderAttributes(manifest);
@@ -272,40 +263,38 @@ private void copyResourcesRaw(File outDir, File manifest, File arscFile) throws
272263
}
273264

274265
private void buildResourcesFull(File outDir, File manifest, File resDir) throws AndrolibException {
275-
File resZip = new File(outDir.getParentFile(), "resources.zip");
276-
if (!mConfig.isForced() && resZip.isFile()
266+
if (!mConfig.isForced()
277267
&& !isFileNewer(manifest, new File(outDir, "AndroidManifest.xml"))
278268
&& !isFileNewer(resDir, new File(outDir, "res"))) {
279269
LOGGER.info("Resources have not changed.");
280270
return;
281271
}
282-
OS.rmfile(resZip);
283272

284273
if (mConfig.isDebuggable()) {
285-
LOGGER.info("Setting 'debuggable' attribute to 'true' in AndroidManifest.xml");
274+
LOGGER.info("Setting 'debuggable' attribute to 'true' in AndroidManifest.xml...");
286275
ResXmlUtils.setApplicationDebugTagTrue(manifest);
287276
}
288277

289278
if (mConfig.isNetSecConf()) {
290-
String targetSdkVersion = mApkInfo.getSdkInfo().getTargetSdkVersion();
291-
if (targetSdkVersion != null && SdkInfo.parseSdkInt(targetSdkVersion) < ResConfig.SDK_NOUGAT) {
292-
LOGGER.warning("Target SDK version is lower than 24! Network Security Configuration might be ignored!");
293-
}
294-
279+
LOGGER.info("Adding permissive network security config in manifest...");
295280
File netSecConfOrig = new File(mApkDir, "res/xml/network_security_config.xml");
296281
OS.mkdir(netSecConfOrig.getParentFile());
297282
ResXmlUtils.modNetworkSecurityConfig(netSecConfOrig);
298283
ResXmlUtils.setNetworkSecurityConfig(manifest);
299-
LOGGER.info("Added permissive network security config in manifest");
284+
285+
String targetSdkVersion = mApkInfo.getSdkInfo().getTargetSdkVersion();
286+
if (targetSdkVersion != null && SdkInfo.parseSdkInt(targetSdkVersion) < ResConfig.SDK_NOUGAT) {
287+
LOGGER.warning("Target SDK version is lower than 24, Network Security Configuration might be ignored!");
288+
}
300289
}
301290

302291
ExtFile tmpFile;
303292
try {
304293
tmpFile = new ExtFile(File.createTempFile("APKTOOL", null));
294+
OS.rmfile(tmpFile);
305295
} catch (IOException ex) {
306296
throw new AndrolibException(ex);
307297
}
308-
OS.rmfile(tmpFile);
309298

310299
File npDir = new File(mApkDir, "9patch");
311300
if (!npDir.isDirectory()) {
@@ -314,8 +303,7 @@ private void buildResourcesFull(File outDir, File manifest, File resDir) throws
314303

315304
LOGGER.info("Building resources with " + AaptManager.getBinaryName() + "...");
316305
try {
317-
AaptInvoker invoker = new AaptInvoker(mApkInfo, mConfig);
318-
invoker.invoke(tmpFile, manifest, resDir, npDir, null, getIncludeFiles());
306+
mAaptInvoker.invoke(tmpFile, manifest, resDir, npDir, null, getIncludeFiles());
319307

320308
Directory tmpDir = tmpFile.getDirectory();
321309
tmpDir.copyToDir(outDir, "AndroidManifest.xml", "resources.arsc", "res");
@@ -336,10 +324,10 @@ private void buildManifest(File outDir, File manifest) throws AndrolibException
336324
ExtFile tmpFile;
337325
try {
338326
tmpFile = new ExtFile(File.createTempFile("APKTOOL", null));
327+
OS.rmfile(tmpFile);
339328
} catch (IOException ex) {
340329
throw new AndrolibException(ex);
341330
}
342-
OS.rmfile(tmpFile);
343331

344332
File npDir = new File(mApkDir, "9patch");
345333
if (!npDir.isDirectory()) {
@@ -348,8 +336,7 @@ private void buildManifest(File outDir, File manifest) throws AndrolibException
348336

349337
LOGGER.info("Building AndroidManifest.xml with " + AaptManager.getBinaryName() + "...");
350338
try {
351-
AaptInvoker invoker = new AaptInvoker(mApkInfo, mConfig);
352-
invoker.invoke(tmpFile, manifest, null, npDir, null, getIncludeFiles());
339+
mAaptInvoker.invoke(tmpFile, manifest, null, npDir, null, getIncludeFiles());
353340

354341
Directory tmpDir = tmpFile.getDirectory();
355342
tmpDir.copyToDir(outDir, "AndroidManifest.xml");
@@ -389,7 +376,7 @@ private void copyOriginalFiles(File outDir) throws AndrolibException {
389376
Directory in = originalDir.getDirectory();
390377

391378
for (String fileName : in.getFiles(true)) {
392-
if (ApkInfo.ORIGINAL_FILENAMES_PATTERN.matcher(fileName).matches()) {
379+
if (ApkInfo.ORIGINAL_FILES_PATTERN.matcher(fileName).matches()) {
393380
in.copyToDir(outDir, fileName);
394381
}
395382
}
@@ -417,7 +404,7 @@ private void buildApkFile(File outDir, File outApk) throws AndrolibException {
417404
ZipUtils.zipDir(outDir, out, doNotCompress);
418405

419406
// Zip standard raw files.
420-
for (String dirName : ApkInfo.RAW_DIRNAMES) {
407+
for (String dirName : ApkInfo.RAW_DIRS) {
421408
File rawDir = new File(mApkDir, dirName);
422409
if (rawDir.isDirectory()) {
423410
LOGGER.info("Importing " + dirName + "...");

0 commit comments

Comments
 (0)