diff --git a/src/main/java/com/reandroid/apk/ApkJsonDecoder.java b/src/main/java/com/reandroid/apk/ApkJsonDecoder.java index 935cdec..3a8d949 100644 --- a/src/main/java/com/reandroid/apk/ApkJsonDecoder.java +++ b/src/main/java/com/reandroid/apk/ApkJsonDecoder.java @@ -1,21 +1,22 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* + * Copyright (C) 2022 github.com/REAndroid + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.reandroid.apk; import com.reandroid.archive.InputSource; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; import com.reandroid.arsc.chunk.xml.ResXmlDocument; @@ -53,8 +54,18 @@ public class ApkJsonDecoder { writeResources(dir); writeRootFiles(dir); writePathMap(dir); + dumpSignatures(dir); return new File(dir, apkModule.getModuleName()); } + private void dumpSignatures(File outDir) throws IOException { + ApkSignatureBlock signatureBlock = apkModule.getApkSignatureBlock(); + if(signatureBlock == null){ + return; + } + apkModule.logMessage("Dumping signatures: " + ApkUtil.SIGNATURE_FILE_NAME); + File file = toSignatureFile(outDir); + signatureBlock.writeRaw(file); + } private void writePathMap(File dir) throws IOException { PathMap pathMap = new PathMap(); pathMap.add(apkModule.getApkArchive()); @@ -189,6 +200,10 @@ public class ApkJsonDecoder { String name = "public.xml"; return new File(file, name); } + private File toSignatureFile(File dir){ + File file = new File(dir, apkModule.getModuleName()); + return new File(file, ApkUtil.SIGNATURE_FILE_NAME); + } private File toPathMapJsonFile(File dir){ File file = new File(dir, apkModule.getModuleName()); return new File(file, PathMap.JSON_FILE); diff --git a/src/main/java/com/reandroid/apk/ApkJsonEncoder.java b/src/main/java/com/reandroid/apk/ApkJsonEncoder.java index 96a10ff..6af21b4 100644 --- a/src/main/java/com/reandroid/apk/ApkJsonEncoder.java +++ b/src/main/java/com/reandroid/apk/ApkJsonEncoder.java @@ -1,22 +1,23 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* + * Copyright (C) 2022 github.com/REAndroid + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.reandroid.apk; import com.reandroid.archive.APKArchive; import com.reandroid.archive.FileInputSource; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; import com.reandroid.json.JSONArray; @@ -40,12 +41,28 @@ public class ApkJsonEncoder { scanResJsonDirs(moduleDir); scanRootDirs(moduleDir); ApkModule module=new ApkModule(moduleName, apkArchive); + module.setLoadDefaultFramework(false); module.setAPKLogger(apkLogger); loadUncompressed(module, moduleDir); applyResourceId(module, moduleDir); restorePathMap(moduleDir, module); + restoreSignatures(moduleDir, module); return module; } + private void restoreSignatures(File dir, ApkModule apkModule){ + File file = new File(dir, ApkUtil.SIGNATURE_FILE_NAME); + if(!file.isFile()){ + return; + } + logMessage("Loading signature: " + file.getName()); + ApkSignatureBlock signatureBlock = new ApkSignatureBlock(); + try { + signatureBlock.read(file); + apkModule.setApkSignatureBlock(signatureBlock); + } catch (IOException exception){ + logError("Failed to load signatures: ", exception); + } + } private void restorePathMap(File dir, ApkModule apkModule){ File file = new File(dir, PathMap.JSON_FILE); if(!file.isFile()){ diff --git a/src/main/java/com/reandroid/apk/ApkModuleXmlDecoder.java b/src/main/java/com/reandroid/apk/ApkModuleXmlDecoder.java index 51af36a..3d899d4 100644 --- a/src/main/java/com/reandroid/apk/ApkModuleXmlDecoder.java +++ b/src/main/java/com/reandroid/apk/ApkModuleXmlDecoder.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -19,6 +19,7 @@ import com.reandroid.apk.xmldecoder.ResXmlDocumentSerializer; import com.reandroid.archive.InputSource; import com.reandroid.apk.xmldecoder.XMLBagDecoder; import com.reandroid.apk.xmldecoder.XMLNamespaceValidator; +import com.reandroid.archive2.block.ApkSignatureBlock; import com.reandroid.arsc.chunk.PackageBlock; import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.chunk.TypeBlock; @@ -92,6 +93,17 @@ import java.util.*; extractRootFiles(outDir); writePathMap(outDir); + + dumpSignatures(outDir); + } + private void dumpSignatures(File outDir) throws IOException { + ApkSignatureBlock signatureBlock = apkModule.getApkSignatureBlock(); + if(signatureBlock == null){ + return; + } + logMessage("Dumping signatures: " + ApkUtil.SIGNATURE_FILE_NAME); + File file = new File(outDir, ApkUtil.SIGNATURE_FILE_NAME); + signatureBlock.writeRaw(file); } private void writePathMap(File dir) throws IOException { PathMap pathMap = new PathMap(); diff --git a/src/main/java/com/reandroid/apk/ApkModuleXmlEncoder.java b/src/main/java/com/reandroid/apk/ApkModuleXmlEncoder.java index 0b0c293..0b2db12 100644 --- a/src/main/java/com/reandroid/apk/ApkModuleXmlEncoder.java +++ b/src/main/java/com/reandroid/apk/ApkModuleXmlEncoder.java @@ -1,77 +1,90 @@ - /* - * Copyright (C) 2022 github.com/REAndroid - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +/* + * Copyright (C) 2022 github.com/REAndroid + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.reandroid.apk; - import com.reandroid.archive.APKArchive; - import com.reandroid.archive.FileInputSource; - import com.reandroid.apk.xmlencoder.RESEncoder; - import com.reandroid.arsc.chunk.TableBlock; - import com.reandroid.json.JSONArray; - import com.reandroid.xml.XMLException; +import com.reandroid.archive.APKArchive; +import com.reandroid.archive.FileInputSource; +import com.reandroid.apk.xmlencoder.RESEncoder; +import com.reandroid.archive2.block.ApkSignatureBlock; +import com.reandroid.arsc.chunk.TableBlock; +import com.reandroid.json.JSONArray; +import com.reandroid.xml.XMLException; - import java.io.File; - import java.io.FileInputStream; - import java.io.IOException; - import java.util.List; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.List; - public class ApkModuleXmlEncoder { - private final RESEncoder resEncoder; - public ApkModuleXmlEncoder(){ - this.resEncoder = new RESEncoder(); - } - public ApkModuleXmlEncoder(ApkModule module, TableBlock tableBlock){ - this.resEncoder = new RESEncoder(module, tableBlock); - } - public void scanDirectory(File mainDirectory) throws IOException, XMLException { - loadUncompressedFiles(mainDirectory); - resEncoder.scanDirectory(mainDirectory); - File rootDir=new File(mainDirectory, "root"); - scanRootDir(rootDir); - restorePathMap(mainDirectory); - } - private void restorePathMap(File dir) throws IOException{ - File file = new File(dir, PathMap.JSON_FILE); - if(!file.isFile()){ - return; - } - PathMap pathMap = new PathMap(); - FileInputStream inputStream = new FileInputStream(file); - JSONArray jsonArray = new JSONArray(inputStream); - pathMap.fromJson(jsonArray); - pathMap.restore(getApkModule()); - } - public ApkModule getApkModule(){ - return resEncoder.getApkModule(); - } +public class ApkModuleXmlEncoder { + private final RESEncoder resEncoder; + public ApkModuleXmlEncoder(){ + this.resEncoder = new RESEncoder(); + } + public ApkModuleXmlEncoder(ApkModule module, TableBlock tableBlock){ + this.resEncoder = new RESEncoder(module, tableBlock); + } + public void scanDirectory(File mainDirectory) throws IOException, XMLException { + loadUncompressedFiles(mainDirectory); + resEncoder.scanDirectory(mainDirectory); + File rootDir=new File(mainDirectory, "root"); + scanRootDir(rootDir); + restorePathMap(mainDirectory); + restoreSignatures(mainDirectory); + } + private void restoreSignatures(File dir) throws IOException { + File file = new File(dir, ApkUtil.SIGNATURE_FILE_NAME); + if(!file.isFile()){ + return; + } + ApkModule apkModule = getApkModule(); + apkModule.logMessage("Loading signature: " + file.getName()); + ApkSignatureBlock signatureBlock = new ApkSignatureBlock(); + signatureBlock.read(file); + apkModule.setApkSignatureBlock(signatureBlock); + } + private void restorePathMap(File dir) throws IOException{ + File file = new File(dir, PathMap.JSON_FILE); + if(!file.isFile()){ + return; + } + PathMap pathMap = new PathMap(); + FileInputStream inputStream = new FileInputStream(file); + JSONArray jsonArray = new JSONArray(inputStream); + pathMap.fromJson(jsonArray); + pathMap.restore(getApkModule()); + } + public ApkModule getApkModule(){ + return resEncoder.getApkModule(); + } - private void scanRootDir(File rootDir){ - APKArchive archive=getApkModule().getApkArchive(); - List rootFileList=ApkUtil.recursiveFiles(rootDir); - for(File file:rootFileList){ - String path=ApkUtil.toArchivePath(rootDir, file); - FileInputSource inputSource=new FileInputSource(file, path); - archive.add(inputSource); - } - } - private void loadUncompressedFiles(File mainDirectory) throws IOException, XMLException { - File file=new File(mainDirectory, UncompressedFiles.JSON_FILE); - UncompressedFiles uncompressedFiles = getApkModule().getUncompressedFiles(); - uncompressedFiles.fromJson(file); - } - public void setApkLogger(APKLogger apkLogger) { - this.resEncoder.setAPKLogger(apkLogger); - } - } + private void scanRootDir(File rootDir){ + APKArchive archive=getApkModule().getApkArchive(); + List rootFileList=ApkUtil.recursiveFiles(rootDir); + for(File file:rootFileList){ + String path=ApkUtil.toArchivePath(rootDir, file); + FileInputSource inputSource=new FileInputSource(file, path); + archive.add(inputSource); + } + } + private void loadUncompressedFiles(File mainDirectory) throws IOException, XMLException { + File file=new File(mainDirectory, UncompressedFiles.JSON_FILE); + UncompressedFiles uncompressedFiles = getApkModule().getUncompressedFiles(); + uncompressedFiles.fromJson(file); + } + public void setApkLogger(APKLogger apkLogger) { + this.resEncoder.setAPKLogger(apkLogger); + } +} diff --git a/src/main/java/com/reandroid/apk/ApkUtil.java b/src/main/java/com/reandroid/apk/ApkUtil.java index fcb49f2..3ba8fa0 100644 --- a/src/main/java/com/reandroid/apk/ApkUtil.java +++ b/src/main/java/com/reandroid/apk/ApkUtil.java @@ -1,4 +1,4 @@ - /* +/* * Copyright (C) 2022 github.com/REAndroid * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +16,7 @@ package com.reandroid.apk; import com.reandroid.archive.InputSource; +import com.reandroid.archive2.block.ApkSignatureBlock; import java.io.File; import java.util.*; @@ -192,5 +193,7 @@ public class ApkUtil { public static final String TAG_STRING_ARRAY = "string-array"; public static final String TAG_INTEGER_ARRAY = "integer-array"; + public static final String SIGNATURE_FILE_NAME = "signatures" + ApkSignatureBlock.FILE_EXT; + private static final int MAX_FILE_NAME_LENGTH = 50; } diff --git a/src/main/java/com/reandroid/archive2/block/ApkSignatureBlock.java b/src/main/java/com/reandroid/archive2/block/ApkSignatureBlock.java index e9d41d0..4220113 100644 --- a/src/main/java/com/reandroid/archive2/block/ApkSignatureBlock.java +++ b/src/main/java/com/reandroid/archive2/block/ApkSignatureBlock.java @@ -157,5 +157,5 @@ public class ApkSignatureBlock extends LengthPrefixedList return 0; } - public static final String FILE_EXT = ".signature.block.bin"; + public static final String FILE_EXT = ".sig"; }