diff --git a/patch/src/main/java/org/lsposed/patch/LSPatch.java b/patch/src/main/java/org/lsposed/patch/LSPatch.java index 50e766b..7cd74c5 100644 --- a/patch/src/main/java/org/lsposed/patch/LSPatch.java +++ b/patch/src/main/java/org/lsposed/patch/LSPatch.java @@ -13,6 +13,7 @@ import com.android.tools.build.apkzlib.zip.ZFile; import com.android.tools.build.apkzlib.zip.ZFileOptions; import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; +import com.beust.jcommander.ParameterException; import com.google.gson.Gson; import com.wind.meditor.core.ManifestEditor; import com.wind.meditor.property.AttributeItem; @@ -72,6 +73,9 @@ public class LSPatch { @Parameter(names = {"-l", "--sigbypasslv"}, description = "Signature bypass level. 0 (disable), 1 (pm), 2 (pm+openat). default 0") private int sigbypassLevel = 0; + @Parameter(names = {"-k", "--keystore"}, arity = 4, description = "Set custom signature keystore. Followed by 4 arguments: keystore path, keystore password, keystore alias, keystore alias password") + private List keystoreArgs = Arrays.asList(null, "123456", "key0", "123456"); + @Parameter(names = {"--v1"}, arity = 1, description = "Sign with v1 signature") private boolean v1 = false; @@ -117,38 +121,40 @@ public class LSPatch { private final Logger logger; public LSPatch(Logger logger, String... args) { - jCommander = JCommander.newBuilder() - .addObject(this) - .build(); - jCommander.parse(args); + jCommander = JCommander.newBuilder().addObject(this).build(); + try { + jCommander.parse(args); + } catch (ParameterException e) { + logger.e(e.getMessage() + "\n"); + help = true; + } + if (apkPaths == null || apkPaths.isEmpty()) { + logger.e("No apk specified\n"); + help = true; + } + if (!modules.isEmpty() && useManager) { + logger.e("Should not use --embed and --manager at the same time\n"); + help = true; + } + this.logger = logger; logger.verbose = verbose; } public static void main(String... args) throws IOException { - LSPatch lsPatch = new LSPatch(new JavaLogger(), args); + LSPatch lspatch = new LSPatch(new JavaLogger(), args); + if (lspatch.help) { + lspatch.jCommander.usage(); + return; + } try { - lsPatch.doCommandLine(); + lspatch.doCommandLine(); } catch (PatchError e) { e.printStackTrace(System.err); } } public void doCommandLine() throws PatchError, IOException { - if (help) { - jCommander.usage(); - return; - } - if (apkPaths == null || apkPaths.isEmpty()) { - jCommander.usage(); - return; - } - - if (!modules.isEmpty() && useManager) { - jCommander.usage(); - return; - } - for (var apk : apkPaths) { File srcApkFile = new File(apk).getAbsoluteFile(); @@ -181,13 +187,20 @@ public class LSPatch { var srcZFile = dstZFile.addNestedZip((ignore) -> ORIGINAL_APK_ASSET_PATH, srcApkFile, false)) { // sign apk - logger.i("Register apk signer..."); try { var keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - try (var is = getClass().getClassLoader().getResourceAsStream("assets/keystore")) { - keyStore.load(is, "123456".toCharArray()); + if (keystoreArgs.get(0) == null) { + logger.i("Register apk signer with default keystore..."); + try (var is = getClass().getClassLoader().getResourceAsStream("assets/keystore")) { + keyStore.load(is, keystoreArgs.get(1).toCharArray()); + } + } else { + logger.i("Register apk signer with custom keystore..."); + try (var is = new FileInputStream(keystoreArgs.get(0))) { + keyStore.load(is, keystoreArgs.get(1).toCharArray()); + } } - var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry("key0", new KeyStore.PasswordProtection("123456".toCharArray())); + var entry = (KeyStore.PrivateKeyEntry) keyStore.getEntry(keystoreArgs.get(2), new KeyStore.PasswordProtection(keystoreArgs.get(3).toCharArray())); new SigningExtension(SigningOptions.builder() .setMinSdkVersion(28) .setV1SigningEnabled(v1) @@ -292,7 +305,9 @@ public class LSPatch { return false; }); - embedModules(dstZFile); + if (!useManager) { + embedModules(dstZFile); + } // create zip link logger.d("Creating nested apk link...");