[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.EntryStore;
import com.reandroid.lib.common.Frameworks; import com.reandroid.lib.common.Frameworks;
import com.reandroid.lib.common.TableEntryStore; import com.reandroid.lib.common.TableEntryStore;
import com.reandroid.lib.json.JSONObject;
import com.reandroid.xml.XMLAttribute; import com.reandroid.xml.XMLAttribute;
import com.reandroid.xml.XMLDocument; import com.reandroid.xml.XMLDocument;
import com.reandroid.xml.XMLElement; import com.reandroid.xml.XMLElement;
@ -58,6 +59,9 @@ import java.util.*;
entryStore.add(Frameworks.getAndroid()); entryStore.add(Frameworks.getAndroid());
TableBlock tableBlock=apkModule.getTableBlock(); TableBlock tableBlock=apkModule.getTableBlock();
entryStore.add(tableBlock); entryStore.add(tableBlock);
decodePackageInfo(outDir, tableBlock);
xmlBagDecoder=new XMLBagDecoder(entryStore); xmlBagDecoder=new XMLBagDecoder(entryStore);
decodePublicXml(tableBlock, outDir); decodePublicXml(tableBlock, outDir);
@ -75,6 +79,17 @@ import java.util.*;
extractRootFiles(outDir); 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) private void decodeUncompressedFiles(File outDir)
throws IOException { throws IOException {
File file=new File(outDir, UncompressedFiles.JSON_FILE); File file=new File(outDir, UncompressedFiles.JSON_FILE);

View File

@ -15,11 +15,16 @@
*/ */
package com.reandroid.lib.apk.xmlencoder; package com.reandroid.lib.apk.xmlencoder;
import com.reandroid.lib.apk.APKLogger;
import com.reandroid.lib.apk.ResourceIds; import com.reandroid.lib.apk.ResourceIds;
import com.reandroid.lib.arsc.chunk.PackageBlock; import com.reandroid.lib.arsc.chunk.PackageBlock;
import com.reandroid.lib.arsc.chunk.TableBlock; import com.reandroid.lib.arsc.chunk.TableBlock;
import com.reandroid.lib.arsc.pool.TypeStringPool; 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.ArrayList;
import java.util.List; import java.util.List;
@ -27,8 +32,14 @@ class PackageCreator {
private List<String> mSpecNames; private List<String> mSpecNames;
private String mPackageName; private String mPackageName;
private int mPackageId; private int mPackageId;
private File packageDirectory;
private APKLogger apkLogger;
public PackageCreator(){ public PackageCreator(){
} }
public void setPackageDirectory(File packageDirectory) {
this.packageDirectory = packageDirectory;
}
public void setPackageName(String name){ public void setPackageName(String name){
this.mPackageName=name; this.mPackageName=name;
} }
@ -37,6 +48,9 @@ class PackageCreator {
PackageBlock packageBlock=new PackageBlock(); PackageBlock packageBlock=new PackageBlock();
packageBlock.setName(mPackageName); packageBlock.setName(mPackageName);
packageBlock.setId(mPackageId); packageBlock.setId(mPackageId);
loadPackageInfoJson(packageBlock);
tableBlock.getPackageArray() tableBlock.getPackageArray()
.add(packageBlock); .add(packageBlock);
packageBlock.getSpecStringPool() packageBlock.getSpecStringPool()
@ -46,6 +60,33 @@ class PackageCreator {
return packageBlock; 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, private void initTypeStringPool(PackageBlock packageBlock,
ResourceIds.Table.Package pkgResourceIds){ ResourceIds.Table.Package pkgResourceIds){
@ -68,4 +109,22 @@ class PackageCreator {
mSpecNames.add(entry.getName()); 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); ResourceIds.Table.Package pkgResourceIds=map.get(pubXmlFile);
addParsedFiles(pubXmlFile); addParsedFiles(pubXmlFile);
PackageCreator packageCreator = new PackageCreator(); PackageBlock packageBlock = createPackage(pkgResourceIds, pubXmlFile);
packageCreator.setPackageName(pkgResourceIds.name);
PackageBlock packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds);
encodeMaterials.setCurrentPackage(packageBlock); encodeMaterials.setCurrentPackage(packageBlock);
packageBlockMap.put(pubXmlFile, packageBlock); packageBlockMap.put(pubXmlFile, packageBlock);
@ -109,9 +106,7 @@
PackageBlock packageBlock=packageBlockMap.get(pubXmlFile); PackageBlock packageBlock=packageBlockMap.get(pubXmlFile);
if(packageBlock==null){ if(packageBlock==null){
PackageCreator packageCreator = new PackageCreator(); packageBlock = createPackage(pkgResourceIds, pubXmlFile);
packageCreator.setPackageName(pkgResourceIds.name);
packageBlock = packageCreator.createNew(tableBlock, pkgResourceIds);
} }
encodeMaterials.setCurrentPackage(packageBlock); encodeMaterials.setCurrentPackage(packageBlock);
@ -135,6 +130,14 @@
} }
tableBlock.refresh(); 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){ private void preloadStringPool(List<File> pubXmlFileList){
logMessage("Loading string pool ..."); logMessage("Loading string pool ...");
ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder(); ValuesStringPoolBuilder poolBuilder=new ValuesStringPoolBuilder();
@ -205,6 +208,10 @@
File root = packageDirectory.getParentFile(); File root = packageDirectory.getParentFile();
return new File(root, AndroidManifestBlock.FILE_NAME); return new File(root, AndroidManifestBlock.FILE_NAME);
} }
private File toPackageDirectory(File pubXmlFile){
return toResDirectory(pubXmlFile)
.getParentFile();
}
private File toResDirectory(File pubXmlFile){ private File toResDirectory(File pubXmlFile){
return pubXmlFile return pubXmlFile
.getParentFile() .getParentFile()
@ -262,6 +269,7 @@
} }
public void setAPKLogger(APKLogger logger) { public void setAPKLogger(APKLogger logger) {
this.apkLogger = logger; this.apkLogger = logger;
this.apkModule.setAPKLogger(logger);
} }
private void logMessage(String msg) { private void logMessage(String msg) {
if(apkLogger!=null){ if(apkLogger!=null){

View File

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

View File

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