[XML] decode/encode package details

This commit is contained in:
REAndroid 2023-01-18 09:04:56 -05:00
parent 50753ca54c
commit 48d46a3e0a
5 changed files with 105 additions and 12 deletions

View File

@ -29,6 +29,7 @@ import com.reandroid.lib.arsc.value.*;
import com.reandroid.lib.common.EntryStore;
import com.reandroid.lib.common.Frameworks;
import com.reandroid.lib.common.TableEntryStore;
import com.reandroid.lib.json.JSONObject;
import com.reandroid.xml.XMLAttribute;
import com.reandroid.xml.XMLDocument;
import com.reandroid.xml.XMLElement;
@ -58,6 +59,9 @@ import java.util.*;
entryStore.add(Frameworks.getAndroid());
TableBlock tableBlock=apkModule.getTableBlock();
entryStore.add(tableBlock);
decodePackageInfo(outDir, tableBlock);
xmlBagDecoder=new XMLBagDecoder(entryStore);
decodePublicXml(tableBlock, outDir);
@ -75,6 +79,17 @@ import java.util.*;
extractRootFiles(outDir);
}
private void decodePackageInfo(File outDir, TableBlock tableBlock) throws IOException {
for(PackageBlock packageBlock:tableBlock.listPackages()){
decodePackageInfo(outDir, packageBlock);
}
}
private void decodePackageInfo(File outDir, PackageBlock packageBlock) throws IOException {
File pkgDir = new File(outDir, getPackageDirName(packageBlock));
File packageJsonFile = new File(pkgDir, PackageBlock.JSON_FILE_NAME);
JSONObject jsonObject = packageBlock.toJson(false);
jsonObject.write(packageJsonFile);
}
private void decodeUncompressedFiles(File outDir)
throws IOException {
File file=new File(outDir, UncompressedFiles.JSON_FILE);

View File

@ -15,11 +15,16 @@
*/
package com.reandroid.lib.apk.xmlencoder;
import com.reandroid.lib.apk.APKLogger;
import com.reandroid.lib.apk.ResourceIds;
import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.pool.TypeStringPool;
import com.reandroid.lib.json.JSONObject;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@ -27,8 +32,14 @@ class PackageCreator {
private List<String> mSpecNames;
private String mPackageName;
private int mPackageId;
private File packageDirectory;
private APKLogger apkLogger;
public PackageCreator(){
}
public void setPackageDirectory(File packageDirectory) {
this.packageDirectory = packageDirectory;
}
public void setPackageName(String name){
this.mPackageName=name;
}
@ -37,6 +48,9 @@ class PackageCreator {
PackageBlock packageBlock=new PackageBlock();
packageBlock.setName(mPackageName);
packageBlock.setId(mPackageId);
loadPackageInfoJson(packageBlock);
tableBlock.getPackageArray()
.add(packageBlock);
packageBlock.getSpecStringPool()
@ -46,6 +60,33 @@ class PackageCreator {
return packageBlock;
}
private void loadPackageInfoJson(PackageBlock packageBlock){
File dir = this.packageDirectory;
if(dir==null || !dir.isDirectory()){
return;
}
String simplePath = dir.getName() + File.separator
+ PackageBlock.JSON_FILE_NAME;
logMessage("Loading: " + simplePath);
File file = new File(dir, PackageBlock.JSON_FILE_NAME);
if(!file.isFile()){
logMessage("W: File not found, this could be decompiled using old version: '"
+ simplePath+"'");
return;
}
JSONObject jsonObject;
try {
FileInputStream inputStream = new FileInputStream(file);
jsonObject = new JSONObject(inputStream);
inputStream.close();
} catch (IOException ex) {
logMessage("Error loading: '" + simplePath
+ "', "+ex.getMessage());
return;
}
packageBlock.fromJson(jsonObject);
logMessage("OK: " + simplePath);
}
private void initTypeStringPool(PackageBlock packageBlock,
ResourceIds.Table.Package pkgResourceIds){
@ -68,4 +109,22 @@ class PackageCreator {
mSpecNames.add(entry.getName());
}
}
public void setAPKLogger(APKLogger logger) {
this.apkLogger = logger;
}
private void logMessage(String msg) {
if(apkLogger!=null){
apkLogger.logMessage(msg);
}
}
private void logError(String msg, Throwable tr) {
if(apkLogger!=null){
apkLogger.logError(msg, tr);
}
}
private void logVerbose(String msg) {
if(apkLogger!=null){
apkLogger.logVerbose(msg);
}
}
}

View File

@ -79,10 +79,7 @@
ResourceIds.Table.Package pkgResourceIds=map.get(pubXmlFile);
addParsedFiles(pubXmlFile);
PackageCreator packageCreator = new PackageCreator();
packageCreator.setPackageName(pkgResourceIds.name);
PackageBlock packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds);
PackageBlock packageBlock = createPackage(pkgResourceIds, pubXmlFile);
encodeMaterials.setCurrentPackage(packageBlock);
packageBlockMap.put(pubXmlFile, packageBlock);
@ -109,9 +106,7 @@
PackageBlock packageBlock=packageBlockMap.get(pubXmlFile);
if(packageBlock==null){
PackageCreator packageCreator = new PackageCreator();
packageCreator.setPackageName(pkgResourceIds.name);
packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds);
packageBlock = createPackage(pkgResourceIds, pubXmlFile);
}
encodeMaterials.setCurrentPackage(packageBlock);
@ -135,6 +130,14 @@
}
tableBlock.refresh();
}
private PackageBlock createPackage(ResourceIds.Table.Package pkgResourceIds
, File pubXmlFile){
PackageCreator packageCreator = new PackageCreator();
packageCreator.setPackageName(pkgResourceIds.name);
packageCreator.setAPKLogger(apkLogger);
packageCreator.setPackageDirectory(toPackageDirectory(pubXmlFile));
return packageCreator.createNew(this.tableBlock, pkgResourceIds);
}
private void preloadStringPool(List<File> pubXmlFileList){
logMessage("Loading string pool ...");
ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder();
@ -205,6 +208,10 @@
File root = packageDirectory.getParentFile();
return new File(root, AndroidManifestBlock.FILE_NAME);
}
private File toPackageDirectory(File pubXmlFile){
return toResDirectory(pubXmlFile)
.getParentFile();
}
private File toResDirectory(File pubXmlFile){
return pubXmlFile
.getParentFile()
@ -262,6 +269,7 @@
}
public void setAPKLogger(APKLogger logger) {
this.apkLogger = logger;
this.apkModule.setAPKLogger(logger);
}
private void logMessage(String msg) {
if(apkLogger!=null){

View File

@ -228,8 +228,11 @@ public class SpecTypePairArray extends BlockArray<SpecTypePair>
}
@Override
public void fromJson(JSONArray json) {
int length= json.length();
clearChildes();
if(json==null){
return;
}
int length = json.length();
ensureSize(length);
for (int i=0;i<length;i++){
JSONObject jsonObject=json.getJSONObject(i);

View File

@ -82,6 +82,9 @@ package com.reandroid.lib.arsc.chunk;
}
return null;
}
public List<StagedAlias> listStagedAlias(){
return getStagedAliasList().getChildes();
}
public BlockList<StagedAlias> getStagedAliasList(){
return mBody.getStagedAliasList();
}
@ -150,7 +153,7 @@ package com.reandroid.lib.arsc.chunk;
public void addLibraryInfo(LibraryInfo info){
getLibraryBlock().addLibraryInfo(info);
}
private LibraryBlock getLibraryBlock(){
public LibraryBlock getLibraryBlock(){
return mBody.getLibraryBlock();
}
public Set<Integer> listResourceIds(){
@ -293,13 +296,18 @@ package com.reandroid.lib.arsc.chunk;
@Override
public JSONObject toJson() {
return toJson(true);
}
public JSONObject toJson(boolean addSpecs) {
JSONObject jsonObject=new JSONObject();
jsonObject.put(BuildInfo.NAME_arsc_lib_version, BuildInfo.getVersion());
jsonObject.put(NAME_package_id, getId());
jsonObject.put(NAME_package_name, getName());
if(addSpecs){
jsonObject.put(NAME_specs, getSpecTypePairArray().toJson());
}
LibraryInfoArray libraryInfoArray = getLibraryBlock().getLibraryInfoArray();
if(libraryInfoArray.childesCount()>0){
jsonObject.put(NAME_libraries,libraryInfoArray.toJson());
@ -316,7 +324,7 @@ package com.reandroid.lib.arsc.chunk;
public void fromJson(JSONObject json) {
setId(json.getInt(NAME_package_id));
setName(json.getString(NAME_package_name));
getSpecTypePairArray().fromJson(json.getJSONArray(NAME_specs));
getSpecTypePairArray().fromJson(json.optJSONArray(NAME_specs));
LibraryInfoArray libraryInfoArray = getLibraryBlock().getLibraryInfoArray();
libraryInfoArray.fromJson(json.optJSONArray(NAME_libraries));
if(json.has(NAME_staged_aliases)){
@ -370,6 +378,6 @@ package com.reandroid.lib.arsc.chunk;
public static final String NAME_package_name = "package_name";
public static final String JSON_FILE_NAME = "package.json";
private static final String NAME_specs="specs";
private static final String NAME_libraries="libraries";
public static final String NAME_libraries="libraries";
public static final String NAME_staged_aliases="staged_aliases";
}