Skip to content

Commit 089e0fd

Browse files
committed
explicit loading restable
1 parent 6fb0c73 commit 089e0fd

File tree

4 files changed

+96
-52
lines changed

4 files changed

+96
-52
lines changed

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

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import brut.androlib.apk.ApkInfo;
2323
import brut.androlib.res.ResourcesDecoder;
2424
import brut.androlib.res.data.*;
25+
import brut.androlib.res.xml.ResXmlPatcher;
2526
import brut.androlib.src.SmaliDecoder;
2627
import brut.directory.Directory;
2728
import brut.directory.ExtFile;
@@ -50,6 +51,10 @@ public class ApkDecoder {
5051
private final static String[] APK_STANDARD_ALL_FILENAMES = new String[] {
5152
"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "r", "R",
5253
"lib", "libs", "assets", "META-INF", "kotlin" };
54+
private final static String[] APK_RESOURCES_FILENAMES = new String[] {
55+
"resources.arsc", "res", "r", "R" };
56+
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
57+
"AndroidManifest.xml" };
5358
private final static Pattern NO_COMPRESS_PATTERN = Pattern.compile("(" +
5459
"jpg|jpeg|png|gif|wav|mp2|mp3|ogg|aac|mpg|mpeg|mid|midi|smf|jet|rtttl|imy|xmf|mp4|" +
5560
"m4a|m4v|3gp|3gpp|3g2|3gpp2|amr|awb|wma|wmv|webm|webp|mkv)$");
@@ -92,8 +97,27 @@ public ApkInfo decode(File outDir) throws AndrolibException, IOException, Direct
9297
LOGGER.info("Using Apktool " + ApktoolProperties.getVersion() + " on " + mApkFile.getName());
9398

9499
ResourcesDecoder resourcesDecoder = new ResourcesDecoder(mConfig, mApkFile);
95-
resourcesDecoder.decodeManifest(outDir);
96-
resourcesDecoder.decodeResources(outDir);
100+
if (hasResources()) {
101+
switch (mConfig.decodeResources) {
102+
case Config.DECODE_RESOURCES_NONE:
103+
copyResourcesRaw(outDir);
104+
break;
105+
case Config.DECODE_RESOURCES_FULL:
106+
resourcesDecoder.decodeResources(outDir);
107+
break;
108+
}
109+
}
110+
111+
if (hasManifest()) {
112+
if (mConfig.decodeResources == Config.DECODE_RESOURCES_FULL ||
113+
mConfig.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
114+
resourcesDecoder.decodeManifest(outDir);
115+
}
116+
else {
117+
copyManifestRaw(outDir);
118+
}
119+
}
120+
resourcesDecoder.updateApkInfo(outDir);
97121

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

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

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

181+
private boolean hasManifest() throws AndrolibException {
182+
try {
183+
return mApkFile.getDirectory().containsFile("AndroidManifest.xml");
184+
} catch (DirectoryException ex) {
185+
throw new AndrolibException(ex);
186+
}
187+
}
188+
189+
private boolean hasResources() throws AndrolibException {
190+
try {
191+
return mApkFile.getDirectory().containsFile("resources.arsc");
192+
} catch (DirectoryException ex) {
193+
throw new AndrolibException(ex);
194+
}
195+
}
196+
157197
private boolean hasSources() throws AndrolibException {
158198
try {
159199
return mApkFile.getDirectory().containsFile("classes.dex");
@@ -187,6 +227,26 @@ private void writeApkInfo(ApkInfo apkInfo, File outDir) throws AndrolibException
187227
}
188228
}
189229

