Skip to content

Commit

Permalink
explicit loading restable
Browse files Browse the repository at this point in the history
  • Loading branch information
sv99 committed Jul 24, 2023
1 parent 6fb0c73 commit e58d28b
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import brut.androlib.apk.ApkInfo;
import brut.androlib.res.ResourcesDecoder;
import brut.androlib.res.data.*;
import brut.androlib.res.xml.ResXmlPatcher;
import brut.androlib.src.SmaliDecoder;
import brut.directory.Directory;
import brut.directory.ExtFile;
Expand Down Expand Up @@ -50,6 +51,10 @@ public class ApkDecoder {
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "r", "R",
"lib", "libs", "assets", "META-INF", "kotlin" };
private final static String[] APK_RESOURCES_FILENAMES = new String[] {
"resources.arsc", "res", "r", "R" };
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
"AndroidManifest.xml" };
private final static Pattern NO_COMPRESS_PATTERN = Pattern.compile("(" +
"jpg|jpeg|png|gif|wav|mp2|mp3|ogg|aac|mpg|mpeg|mid|midi|smf|jet|rtttl|imy|xmf|mp4|" +
"m4a|m4v|3gp|3gpp|3g2|3gpp2|amr|awb|wma|wmv|webm|webp|mkv)$");
Expand Down Expand Up @@ -92,8 +97,27 @@ public ApkInfo decode(File outDir) throws AndrolibException, IOException, Direct
LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName());

ResourcesDecoder resourcesDecoder = new ResourcesDecoder(mConfig, mApkFile);
resourcesDecoder.decodeManifest(outDir);
resourcesDecoder.decodeResources(outDir);
if (hasResources()) {
switch (mConfig.decodeResources) {
case Config.DECODE_RESOURCES_NONE:
copyResourcesRaw(outDir);
break;
case Config.DECODE_RESOURCES_FULL:
resourcesDecoder.decodeResources(outDir);
break;
}
}

if (hasManifest()) {
if (mConfig.decodeResources == Config.DECODE_RESOURCES_FULL ||
mConfig.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
resourcesDecoder.decodeManifest(outDir);
}
else {
copyManifestRaw(outDir);
}
}
resourcesDecoder.updateApkInfo(outDir);

