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"));
}
if (cli.hasOption("m") || cli.hasOption("match-original")) {
decoder.setAnalysisMode(true, false);
decoder.setAnalysisMode(true);
}
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")) {
outDir = new File(cli.getOptionValue("o"));

View File

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

View File

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

View File

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

View File

@ -31,17 +31,17 @@ import java.io.IOException;
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 {
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;
mOutDir = outDir;
mOutDir = outDir;
mDexFile = dexName;
mBakDeb = bakdeb;
mApi = api;
mBakDeb = bakDeb;
mApiLevel = apiLevel;
}
private void decode() throws AndrolibException {
@ -67,7 +67,7 @@ public class SmaliDecoder {
}
// 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;
DexBackedDexFile dexFile;
@ -105,5 +105,5 @@ public class SmaliDecoder {
private final File mOutDir;
private final String mDexFile;
private final boolean mBakDeb;
private final int mApi;
private final int mApiLevel;
}