Merge pull request #2604 from IgorEisberg/master

Fix baksmali without API version and various optimizations
This commit is contained in:
Connor Tumbleson 2021-07-03 17:41:22 -04:00 committed by GitHub
commit d1e4478f82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 50 additions and 74 deletions

View File

@ -149,10 +149,10 @@ public class Main {
decoder.setFrameworkDir(cli.getOptionValue("p")); decoder.setFrameworkDir(cli.getOptionValue("p"));
} }
if (cli.hasOption("m") || cli.hasOption("match-original")) { if (cli.hasOption("m") || cli.hasOption("match-original")) {
decoder.setAnalysisMode(true, false); decoder.setAnalysisMode(true);
} }
if (cli.hasOption("api") || cli.hasOption("api-level")) { if (cli.hasOption("api") || cli.hasOption("api-level")) {
decoder.setApi(Integer.parseInt(cli.getOptionValue("api"))); decoder.setApiLevel(Integer.parseInt(cli.getOptionValue("api")));
} }
if (cli.hasOption("o") || cli.hasOption("output")) { if (cli.hasOption("o") || cli.hasOption("output")) {
outDir = new File(cli.getOptionValue("o")); outDir = new File(cli.getOptionValue("o"));

View File

@ -31,8 +31,7 @@ import brut.androlib.src.SmaliBuilder;
import brut.androlib.src.SmaliDecoder; import brut.androlib.src.SmaliDecoder;
import brut.common.BrutException; import brut.common.BrutException;
import brut.directory.*; import brut.directory.*;
import brut.util.BrutIO; import brut.util.*;
import brut.util.OS;
import java.io.*; import java.io.*;
import java.util.*; import java.util.*;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -81,7 +80,7 @@ public class Androlib {
} }
} }
public void decodeSourcesSmali(File apkFile, File outDir, String filename, boolean bakdeb, int api) public void decodeSourcesSmali(File apkFile, File outDir, String filename, boolean bakDeb, int apiLevel)
throws AndrolibException { throws AndrolibException {
try { try {
File smaliDir; File smaliDir;
@ -93,7 +92,7 @@ public class Androlib {
OS.rmdir(smaliDir); OS.rmdir(smaliDir);
smaliDir.mkdirs(); smaliDir.mkdirs();
LOGGER.info("Baksmaling " + filename + "..."); LOGGER.info("Baksmaling " + filename + "...");
SmaliDecoder.decode(apkFile, smaliDir, filename, bakdeb, api); SmaliDecoder.decode(apkFile, smaliDir, filename, bakDeb, apiLevel);
} catch (BrutException ex) { } catch (BrutException ex) {
throw new AndrolibException(ex); throw new AndrolibException(ex);
} }
@ -193,7 +192,7 @@ public class Androlib {
return false; return false;
} }
public void decodeUnknownFiles(ExtFile apkFile, File outDir, ResTable resTable) public void decodeUnknownFiles(ExtFile apkFile, 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);

View File

@ -67,14 +67,10 @@ public class ApkDecoder {
mResTable = null; mResTable = null;
} }
public void setOutDir(File outDir) throws AndrolibException { public void setOutDir(File outDir) {
mOutDir = outDir; mOutDir = outDir;
} }
public void setApi(int api) {
mApi = api;
}
public void decode() throws AndrolibException, IOException, DirectoryException { public void decode() throws AndrolibException, IOException, DirectoryException {
try { try {
File outDir = getOutDir(); File outDir = getOutDir();
@ -102,9 +98,6 @@ public class ApkDecoder {
case DECODE_RESOURCES_NONE: case DECODE_RESOURCES_NONE:
mAndrolib.decodeResourcesRaw(mApkFile, outDir); mAndrolib.decodeResourcesRaw(mApkFile, outDir);
if (mForceDecodeManifest == FORCE_DECODE_MANIFEST_FULL) { if (mForceDecodeManifest == FORCE_DECODE_MANIFEST_FULL) {
setTargetSdkVersion();
setAnalysisMode(mAnalysisMode, true);
// done after raw decoding of resources because copyToDir overwrites dest files // done after raw decoding of resources because copyToDir overwrites dest files
if (hasManifest()) { if (hasManifest()) {
mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable()); mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable());
@ -112,9 +105,6 @@ public class ApkDecoder {
} }
break; break;
case DECODE_RESOURCES_FULL: case DECODE_RESOURCES_FULL:
setTargetSdkVersion();
setAnalysisMode(mAnalysisMode, true);
if (hasManifest()) { if (hasManifest()) {
mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable()); mAndrolib.decodeManifestWithResources(mApkFile, outDir, getResTable());
} }
@ -142,7 +132,7 @@ public class ApkDecoder {
break; break;
case DECODE_SOURCES_SMALI: case DECODE_SOURCES_SMALI:
case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
mAndrolib.decodeSourcesSmali(mApkFile, outDir, "classes.dex", mBakDeb, mApi); mAndrolib.decodeSourcesSmali(mApkFile, outDir, "classes.dex", mBakDeb, mApiLevel);
break; break;
} }
} }
@ -158,11 +148,11 @@ public class ApkDecoder {
mAndrolib.decodeSourcesRaw(mApkFile, outDir, file); mAndrolib.decodeSourcesRaw(mApkFile, outDir, file);
break; break;
case DECODE_SOURCES_SMALI: case DECODE_SOURCES_SMALI:
mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi); mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApiLevel);
break; break;
case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES: case DECODE_SOURCES_SMALI_ONLY_MAIN_CLASSES:
if (file.startsWith("classes") && file.endsWith(".dex")) { if (file.startsWith("classes") && file.endsWith(".dex")) {
mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApi); mAndrolib.decodeSourcesSmali(mApkFile, outDir, file, mBakDeb, mApiLevel);
} else { } else {
mAndrolib.decodeSourcesRaw(mApkFile, outDir, file); mAndrolib.decodeSourcesRaw(mApkFile, outDir, file);
} }
@ -174,7 +164,7 @@ public class ApkDecoder {
} }
mAndrolib.decodeRawFiles(mApkFile, outDir, mDecodeAssets); mAndrolib.decodeRawFiles(mApkFile, outDir, mDecodeAssets);
mAndrolib.decodeUnknownFiles(mApkFile, outDir, mResTable); mAndrolib.decodeUnknownFiles(mApkFile, outDir);
mUncompressedFiles = new ArrayList<String>(); mUncompressedFiles = new ArrayList<String>();
mAndrolib.recordUncompressedFiles(mApkFile, mUncompressedFiles); mAndrolib.recordUncompressedFiles(mApkFile, mUncompressedFiles);
mAndrolib.writeOriginalFiles(mApkFile, outDir); mAndrolib.writeOriginalFiles(mApkFile, outDir);
@ -216,31 +206,20 @@ public class ApkDecoder {
mDecodeAssets = mode; mDecodeAssets = mode;
} }
public void setAnalysisMode(boolean mode, boolean pass) throws AndrolibException{ public void setAnalysisMode(boolean mode) {
mAnalysisMode = mode; mAnalysisMode = mode;
// only set mResTable, once it exists if (mResTable != null) {
if (pass) {
if (mResTable == null) {
mResTable = getResTable();
}
mResTable.setAnalysisMode(mode); mResTable.setAnalysisMode(mode);
} }
} }
public void setTargetSdkVersion() throws AndrolibException { public void setApiLevel(int apiLevel) {
if (mResTable == null) { mApiLevel = apiLevel;
mResTable = mAndrolib.getResTable(mApkFile);
}
Map<String, String> sdkInfo = mResTable.getSdkInfo();
if (sdkInfo.get("targetSdkVersion") != null) {
mApi = Integer.parseInt(sdkInfo.get("targetSdkVersion"));
}
} }
public void setBaksmaliDebugMode(boolean bakdeb) { public void setBaksmaliDebugMode(boolean bakDeb) {
mBakDeb = bakdeb; mBakDeb = bakDeb;
} }
public void setForceDelete(boolean forceDelete) { public void setForceDelete(boolean forceDelete) {
@ -268,6 +247,7 @@ public class ApkDecoder {
"Apk doesn't contain either AndroidManifest.xml file or resources.arsc file"); "Apk doesn't contain either AndroidManifest.xml file or resources.arsc file");
} }
mResTable = mAndrolib.getResTable(mApkFile, hasResources); mResTable = mAndrolib.getResTable(mApkFile, hasResources);
mResTable.setAnalysisMode(mAnalysisMode);
} }
return mResTable; return mResTable;
} }
@ -344,8 +324,8 @@ public class ApkDecoder {
meta.version = Androlib.getVersion(); meta.version = Androlib.getVersion();
meta.apkFileName = mApkFile.getName(); meta.apkFileName = mApkFile.getName();
if (mDecodeResources != DECODE_RESOURCES_NONE && (hasManifest() || hasResources())) { if (mResTable != null) {
meta.isFrameworkApk = mAndrolib.isFrameworkApk(getResTable()); meta.isFrameworkApk = mAndrolib.isFrameworkApk(mResTable);
putUsesFramework(meta); putUsesFramework(meta);
putSdkInfo(meta); putSdkInfo(meta);
putPackageInfo(meta); putPackageInfo(meta);
@ -359,8 +339,8 @@ public class ApkDecoder {
mAndrolib.writeMetaFile(mOutDir, meta); mAndrolib.writeMetaFile(mOutDir, meta);
} }
private void putUsesFramework(MetaInfo meta) throws AndrolibException { private void putUsesFramework(MetaInfo meta) {
Set<ResPackage> pkgs = getResTable().listFramePackages(); Set<ResPackage> pkgs = mResTable.listFramePackages();
if (pkgs.isEmpty()) { if (pkgs.isEmpty()) {
return; return;
} }
@ -380,8 +360,8 @@ public class ApkDecoder {
} }
} }
private void putSdkInfo(MetaInfo meta) throws AndrolibException { private void putSdkInfo(MetaInfo meta) {
Map<String, String> info = getResTable().getSdkInfo(); Map<String, String> info = mResTable.getSdkInfo();
if (info.size() > 0) { if (info.size() > 0) {
String refValue; String refValue;
if (info.get("minSdkVersion") != null) { if (info.get("minSdkVersion") != null) {
@ -407,12 +387,12 @@ public class ApkDecoder {
} }
private void putPackageInfo(MetaInfo meta) throws AndrolibException { private void putPackageInfo(MetaInfo meta) throws AndrolibException {
String renamed = getResTable().getPackageRenamed(); String renamed = mResTable.getPackageRenamed();
String original = getResTable().getPackageOriginal(); String original = mResTable.getPackageOriginal();
int id = getResTable().getPackageId(); int id = mResTable.getPackageId();
try { try {
id = getResTable().getPackage(renamed).getId(); id = mResTable.getPackage(renamed).getId();
} catch (UndefinedResObjectException ignored) {} } catch (UndefinedResObjectException ignored) {}
if (Strings.isNullOrEmpty(original)) { if (Strings.isNullOrEmpty(original)) {
@ -428,8 +408,8 @@ public class ApkDecoder {
meta.packageInfo.forcedPackageId = String.valueOf(id); meta.packageInfo.forcedPackageId = String.valueOf(id);
} }
private void putVersionInfo(MetaInfo meta) throws AndrolibException { private void putVersionInfo(MetaInfo meta) {
VersionInfo info = getResTable().getVersionInfo(); VersionInfo info = mResTable.getVersionInfo();
String refValue = ResXmlPatcher.pullValueFromStrings(mOutDir, info.versionName); String refValue = ResXmlPatcher.pullValueFromStrings(mOutDir, info.versionName);
if (refValue != null) { if (refValue != null) {
info.versionName = refValue; info.versionName = refValue;
@ -437,6 +417,14 @@ public class ApkDecoder {
meta.versionInfo = info; meta.versionInfo = info;
} }
private void putSharedLibraryInfo(MetaInfo meta) {
meta.sharedLibrary = mResTable.getSharedLibrary();
}
private void putSparseResourcesInfo(MetaInfo meta) {
meta.sparseResources = mResTable.getSparseResources();
}
private void putUnknownInfo(MetaInfo meta) { private void putUnknownInfo(MetaInfo meta) {
meta.unknownFiles = mAndrolib.mResUnknownFiles.getUnknownFiles(); meta.unknownFiles = mAndrolib.mResUnknownFiles.getUnknownFiles();
} }
@ -447,14 +435,6 @@ public class ApkDecoder {
} }
} }
private void putSparseResourcesInfo(MetaInfo meta) {
meta.sparseResources = mResTable.getSparseResources();
}
private void putSharedLibraryInfo(MetaInfo meta) {
meta.sharedLibrary = mResTable.getSharedLibrary();
}
private final Androlib mAndrolib; private final Androlib mAndrolib;
private final static Logger LOGGER = Logger.getLogger(Androlib.class.getName()); private final static Logger LOGGER = Logger.getLogger(Androlib.class.getName());
@ -471,5 +451,5 @@ public class ApkDecoder {
private boolean mBakDeb = true; private boolean mBakDeb = true;
private Collection<String> mUncompressedFiles; private Collection<String> mUncompressedFiles;
private boolean mAnalysisMode = false; private boolean mAnalysisMode = false;
private int mApi = 15; private int mApiLevel = 0;
} }

View File

@ -26,12 +26,12 @@ import brut.androlib.res.data.*;
import brut.androlib.res.decoder.*; import brut.androlib.res.decoder.*;
import brut.androlib.res.decoder.ARSCDecoder.ARSCData; import brut.androlib.res.decoder.ARSCDecoder.ARSCData;
import brut.androlib.res.decoder.ARSCDecoder.FlagsOffset; import brut.androlib.res.decoder.ARSCDecoder.FlagsOffset;
import brut.directory.*;
import brut.androlib.res.util.ExtMXSerializer; import brut.androlib.res.util.ExtMXSerializer;
import brut.androlib.res.util.ExtXmlSerializer; import brut.androlib.res.util.ExtXmlSerializer;
import brut.androlib.res.xml.ResValuesXmlSerializable; import brut.androlib.res.xml.ResValuesXmlSerializable;
import brut.androlib.res.xml.ResXmlPatcher; import brut.androlib.res.xml.ResXmlPatcher;
import brut.common.BrutException; import brut.common.BrutException;
import brut.directory.*;
import brut.util.*; import brut.util.*;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.xmlpull.v1.XmlSerializer; import org.xmlpull.v1.XmlSerializer;

View File

@ -32,14 +32,11 @@ import java.io.InputStream;
import java.util.logging.Logger; import java.util.logging.Logger;
public class SmaliBuilder { public class SmaliBuilder {
public static void build(ExtFile smaliDir, File dexFile, int apiLevel) throws AndrolibException { public static void build(ExtFile smaliDir, File dexFile, int apiLevel) throws AndrolibException {
new SmaliBuilder(smaliDir, dexFile, apiLevel).build(); new SmaliBuilder(smaliDir, dexFile, apiLevel).build();
} }
public static void build(ExtFile smaliDir, File dexFile) throws AndrolibException {
new SmaliBuilder(smaliDir, dexFile, 0).build();
}
private SmaliBuilder(ExtFile smaliDir, File dexFile, int apiLevel) { private SmaliBuilder(ExtFile smaliDir, File dexFile, int apiLevel) {
mSmaliDir = smaliDir; mSmaliDir = smaliDir;
mDexFile = dexFile; mDexFile = dexFile;
@ -85,7 +82,7 @@ public class SmaliBuilder {
private final ExtFile mSmaliDir; private final ExtFile mSmaliDir;
private final File mDexFile; private final File mDexFile;
private int mApiLevel = 0; private final int mApiLevel;
private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class.getName()); private final static Logger LOGGER = Logger.getLogger(SmaliBuilder.class.getName());
} }

View File

@ -31,17 +31,17 @@ import java.io.IOException;
public class SmaliDecoder { public class SmaliDecoder {
public static void decode(File apkFile, File outDir, String dexName, boolean bakdeb, int api) public static void decode(File apkFile, File outDir, String dexName, boolean bakDeb, int apiLevel)
throws AndrolibException { throws AndrolibException {
new SmaliDecoder(apkFile, outDir, dexName, bakdeb, api).decode(); new SmaliDecoder(apkFile, outDir, dexName, bakDeb, apiLevel).decode();
} }
private SmaliDecoder(File apkFile, File outDir, String dexName, boolean bakdeb, int api) { private SmaliDecoder(File apkFile, File outDir, String dexName, boolean bakDeb, int apiLevel) {
mApkFile = apkFile; mApkFile = apkFile;
mOutDir = outDir; mOutDir = outDir;
mDexFile = dexName; mDexFile = dexName;
mBakDeb = bakdeb; mBakDeb = bakDeb;
mApi = api; mApiLevel = apiLevel;
} }
private void decode() throws AndrolibException { private void decode() throws AndrolibException {
@ -67,7 +67,7 @@ public class SmaliDecoder {
} }
// create the container // create the container
MultiDexContainer<? extends DexBackedDexFile> container = DexFileFactory.loadDexContainer(mApkFile, Opcodes.forApi(mApi)); MultiDexContainer<? extends DexBackedDexFile> container = DexFileFactory.loadDexContainer(mApkFile, mApiLevel > 0 ? Opcodes.forApi(mApiLevel) : null);
MultiDexContainer.DexEntry<? extends DexBackedDexFile> dexEntry; MultiDexContainer.DexEntry<? extends DexBackedDexFile> dexEntry;
DexBackedDexFile dexFile; DexBackedDexFile dexFile;
@ -105,5 +105,5 @@ public class SmaliDecoder {
private final File mOutDir; private final File mOutDir;
private final String mDexFile; private final String mDexFile;
private final boolean mBakDeb; private final boolean mBakDeb;
private final int mApi; private final int mApiLevel;
} }