From 5082403d72acbeb99eb78a934a282aecb2882fae Mon Sep 17 00:00:00 2001 From: REAndroid Date: Sat, 22 Jul 2023 21:37:12 +0200 Subject: [PATCH] introduce decompile/build as RAW type --- .../java/com/reandroid/apkeditor/Options.java | 3 +- .../apkeditor/compile/BuildOptions.java | 2 +- .../reandroid/apkeditor/compile/Builder.java | 52 ++++++++++++++++--- .../apkeditor/decompile/DecompileOptions.java | 2 +- .../apkeditor/decompile/Decompiler.java | 3 ++ 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/reandroid/apkeditor/Options.java b/src/main/java/com/reandroid/apkeditor/Options.java index 4b3369fc..6a1b4356 100644 --- a/src/main/java/com/reandroid/apkeditor/Options.java +++ b/src/main/java/com/reandroid/apkeditor/Options.java @@ -77,7 +77,7 @@ protected void parseType(String[] args) throws ARGException { parseType(args, TYPE_JSON); } protected void parseType(String[] args, String def) throws ARGException { - String[] choices = new String[]{TYPE_JSON, TYPE_XML, TYPE_SIG}; + String[] choices = new String[]{TYPE_JSON, TYPE_XML, TYPE_RAW, TYPE_SIG}; this.type = parseType(ARG_type, args, choices, def); } protected void parseSignaturesDir(String[] args) throws ARGException { @@ -238,6 +238,7 @@ protected boolean containsArg(String argSwitch, boolean ignore_case, String[] ar public static final String TYPE_SIG = "sig"; public static final String TYPE_JSON = "json"; + public static final String TYPE_RAW = "raw"; public static final String TYPE_XML = "xml"; public static final String TYPE_TEXT = "text"; diff --git a/src/main/java/com/reandroid/apkeditor/compile/BuildOptions.java b/src/main/java/com/reandroid/apkeditor/compile/BuildOptions.java index 136d0fb9..469ebd8c 100644 --- a/src/main/java/com/reandroid/apkeditor/compile/BuildOptions.java +++ b/src/main/java/com/reandroid/apkeditor/compile/BuildOptions.java @@ -19,7 +19,6 @@ import com.reandroid.apkeditor.Options; import com.reandroid.apkeditor.utils.StringHelper; import com.reandroid.commons.command.ARGException; -import com.sun.org.apache.xpath.internal.Arg; import java.io.File; @@ -27,6 +26,7 @@ public class BuildOptions extends Options { public boolean validateResDir; public String resDirName; public boolean isXml; + public boolean isRaw; public boolean noCache; public BuildOptions(){ } diff --git a/src/main/java/com/reandroid/apkeditor/compile/Builder.java b/src/main/java/com/reandroid/apkeditor/compile/Builder.java index c5f1b00d..7a74c203 100644 --- a/src/main/java/com/reandroid/apkeditor/compile/Builder.java +++ b/src/main/java/com/reandroid/apkeditor/compile/Builder.java @@ -21,7 +21,8 @@ import com.reandroid.apkeditor.smali.SmaliCompiler; import com.reandroid.archive.ArchiveFile; import com.reandroid.archive.block.ApkSignatureBlock; -import com.reandroid.archive.writer.ApkWriter; +import com.reandroid.archive.writer.ApkFileWriter; +import com.reandroid.arsc.chunk.TableBlock; import com.reandroid.arsc.coder.xml.XmlCoder; import com.reandroid.commons.command.ARGException; import com.reandroid.arsc.chunk.xml.AndroidManifestBlock; @@ -40,7 +41,9 @@ public void run() throws IOException { restoreSignatures(); return; } - if(options.isXml){ + if(options.isRaw){ + buildRaw(); + }else if(options.isXml){ buildXml(); }else { buildJson(); @@ -50,7 +53,7 @@ private void restoreSignatures() throws IOException { logMessage("Restoring signatures ..."); BuildOptions options = getOptions(); ArchiveFile archive = new ArchiveFile(options.inputFile); - ApkWriter apkWriter = new ApkWriter(options.outputFile, archive.getInputSources()); + ApkFileWriter apkWriter = new ApkFileWriter(options.outputFile, archive.getInputSources()); apkWriter.setAPKLogger(this); ApkSignatureBlock apkSignatureBlock = new ApkSignatureBlock(); apkSignatureBlock.scanSplitFiles(options.signaturesDirectory); @@ -117,13 +120,42 @@ public void buildXml() throws IOException { loadedModule.close(); logMessage("Saved to: " + options.outputFile); } + public void buildRaw() throws IOException { + logMessage("Scanning Raw directory ..."); + ApkModuleRawEncoder encoder = new ApkModuleRawEncoder(); + encoder.setApkLogger(this); + + BuildOptions options = getOptions(); + + SmaliCompiler smaliCompiler = new SmaliCompiler(options.noCache); + smaliCompiler.setApkLogger(this); + + encoder.setDexEncoder(smaliCompiler); + ApkModule loadedModule = encoder.getApkModule(); + loadedModule.setAPKLogger(this); + + loadedModule.setPreferredFramework(options.frameworkVersion); + if(options.frameworks != null){ + for(File file : options.frameworks){ + loadedModule.addExternalFramework(file); + } + } + encoder.scanDirectory(options.inputFile); + loadedModule = encoder.getApkModule(); + logMessage("Writing apk..."); + loadedModule.writeApk(options.outputFile, null); + loadedModule.close(); + logMessage("Saved to: " + options.outputFile); + } public static void execute(String[] args) throws ARGException, IOException { if(Util.isHelp(args)){ throw new ARGException(BuildOptions.getHelp()); } BuildOptions option=new BuildOptions(); option.parse(args); - if(isJsonInDir(option.inputFile)){ + if(isRawInDir(option.inputFile)){ + option.isRaw = true; + }else if(isJsonInDir(option.inputFile)){ option.inputFile = getJsonInDir(option.inputFile); }else if (isXmlInDir(option.inputFile)){ option.isXml=true; @@ -143,11 +175,15 @@ public static void execute(String[] args) throws ARGException, IOException { } builder.run(); } - private static boolean isXmlInDir(File dir){ - File manifest=new File(dir, AndroidManifestBlock.FILE_NAME); - if(!manifest.isFile()){ - manifest=new File(dir, AndroidManifestBlock.FILE_NAME_BIN); + private static boolean isRawInDir(File dir){ + File file=new File(dir, AndroidManifestBlock.FILE_NAME_BIN); + if(!file.isFile()){ + file = new File(dir, TableBlock.FILE_NAME); } + return file.isFile(); + } + private static boolean isXmlInDir(File dir){ + File manifest = new File(dir, AndroidManifestBlock.FILE_NAME); return manifest.isFile(); } private static boolean isJsonInDir(File dir) { diff --git a/src/main/java/com/reandroid/apkeditor/decompile/DecompileOptions.java b/src/main/java/com/reandroid/apkeditor/decompile/DecompileOptions.java index 4c9694e1..512bdf5d 100644 --- a/src/main/java/com/reandroid/apkeditor/decompile/DecompileOptions.java +++ b/src/main/java/com/reandroid/apkeditor/decompile/DecompileOptions.java @@ -188,7 +188,7 @@ public static String getHelp(){ private static final String ARG_split_resources="-split-json"; private static final String ARG_DESC_split_resources="splits resources.arsc into multiple parts as per type entries (use this for large files)"; - private static final String ARG_DESC_type = "Decode types: \n 1) json \n 2) xml \n 3) sig \n default=" + TYPE_XML; + private static final String ARG_DESC_type = "Decode types: \n 1) json \n 2) xml \n 3) raw \n 4) sig \n default=" + TYPE_XML; private static final String ARG_keep_res_path = "-keep-res-path"; diff --git a/src/main/java/com/reandroid/apkeditor/decompile/Decompiler.java b/src/main/java/com/reandroid/apkeditor/decompile/Decompiler.java index 5d4a1253..f3b56868 100644 --- a/src/main/java/com/reandroid/apkeditor/decompile/Decompiler.java +++ b/src/main/java/com/reandroid/apkeditor/decompile/Decompiler.java @@ -69,6 +69,9 @@ private ApkModuleDecoder getApkModuleDecoder(ApkModule apkModule){ if(DecompileOptions.TYPE_JSON.equals(options.type)){ decoder = new ApkModuleJsonDecoder(apkModule, options.splitJson); decoder.setDexDecoder(getSmaliDecompiler(apkModule.getTableBlock())); + }else if(DecompileOptions.TYPE_RAW.equals(options.type)){ + decoder = new ApkModuleRawDecoder(apkModule); + decoder.setDexDecoder(getSmaliDecompiler(apkModule.getTableBlock())); }else{ ApkModuleXmlDecoder xmlDecoder = new ApkModuleXmlDecoder(apkModule); xmlDecoder.setKeepResPath(options.keepResPath);