Skip to content

Commit

Permalink
[Refactor] Fix parsing AndroidManifest using ARSCLib
Browse files Browse the repository at this point in the history
Signed-off-by: Muntashir Al-Islam <[email protected]>
  • Loading branch information
MuntashirAkon committed Dec 7, 2024
1 parent 15dc03a commit 9338ab2
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
import androidx.annotation.WorkerThread;
import androidx.core.content.pm.PackageInfoCompat;

import com.reandroid.xml.XMLAttribute;
import com.reandroid.xml.XMLDocument;
import com.reandroid.xml.XMLElement;
import com.reandroid.arsc.chunk.xml.ResXmlAttribute;
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
import com.reandroid.arsc.chunk.xml.ResXmlElement;
import com.reandroid.arsc.io.BlockReader;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
Expand All @@ -31,6 +32,7 @@
import java.nio.ByteBuffer;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Objects;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
Expand Down Expand Up @@ -187,36 +189,51 @@ public static ByteBuffer getManifestFromApk(InputStream apkInputStream) throws I
@NonNull
public static HashMap<String, String> getManifestAttributes(@NonNull ByteBuffer manifestBytes)
throws ApkFile.ApkFileException, IOException {
HashMap<String, String> manifestAttrs = new HashMap<>();
XMLDocument xmlDocument = AndroidBinXmlDecoder.decodeToXml(manifestBytes);
XMLElement manifestElement = xmlDocument.getDocumentElement();
if (!"manifest".equals(manifestElement.getName())) {
throw new ApkFile.ApkFileException("No manifest found.");
}
for (XMLAttribute attribute : manifestElement.listAttributes()) {
if (attribute.getName().isEmpty()) {
continue;
try (BlockReader reader = new BlockReader(manifestBytes.array())) {
HashMap<String, String> manifestAttrs = new HashMap<>();
ResXmlDocument xmlBlock = new ResXmlDocument();
xmlBlock.readBytes(reader);
xmlBlock.setPackageBlock(AndroidBinXmlDecoder.getFrameworkPackageBlock());
ResXmlElement resManifestElement = xmlBlock.getDocumentElement();
// manifest
if (!"manifest".equals(resManifestElement.getName())) {
throw new ApkFile.ApkFileException("No manifest found.");
}
manifestAttrs.put(attribute.getName(), attribute.getValueAsString());
}
XMLElement androidElement = null;
for (XMLElement elem : manifestElement.getChildElementList()) {
if ("application".equals(elem.getName())) {
androidElement = elem;
break;
Iterator<ResXmlAttribute> attrIt = resManifestElement.getAttributes();
ResXmlAttribute attr;
String attrName;
while (attrIt.hasNext()) {
attr = attrIt.next();
attrName = attr.getName();
if (attrName == null || attrName.isEmpty()) {
continue;
}
manifestAttrs.put(attrName, attr.getValueAsString());
}
}
if (androidElement == null) {
Log.w("ApkUtils", "No application element found while parsing APK.");
return manifestAttrs;
}
for (XMLAttribute attribute : androidElement.listAttributes()) {
if (attribute.getName().isEmpty()) {
continue;
// application
ResXmlElement resApplicationElement = null;
Iterator<ResXmlElement> resXmlElementIt = resManifestElement.getElements("application");
if (resXmlElementIt.hasNext()) {
resApplicationElement = resXmlElementIt.next();
}
if (resXmlElementIt.hasNext()) {
throw new IOException("\"manifest\" has duplicate \"application\" tags.");
}
manifestAttrs.put(attribute.getName(), attribute.getValueAsString());
if (resApplicationElement == null) {
Log.w("ApkUtils", "No application tag found while parsing APK.");
return manifestAttrs;
}
attrIt = resApplicationElement.getAttributes();
while (attrIt.hasNext()) {
attr = attrIt.next();
attrName = attr.getName();
if (attrName == null || attrName.isEmpty()) {
continue;
}
manifestAttrs.put(attrName, attr.getValueAsString());
}
return manifestAttrs;
}
return manifestAttrs;
}

public static boolean hasObbFiles(@NonNull String packageName, @UserIdInt int userId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
import com.reandroid.arsc.chunk.xml.ResXmlDocument;
import com.reandroid.arsc.chunk.xml.ResXmlPullParser;
import com.reandroid.arsc.io.BlockReader;
import com.reandroid.xml.XMLDocument;

import org.xmlpull.v1.XmlPullParserException;

Expand Down Expand Up @@ -122,15 +121,6 @@ public static void decode(@NonNull ByteBuffer byteBuffer, @NonNull OutputStream
}
}

public static XMLDocument decodeToXml(@NonNull ByteBuffer byteBuffer) throws IOException {
ResXmlDocument xmlBlock = new ResXmlDocument();
try (BlockReader reader = new BlockReader(byteBuffer.array())) {
xmlBlock.readBytes(reader);
xmlBlock.setPackageBlock(getFrameworkPackageBlock());
return xmlBlock.toXml(true);
}
}

@NonNull
private static String getNamespacePrefix(String prefix) {
if (TextUtils.isEmpty(prefix)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public ManifestParser(@NonNull ByteBuffer manifestBytes) {
}

public List<ManifestComponent> parseComponents() throws IOException {
ResXmlDocument xmlBlock = new ResXmlDocument();
try (BlockReader reader = new BlockReader(mManifestBytes.array())) {
ResXmlDocument xmlBlock = new ResXmlDocument();
xmlBlock.readBytes(reader);
xmlBlock.setPackageBlock(AndroidBinXmlDecoder.getFrameworkPackageBlock());
ResXmlElement resManifestElement = xmlBlock.getDocumentElement();
Expand Down

0 comments on commit 9338ab2

Please sign in to comment.