230+
private void copyManifestRaw(File outDir)
231+
throws AndrolibException {
232+
try {
233+
LOGGER.info("Copying raw manifest...");
234+
mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
235+
} catch (DirectoryException ex) {
236+
throw new AndrolibException(ex);
237+
}
238+
}
239+
240+
private void copyResourcesRaw(File outDir)
241+
throws AndrolibException {
242+
try {
243+
LOGGER.info("Copying raw resources...");
244+
mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
245+
} catch (DirectoryException ex) {
246+
throw new AndrolibException(ex);
247+
}
248+
}
249+
190250
private void copySourcesRaw(File outDir, String filename)
191251
throws AndrolibException {
192252
try {

brut.apktool/apktool-lib/src/main/java/brut/androlib/res/ResourcesDecoder.java

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import brut.directory.ExtFile;
3131
import brut.directory.FileDirectory;
3232
import brut.util.Duo;
33+
import com.sun.org.apache.xpath.internal.operations.And;
3334
import org.xmlpull.v1.XmlSerializer;
3435

3536
import java.io.File;
@@ -48,10 +49,6 @@ public class ResourcesDecoder {
4849
private final ApkInfo mApkInfo;
4950
private final Map<String, String> mResFileMapping = new HashMap<>();
5051

51-
private final static String[] APK_RESOURCES_FILENAMES = new String[] {
52-
"resources.arsc", "res", "r", "R" };
53-
private final static String[] APK_MANIFEST_FILENAMES = new String[] {
54-
"AndroidManifest.xml" };
5552
private final static String[] IGNORED_PACKAGES = new String[] {
5653
"android", "com.htc", "com.lge", "com.lge.internal", "yi", "flyme", "air.com.adobe.appentry",
5754
"FFFFFFFFFFFFFFFFFFFFFF" };
@@ -85,9 +82,9 @@ public ResTable getResTable() throws AndrolibException {
8582
throw new AndrolibException(
8683
"Apk doesn't contain either AndroidManifest.xml file or resources.arsc file");
8784
}
88-
if (hasResources() && !mResTable.isMainPkgLoaded()) {
89-
mResTable.loadMainPkg(mApkFile);
90-
}
85+
// if (hasResources() && !mResTable.isMainPkgLoaded()) {
86+
// mResTable.loadMainPkg(mApkFile);
87+
// }
9188
return mResTable;
9289
}
9390

@@ -101,38 +98,31 @@ public Map<String, String> getResFileMapping() {
10198

10299
public void decodeManifest(File outDir) throws AndrolibException {
103100
if (hasManifest()) {
104-
if (mConfig.decodeResources == Config.DECODE_RESOURCES_FULL ||
105-
mConfig.forceDecodeManifest == Config.FORCE_DECODE_MANIFEST_FULL) {
106-
decodeManifest(getResTable(), mApkFile, outDir);
107-
if (hasResources()) {
108-
if (!mConfig.analysisMode) {
109-
// Remove versionName / versionCode (aapt API 16)
110-
//
111-
// check for a mismatch between resources.arsc package and the package listed in AndroidManifest
112-
// also remove the android::versionCode / versionName from manifest for rebuild
113-
// this is a required change to prevent aapt warning about conflicting versions
114-
// it will be passed as a parameter to aapt like "--min-sdk-version" via apktool.yml
115-
adjustPackageManifest(getResTable(), outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml");
116-
117-
ResXmlPatcher.removeManifestVersions(new File(
118-
outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml"));
119-
120-
// update apk info
121-
mApkInfo.packageInfo.forcedPackageId = String.valueOf(mResTable.getPackageId());
122-
}
123-
}
124-
}
125-
else {
126-
try {
127-
LOGGER.info("Copying raw manifest...");
128-
mApkFile.getDirectory().copyToDir(outDir, APK_MANIFEST_FILENAMES);
129-
} catch (DirectoryException ex) {
130-
throw new AndrolibException(ex);
101+
decodeManifest(getResTable(), mApkFile, outDir);
102+
if (hasResources()) {
103+
if (!mConfig.analysisMode) {
104+
// Remove versionName / versionCode (aapt API 16)
105+
//
106+
// check for a mismatch between resources.arsc package and the package listed in AndroidManifest
107+
// also remove the android::versionCode / versionName from manifest for rebuild
108+
// this is a required change to prevent aapt warning about conflicting versions
109+
// it will be passed as a parameter to aapt like "--min-sdk-version" via apktool.yml
110+
adjustPackageManifest(getResTable(), outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml");
111+
112+
ResXmlPatcher.removeManifestVersions(new File(
113+
outDir.getAbsolutePath() + File.separator + "AndroidManifest.xml"));
114+
115+
// update apk info
116+
mApkInfo.packageInfo.forcedPackageId = String.valueOf(mResTable.getPackageId());
131117
}
132118
}
133119
}
134120
}
135121

122+
public void updateApkInfo(File outDir) throws AndrolibException {
123+
mResTable.initApkInfo(mApkInfo, outDir);
124+
}
125+
136126
private void decodeManifest(ResTable resTable, ExtFile apkFile, File outDir)
137127
throws AndrolibException {
138128

@@ -191,22 +181,14 @@ private ExtMXSerializer getResXmlSerializer() {
191181
return serial;
192182
}
193183

184+
public void load() throws AndrolibException {
185+
mResTable.loadMainPkg(mApkFile);
186+
}
187+
194188
public ResTable decodeResources(File outDir) throws AndrolibException {
195189
if (hasResources()) {
196-
switch (mConfig.decodeResources) {
197-
case Config.DECODE_RESOURCES_NONE:
198-
try {
199-
LOGGER.info("Copying raw resources...");
200-
mApkFile.getDirectory().copyToDir(outDir, APK_RESOURCES_FILENAMES);
201-
} catch (DirectoryException ex) {
202-
throw new AndrolibException(ex);
203-
}
204-
break;
205-
case Config.DECODE_RESOURCES_FULL:
206-
decodeResources(getResTable(), mApkFile, outDir);
207-
break;
208-
}
209-
mResTable.initApkInfo(mApkInfo, outDir);
190+
load();
191+
decodeResources(getResTable(), mApkFile, outDir);
210192
}
211193
return mResTable;
212194
}

brut.apktool/apktool-lib/src/test/java/brut/androlib/aapt2/NonStandardPkgIdTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ public static void beforeClass() throws Exception {
5858
Config.getDefaultConfig(), new ExtFile(testApk));
5959

6060
sTestNewDir.mkdirs();
61-
resourcesDecoder.decodeManifest(sTestNewDir);
6261
mResTable = resourcesDecoder.decodeResources(sTestNewDir);
62+
resourcesDecoder.decodeManifest(sTestNewDir);
6363
}
6464

6565
@AfterClass

brut.apktool/apktool-lib/src/test/java/brut/androlib/decode/DecodeArrayTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ public void decodeStringArray() throws BrutException {
5757
Config.getDefaultConfig(),
5858
new ExtFile(sTmpDir + File.separator + apk));
5959

60+
resourcesDecoder.load();
6061
ResTable resTable = resourcesDecoder.getResTable();
6162
ResValue value = resTable.getResSpec(0x7f020001).getDefaultResource().getValue();
6263

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

74+
resourcesDecoder.load();
7375
ResTable resTable = resourcesDecoder.getResTable();
7476
ResValue value = resTable.getResSpec(0x7f020000).getDefaultResource().getValue();
7577

0 commit comments

Comments
 (0)