mirror of
https://github.com/revanced/Apktool.git
synced 2025-01-07 10:35:52 +01:00
refactor Apkecoder - streamline decode procedure (#3109)
This commit is contained in:
parent
1e400aa995
commit
5cd94d6aa0
@ -53,7 +53,7 @@ public class ApkDecoder {
|
|||||||
private final static String SMALI_DIRNAME = "smali";
|
private final static String SMALI_DIRNAME = "smali";
|
||||||
private final static String UNK_DIRNAME = "unknown";
|
private final static String UNK_DIRNAME = "unknown";
|
||||||
private final static String[] APK_RESOURCES_FILENAMES = new String[] {
|
private final static String[] APK_RESOURCES_FILENAMES = new String[] {
|
||||||
"resources.arsc", "AndroidManifest.xml", "res", "r", "R" };
|
"resources.arsc", "res", "r", "R" };
|
||||||
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
|
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
|
||||||
"AndroidManifest.xml" };
|
"AndroidManifest.xml" };
|
||||||
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
|
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
|
||||||
@ -101,46 +101,17 @@ public class ApkDecoder {
|
|||||||
|
|
||||||
LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName());
|
LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName());
|
||||||
|
|
||||||
if (hasResources()) {
|
decodeManifest(outDir);
|
||||||
switch (config.decodeResources) {
|
decodeResources(outDir);
|
||||||
case Config.DECODE_RESOURCES_NONE:
|
|
||||||
copyResourcesRaw(mApkFile, outDir);
|
|
||||||
if (config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
|
|
||||||
// done after raw decoding of resources because copyToDir overwrites dest files
|
|
||||||
if (hasManifest()) {
|
|
||||||
decodeManifestWithResources(mApkFile, outDir, getResTable());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Config.DECODE_RESOURCES_FULL:
|
|
||||||
if (hasManifest()) {
|
|
||||||
decodeManifestWithResources(mApkFile, outDir, getResTable());
|
|
||||||
}
|
|
||||||
decodeResourcesFull(mApkFile, outDir, getResTable());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// if there's no resources.arsc, decode the manifest without looking
|
|
||||||
// up attribute references
|
|
||||||
if (hasManifest()) {
|
|
||||||
if (config.decodeResources == Config.DECODE_RESOURCES_FULL
|
|
||||||
|| config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
|
|
||||||
decodeManifestFull(mApkFile, outDir, getResTable());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
copyManifestRaw(mApkFile, outDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hasSources()) {
|
if (hasSources()) {
|
||||||
switch (config.decodeSources) {
|
switch (config.decodeSources) {
|
||||||
case Config.DECODE_SOURCES_NONE:
|
case Config.DECODE_SOURCES_NONE:
|
||||||
copySourcesRaw(mApkFile, outDir, "classes.dex");
|
copySourcesRaw(outDir, "classes.dex");
|
||||||
break;
|
break;
|
||||||
case Config.DECODE_SOURCES_SMALI:
|
case Config.DECODE_SOURCES_SMALI:
|
||||||
case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
|
case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
|
||||||
decodeSourcesSmali(mApkFile, outDir, "classes.dex");
|
decodeSourcesSmali(outDir, "classes.dex");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,16 +124,16 @@ public class ApkDecoder {
|
|||||||
if (! file.equalsIgnoreCase("classes.dex")) {
|
if (! file.equalsIgnoreCase("classes.dex")) {
|
||||||
switch(config.decodeSources) {
|
switch(config.decodeSources) {
|
||||||
case Config.DECODE_SOURCES_NONE:
|
case Config.DECODE_SOURCES_NONE:
|
||||||
copySourcesRaw(mApkFile, outDir, file);
|
copySourcesRaw(outDir, file);
|
||||||
break;
|
break;
|
||||||
case Config.DECODE_SOURCES_SMALI:
|
case Config.DECODE_SOURCES_SMALI:
|
||||||
decodeSourcesSmali(mApkFile, outDir, file);
|
decodeSourcesSmali(outDir, file);
|
||||||
break;
|
break;
|
||||||
case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
|
case Config.DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
|
||||||
if (file.startsWith("classes") && file.endsWith(".dex")) {
|
if (file.startsWith("classes") && file.endsWith(".dex")) {
|
||||||
decodeSourcesSmali(mApkFile, outDir, file);
|
decodeSourcesSmali(outDir, file);
|
||||||
} else {
|
} else {
|
||||||
copySourcesRaw(mApkFile, outDir, file);
|
copySourcesRaw(outDir, file);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -171,11 +142,11 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
copyRawFiles(mApkFile, outDir);
|
copyRawFiles(outDir);
|
||||||
copyUnknownFiles(mApkFile, outDir);
|
copyUnknownFiles(outDir);
|
||||||
mUncompressedFiles = new ArrayList<>();
|
mUncompressedFiles = new ArrayList<>();
|
||||||
recordUncompressedFiles(mApkFile, mUncompressedFiles);
|
recordUncompressedFiles(mUncompressedFiles);
|
||||||
copyOriginalFiles(mApkFile, outDir);
|
copyOriginalFiles(outDir);
|
||||||
writeMetaFile(outDir);
|
writeMetaFile(outDir);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
@ -276,17 +247,17 @@ public class ApkDecoder {
|
|||||||
return sdkInfo;
|
return sdkInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copySourcesRaw(ExtFile apkFile, File outDir, String filename)
|
private void copySourcesRaw(File outDir, String filename)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
try {
|
try {
|
||||||
LOGGER.info("Copying raw " + filename + " file...");
|
LOGGER.info("Copying raw " + filename + " file...");
|
||||||
apkFile.getDirectory().copyToDir(outDir, filename);
|
mApkFile.getDirectory().copyToDir(outDir, filename);
|
||||||
} catch (DirectoryException ex) {
|
} catch (DirectoryException ex) {
|
||||||
throw new AndrolibException(ex);
|
throw new AndrolibException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeSourcesSmali(File apkFile, File outDir, String filename)
|
private void decodeSourcesSmali(File outDir, String filename)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
try {
|
try {
|
||||||
File smaliDir;
|
File smaliDir;
|
||||||
@ -299,7 +270,7 @@ public class ApkDecoder {
|
|||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
smaliDir.mkdirs();
|
smaliDir.mkdirs();
|
||||||
LOGGER.info("Baksmaling " + filename + "...");
|
LOGGER.info("Baksmaling " + filename + "...");
|
||||||
DexFile dexFile = SmaliDecoder.decode(apkFile, smaliDir, filename,
|
DexFile dexFile = SmaliDecoder.decode(mApkFile, smaliDir, filename,
|
||||||
config.baksmaliDebugMode, config.apiLevel);
|
config.baksmaliDebugMode, config.apiLevel);
|
||||||
int minSdkVersion = dexFile.getOpcodes().api;
|
int minSdkVersion = dexFile.getOpcodes().api;
|
||||||
if (mMinSdkVersion == 0 || mMinSdkVersion > minSdkVersion) {
|
if (mMinSdkVersion == 0 || mMinSdkVersion > minSdkVersion) {
|
||||||
@ -310,46 +281,52 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyManifestRaw(ExtFile apkFile, File outDir)
|
private void decodeManifest(File outDir) throws AndrolibException {
|
||||||
throws AndrolibException {
|
if (hasManifest()) {
|
||||||
try {
|
if (config.decodeResources == Config.DECODE_RESOURCES_FULL ||
|
||||||
LOGGER.info("Copying raw manifest...");
|
config.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
|
||||||
apkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
|
if (hasResources()) {
|
||||||
} catch (DirectoryException ex) {
|
mAndRes.decodeManifestWithResources(getResTable(), mApkFile, outDir);
|
||||||
throw new AndrolibException(ex);
|
} else {
|
||||||
|
// if there's no resources.arsc, decode the manifest without looking
|
||||||
|
// up attribute references
|
||||||
|
mAndRes.decodeManifest(getResTable(), mApkFile, outDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
LOGGER.info("Copying raw manifest...");
|
||||||
|
mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
|
||||||
|
} catch (DirectoryException ex) {
|
||||||
|
throw new AndrolibException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeManifestFull(ExtFile apkFile, File outDir, ResTable resTable)
|
private void decodeResources(File outDir) throws AndrolibException {
|
||||||
throws AndrolibException {
|
if (hasResources()) {
|
||||||
mAndRes.decodeManifest(resTable, apkFile, outDir);
|
switch (config.decodeResources) {
|
||||||
}
|
case Config.DECODE_RESOURCES_NONE:
|
||||||
|
try {
|
||||||
private void copyResourcesRaw(ExtFile apkFile, File outDir)
|
LOGGER.info("Copying raw resources...");
|
||||||
throws AndrolibException {
|
mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
|
||||||
try {
|
} catch (DirectoryException ex) {
|
||||||
LOGGER.info("Copying raw resources...");
|
throw new AndrolibException(ex);
|
||||||
apkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
|
}
|
||||||
} catch (DirectoryException ex) {
|
break;
|
||||||
throw new AndrolibException(ex);
|
case Config.DECODE_RESOURCES_FULL:
|
||||||
|
mAndRes.decode(getResTable(), mApkFile, outDir);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void decodeResourcesFull(ExtFile apkFile, File outDir, ResTable resTable)
|
private void copyRawFiles(File outDir)
|
||||||
throws AndrolibException {
|
|
||||||
mAndRes.decode(resTable, apkFile, outDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void decodeManifestWithResources(ExtFile apkFile, File outDir, ResTable resTable)
|
|
||||||
throws AndrolibException {
|
|
||||||
mAndRes.decodeManifestWithResources(resTable, apkFile, outDir);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void copyRawFiles(ExtFile apkFile, File outDir)
|
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
LOGGER.info("Copying assets and libs...");
|
LOGGER.info("Copying assets and libs...");
|
||||||
try {
|
try {
|
||||||
Directory in = apkFile.getDirectory();
|
Directory in = mApkFile.getDirectory();
|
||||||
|
|
||||||
if (config.decodeAssets == Config.DECODE_ASSETS_FULL) {
|
if (config.decodeAssets == Config.DECODE_ASSETS_FULL) {
|
||||||
if (in.containsDir("assets")) {
|
if (in.containsDir("assets")) {
|
||||||
@ -379,12 +356,12 @@ public class ApkDecoder {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyUnknownFiles(ExtFile apkFile, File outDir)
|
private void copyUnknownFiles(File outDir)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
LOGGER.info("Copying unknown files...");
|
LOGGER.info("Copying unknown files...");
|
||||||
File unknownOut = new File(outDir, UNK_DIRNAME);
|
File unknownOut = new File(outDir, UNK_DIRNAME);
|
||||||
try {
|
try {
|
||||||
Directory unk = apkFile.getDirectory();
|
Directory unk = mApkFile.getDirectory();
|
||||||
|
|
||||||
// loop all items in container recursively, ignoring any that are pre-defined by aapt
|
// loop all items in container recursively, ignoring any that are pre-defined by aapt
|
||||||
Set<String> files = unk.getFiles(true);
|
Set<String> files = unk.getFiles(true);
|
||||||
@ -403,7 +380,7 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyOriginalFiles(ExtFile apkFile, File outDir)
|
private void copyOriginalFiles(File outDir)
|
||||||
throws AndrolibException {
|
throws AndrolibException {
|
||||||
LOGGER.info("Copying original files...");
|
LOGGER.info("Copying original files...");
|
||||||
File originalDir = new File(outDir, "original");
|
File originalDir = new File(outDir, "original");
|
||||||
@ -413,7 +390,7 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Directory in = apkFile.getDirectory();
|
Directory in = mApkFile.getDirectory();
|
||||||
if (in.containsFile("AndroidManifest.xml")) {
|
if (in.containsFile("AndroidManifest.xml")) {
|
||||||
in.copyToDir(originalDir, "AndroidManifest.xml");
|
in.copyToDir(originalDir, "AndroidManifest.xml");
|
||||||
}
|
}
|
||||||
@ -436,9 +413,9 @@ public class ApkDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recordUncompressedFiles(ExtFile apkFile, Collection<String> uncompressedFilesOrExts) throws AndrolibException {
|
private void recordUncompressedFiles(Collection<String> uncompressedFilesOrExts) throws AndrolibException {
|
||||||
try {
|
try {
|
||||||
Directory unk = apkFile.getDirectory();
|
Directory unk = mApkFile.getDirectory();
|
||||||
Set<String> files = unk.getFiles(true);
|
Set<String> files = unk.getFiles(true);
|
||||||
|
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
|
Loading…
Reference in New Issue
Block a user