if (hasSources()) {
switch (mConfig.decodeSources) {
Expand Down Expand Up @@ -135,7 +159,7 @@ public ApkInfo decode(File outDir) throws AndrolibException, IOException, Direct

// In case we have no resources. We should store the minSdk we pulled from the source opcode api level
ApkInfo apkInfo = resourcesDecoder.getApkInfo();
if (! resourcesDecoder.hasResources() && mMinSdkVersion > 0) {
if (!hasResources() && mMinSdkVersion > 0) {
apkInfo.setSdkInfoField("minSdkVersion", Integer.toString(mMinSdkVersion));
}

Expand All @@ -154,6 +178,22 @@ public ApkInfo decode(File outDir) throws AndrolibException, IOException, Direct
}
}

private boolean hasManifest() throws AndrolibException {
try {
return mApkFile.getDirectory().containsFile("AndroidManifest.xml");
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}

private boolean hasResources() throws AndrolibException {
try {
return mApkFile.getDirectory().containsFile("resources.arsc");
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}

private boolean hasSources() throws AndrolibException {
try {
return mApkFile.getDirectory().containsFile("classes.dex");
Expand Down Expand Up @@ -187,6 +227,26 @@ private void writeApkInfo(ApkInfo apkInfo, File outDir) throws AndrolibException
}
}

private void copyManifestRaw(File outDir)
throws AndrolibException {
try {
LOGGER.info("Copying raw manifest...");
mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}

private void copyResourcesRaw(File outDir)
throws AndrolibException {
try {
LOGGER.info("Copying raw resources...");
mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
}

private void copySourcesRaw(File outDir, String filename)
throws AndrolibException {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import brut.directory.DirectoryException;
import brut.directory.ExtFile;
import brut.directory.FileDirectory;
import brut.util.Duo;
import org.xmlpull.v1.XmlSerializer;

import java.io.File;
Expand All @@ -48,10 +47,6 @@ public class ResourcesDecoder {
private final ApkInfo mApkInfo;
private final Map<String, String> mResFileMapping = new HashMap<>();

private final static String[] APK_RESOURCES_FILENAMES = new String[] {
"resources.arsc", "res", "r", "R" };
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
"AndroidManifest.xml" };
private final static String[] IGNORED_PACKAGES = new String[] {
"android", "com.htc", "com.lge", "com.lge.internal", "yi", "flyme", "air.com.adobe.appentry",
"FFFFFFFFFFFFFFFFFFFFFF" };
Expand Down Expand Up @@ -85,9 +80,6 @@ public ResTable getResTable() throws AndrolibException {
throw new AndrolibException(
"Apk doesn't contain either AndroidManifest.xml file or resources.arsc file");
}
if (hasResources() && !mResTable.isMainPkgLoaded()) {
mResTable.loadMainPkg(mApkFile);
}
return mResTable;
}

Expand All @@ -101,38 +93,31 @@ public Map<String, String> getResFileMapping() {

public void decodeManifest(File outDir) throws AndrolibException {
if (hasManifest()) {
if (mConfig.decodeResources == Config.DECODE_RESOURCES_FULL ||
mConfig.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
decodeManifest(getResTable(), mApkFile, outDir);
if (hasResources()) {
if (!mConfig.analysisMode) {
// Remove versionName / versionCode (aapt API 16)
//
// check for a mismatch between resources.arsc package and the package listed in AndroidManifest
// also remove the android::versionCode / versionName from manifest for rebuild
// this is a required change to prevent aapt warning about conflicting versions
// it will be passed as a parameter to aapt like "--min-sdk-version" via apktool.yml
adjustPackageManifest(getResTable(), outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml");

ResXmlPatcher.removeManifestVersions(new File(
outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml"));

// update apk info
mApkInfo.packageInfo.forcedPackageId = String.valueOf(mResTable.getPackageId());
}
}
}
else {
try {
LOGGER.info("Copying raw manifest...");
mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
decodeManifest(getResTable(), mApkFile, outDir);
if (hasResources()) {
if (!mConfig.analysisMode) {
// Remove versionName / versionCode (aapt API 16)
//
// check for a mismatch between resources.arsc package and the package listed in AndroidManifest
// also remove the android::versionCode / versionName from manifest for rebuild
// this is a required change to prevent aapt warning about conflicting versions
// it will be passed as a parameter to aapt like "--min-sdk-version" via apktool.yml
adjustPackageManifest(getResTable(), outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml");

ResXmlPatcher.removeManifestVersions(new File(
outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml"));

// update apk info
mApkInfo.packageInfo.forcedPackageId = String.valueOf(mResTable.getPackageId());
}
}
}
}

public void updateApkInfo(File outDir) throws AndrolibException {
mResTable.initApkInfo(mApkInfo, outDir);
}

private void decodeManifest(ResTable resTable, ExtFile apkFile, File outDir)
throws AndrolibException {

Expand Down Expand Up @@ -191,22 +176,14 @@ private ExtMXSerializer getResXmlSerializer() {
return serial;
}

public void loadMainPkg() throws AndrolibException {
mResTable.loadMainPkg(mApkFile);
}

public ResTable decodeResources(File outDir) throws AndrolibException {
if (hasResources()) {
switch (mConfig.decodeResources) {
case Config.DECODE_RESOURCES_NONE:
try {
LOGGER.info("Copying raw resources...");
mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
} catch (DirectoryException ex) {
throw new AndrolibException(ex);
}
break;
case Config.DECODE_RESOURCES_FULL:
decodeResources(getResTable(), mApkFile, outDir);
break;
}
mResTable.initApkInfo(mApkInfo, outDir);
loadMainPkg();
decodeResources(getResTable(), mApkFile, outDir);
}
return mResTable;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ public static void beforeClass() throws Exception {
Config.getDefaultConfig(), new ExtFile(testApk));

sTestNewDir.mkdirs();
resourcesDecoder.decodeManifest(sTestNewDir);
mResTable = resourcesDecoder.decodeResources(sTestNewDir);
resourcesDecoder.decodeManifest(sTestNewDir);
}

@AfterClass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void decodeStringArray() throws BrutException {
Config.getDefaultConfig(),
new ExtFile(sTmpDir + File.separator + apk));

resourcesDecoder.loadMainPkg();
ResTable resTable = resourcesDecoder.getResTable();
ResValue value = resTable.getResSpec(0x7f020001).getDefaultResource().getValue();

Expand All @@ -70,6 +71,7 @@ public void decodeArray() throws BrutException {
Config.getDefaultConfig(),
new ExtFile(sTmpDir + File.separator + apk));

resourcesDecoder.loadMainPkg();
ResTable resTable = resourcesDecoder.getResTable();
ResValue value = resTable.getResSpec(0x7f020000).getDefaultResource().getValue();

Expand Down

0 comments on commit e58d28b

Please sign in to comment.