diff --git a/xpatch/.gitignore b/xpatch/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/xpatch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/xpatch/build.gradle b/xpatch/build.gradle deleted file mode 100644 index d384968..0000000 --- a/xpatch/build.gradle +++ /dev/null @@ -1,39 +0,0 @@ -apply plugin: 'java-library' - -dependencies { - compile fileTree(dir: 'libs', include: ['*.jar']) - compile project(':axmlprinter') - compile project(':apksigner') - compile group: 'commons-io', name: 'commons-io', version: '2.8.0' -} - -jar { - baseName = "mmpatch" - manifest { - attributes 'Main-Class': 'com.storm.wind.xpatch.MainCommand' - } - //添加将引用的jar的源码打入最终的jar - from { - (configurations.runtime).collect { - it.isDirectory() ? it : zipTree(it) - } - } - - from fileTree(dir: 'src/main', includes: ['assets/**']) - - //排除引用的jar中的签名信息 - exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF' -} - -tasks.build.doLast { - println("Build to " + jar.archivePath) - println("Try \'java -jar " + jar.archiveName + "\' find more help") -} - -//添加源码中引入的非代码文件,例如资源等 -sourceSets.main.resources { - srcDirs = [ - "src/main/java", - ]; - include "**/*.*" -} \ No newline at end of file diff --git a/xpatch/libs/ManifestEditor-1.0.1.jar b/xpatch/libs/ManifestEditor-1.0.1.jar deleted file mode 100644 index e1664cc..0000000 Binary files a/xpatch/libs/ManifestEditor-1.0.1.jar and /dev/null differ diff --git a/xpatch/libs/dex-tools-2.1-SNAPSHOT.jar b/xpatch/libs/dex-tools-2.1-SNAPSHOT.jar deleted file mode 100644 index 0b780ac..0000000 Binary files a/xpatch/libs/dex-tools-2.1-SNAPSHOT.jar and /dev/null differ diff --git a/xpatch/src/main/assets/android.keystore b/xpatch/src/main/assets/android.keystore deleted file mode 100644 index 879c1dc..0000000 Binary files a/xpatch/src/main/assets/android.keystore and /dev/null differ diff --git a/xpatch/src/main/assets/keystore b/xpatch/src/main/assets/keystore deleted file mode 100644 index 67f1939..0000000 Binary files a/xpatch/src/main/assets/keystore and /dev/null differ diff --git a/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java b/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java deleted file mode 100644 index 536876b..0000000 --- a/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.storm.wind.xpatch; - -import com.storm.wind.xpatch.base.BaseCommand; -import com.storm.wind.xpatch.task.ApkModifyTask; -import com.storm.wind.xpatch.task.BuildAndSignApkTask; -import com.storm.wind.xpatch.task.SaveApkSignatureTask; -import com.storm.wind.xpatch.task.SaveOriginalApplicationNameTask; -import com.storm.wind.xpatch.task.SoAndDexCopyTask; -import com.storm.wind.xpatch.util.FileUtils; -import com.storm.wind.xpatch.util.ManifestParser; -import com.wind.meditor.core.FileProcesser; -import com.wind.meditor.property.AttributeItem; -import com.wind.meditor.property.ModificationProperty; -import com.wind.meditor.utils.NodeValue; - -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.regex.Pattern; - -import static org.apache.commons.io.FileUtils.copyFile; - -public class MainCommand extends BaseCommand { - - private String apkPath; - - private String unzipApkFilePath; - - @Opt(opt = "o", longOpt = "output", description = "output .apk file, default is " + - "$source_apk_dir/[file-name]-xposed-signed.apk", argName = "out-apk-file") - private String output; // 输出的apk文件的目录以及名称 - - @Opt(opt = "f", longOpt = "force", hasArg = false, description = "force overwrite") - private boolean forceOverwrite = false; - - @Opt(opt = "pn", longOpt = "proxyname", description = "special proxy app name with full dot path", argName = "proxy app name") - private String proxyname = "com.wind.xposed.entry.MMPApplication"; - - @Opt(opt = "c", longOpt = "crach", hasArg = false, - description = "disable craching the apk's signature.") - private boolean disableCrackSignature = false; - - // 使用dex文件中插入代码的方式修改apk,而不是默认的修改Manifest中Application name的方式 - @Opt(opt = "dex", longOpt = "dex", hasArg = false, description = "insert code into the dex file, not modify manifest application name attribute") - private boolean dexModificationMode = false; - - @Opt(opt = "pkg", longOpt = "packageName", description = "modify the apk package name", argName = "new package name") - private String newPackageName; - - @Opt(opt = "d", longOpt = "debuggable", description = "set 1 to make the app debuggable = true, " + - "set 0 to make the app debuggable = false", argName = "0 or 1") - private int debuggable = -1; // 0: debuggable = false 1: debuggable = true - - @Opt(opt = "vc", longOpt = "versionCode", description = "set the app version code", - argName = "new-version-code") - private int versionCode; - - @Opt(opt = "vn", longOpt = "versionName", description = "set the app version name", - argName = "new-version-name") - private String versionName; - - // 原来apk中dex文件的数量 - private int dexFileCount = 0; - - private static final String UNZIP_APK_FILE_NAME = "apk-unzip-files"; - - private List mXpatchTasks = new ArrayList<>(); - - public static void main(String... args) { - new MainCommand().doMain(args); - } - - private void fuckIfFail(boolean b) { - if (!b) { - throw new IllegalStateException("wtf", new Throwable("DUMPBT")); - } - } - - @Override - protected void doCommandLine() throws IOException { - if (remainingArgs.length != 1) { - if (remainingArgs.length == 0) { - System.out.println("Please choose one apk file you want to process. "); - } - if (remainingArgs.length > 1) { - System.out.println("This tool can only used with one apk file."); - } - usage(); - return; - } - - apkPath = remainingArgs[0]; - - File srcApkFile = new File(apkPath); - - if (!srcApkFile.exists()) { - System.out.println("The source apk file not exsit, please choose another one. " + - "current apk file is = " + apkPath); - return; - } - - String currentDir = new File(".").getAbsolutePath(); - System.out.println("currentDir: " + currentDir); - System.out.println("apkPath: " + apkPath); - - if (output == null || output.length() == 0) { - output = getBaseName(apkPath) + "-xposed-signed.apk"; - } - - File outputFile = new File(output); - if (outputFile.exists() && !forceOverwrite) { - System.err.println(output + " exists, use --force to overwrite"); - usage(); - return; - } - - String outputApkFileParentPath = outputFile.getParent(); - if (outputApkFileParentPath == null) { - String absPath = outputFile.getAbsolutePath(); - int index = absPath.lastIndexOf(File.separatorChar); - outputApkFileParentPath = absPath.substring(0, index); - } - - System.out.println("output apk path: " + output); - System.out.println("disableCrackSignature: " + disableCrackSignature); - - String apkFileName = getBaseName(srcApkFile); - - String tempFilePath = outputApkFileParentPath + File.separator + - currentTimeStr() + "-tmp" + File.separator; - - unzipApkFilePath = tempFilePath + apkFileName + "-" + UNZIP_APK_FILE_NAME + File.separator; - - System.out.println("outputApkFileParentPath: " + outputApkFileParentPath); - System.out.println("unzipApkFilePath = " + unzipApkFilePath); - - if (!disableCrackSignature) { - // save the apk original signature info, to support crach signature. - new SaveApkSignatureTask(apkPath, unzipApkFilePath).run(); - } - - long currentTime = System.currentTimeMillis(); - FileUtils.decompressZip(apkPath, unzipApkFilePath); - - System.out.println("decompress apk cost time: " + (System.currentTimeMillis() - currentTime) + "ms"); - - // Get the dex count in the apk zip file - dexFileCount = findDexFileCount(unzipApkFilePath); - - System.out.println("dexFileCount: " + dexFileCount); - - String manifestFilePath = unzipApkFilePath + "AndroidManifest.xml"; - - currentTime = System.currentTimeMillis(); - - // parse the app main application full name from the manifest file - ManifestParser.Pair pair = ManifestParser.parseManifestFile(manifestFilePath); - String applicationName = null; - if (pair != null && pair.applicationName != null) { - applicationName = pair.applicationName; - } - - System.out.println("Get application name cost time: " + (System.currentTimeMillis() - currentTime) + "ms"); - System.out.println("Get the application name: " + applicationName); - - // modify manifest - File manifestFile = new File(manifestFilePath); - String manifestFilePathNew = unzipApkFilePath + "AndroidManifest" + "-" + currentTimeStr() + ".xml"; - File manifestFileNew = new File(manifestFilePathNew); - fuckIfFail(manifestFile.renameTo(manifestFileNew)); - - modifyManifestFile(manifestFilePathNew, manifestFilePath, applicationName); - - // new manifest may not exist - if (manifestFile.exists() && manifestFile.length() > 0) { - fuckIfFail(manifestFileNew.delete()); - } else { - fuckIfFail(manifestFileNew.renameTo(manifestFile)); - } - - // save original main application name to asset file - if (isNotEmpty(applicationName)) { - mXpatchTasks.add(new SaveOriginalApplicationNameTask(applicationName, unzipApkFilePath)); - } - - // modify the apk dex file to make xposed can run in it - if (dexModificationMode && isNotEmpty(applicationName)) { - mXpatchTasks.add(new ApkModifyTask(true, true, unzipApkFilePath, applicationName, - dexFileCount)); - } - - // copy xposed so and dex files into the unzipped apk - mXpatchTasks.add(new SoAndDexCopyTask(dexFileCount, unzipApkFilePath)); - - // compress all files into an apk and then sign it. - mXpatchTasks.add(new BuildAndSignApkTask(true, unzipApkFilePath, output)); - - // copy origin apk to assets - // convenient to bypass some check like CRC - copyFile(srcApkFile, new File(unzipApkFilePath, "assets/origin_apk.bin")); - - // excute these tasks - for (Runnable executor : mXpatchTasks) { - currentTime = System.currentTimeMillis(); - executor.run(); - - System.out.println(executor.getClass().getSimpleName() + " cost time: " - + (System.currentTimeMillis() - currentTime) + "ms"); - } - - System.out.println("Output APK: " + output); - } - - private void modifyManifestFile(String filePath, String dstFilePath, String originalApplicationName) { - ModificationProperty property = new ModificationProperty(); - boolean modifyEnabled = false; - if (isNotEmpty(newPackageName)) { - modifyEnabled = true; - property.addManifestAttribute(new AttributeItem(NodeValue.Manifest.PACKAGE, newPackageName).setNamespace(null)); - } - - if (versionCode > 0) { - modifyEnabled = true; - property.addManifestAttribute(new AttributeItem(NodeValue.Manifest.VERSION_CODE, versionCode)); - } - - if (isNotEmpty(versionName)) { - modifyEnabled = true; - property.addManifestAttribute(new AttributeItem(NodeValue.Manifest.VERSION_NAME, versionName)); - } - - if (debuggable >= 0) { - modifyEnabled = true; - property.addApplicationAttribute(new AttributeItem(NodeValue.Application.DEBUGGABLE, debuggable != 0)); - } - - property.addApplicationAttribute(new AttributeItem("extractNativeLibs", true)); - - if (!dexModificationMode || !isNotEmpty(originalApplicationName)) { - modifyEnabled = true; - property.addApplicationAttribute(new AttributeItem(NodeValue.Application.NAME, proxyname)); - } - - if (modifyEnabled) { - FileProcesser.processManifestFile(filePath, dstFilePath, property); - } - } - - private int findDexFileCount(String unzipApkFilePath) { - File zipfileRoot = new File(unzipApkFilePath); - if (!zipfileRoot.exists()) { - return 0; - } - File[] childFiles = zipfileRoot.listFiles(); - if (childFiles == null || childFiles.length == 0) { - return 0; - } - int count = 0; - for (File file : childFiles) { - String fileName = file.getName(); - if (Pattern.matches("classes.*\\.dex", fileName)) { - count++; - } - } - return count; - } - - // Use the current timestamp as the name of the build file - private String currentTimeStr() { - SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - return df.format(new Date()); - } - - private String[] getXposedModules(String modules) { - if (modules == null || modules.isEmpty()) { - return null; - } - return modules.split(File.pathSeparator); - } - - private static boolean isNotEmpty(String str) { - return str != null && !str.isEmpty(); - } -} diff --git a/xpatch/src/main/java/com/storm/wind/xpatch/base/BaseCommand.java b/xpatch/src/main/java/com/storm/wind/xpatch/base/BaseCommand.java deleted file mode 100644 index 648a50c..0000000 --- a/xpatch/src/main/java/com/storm/wind/xpatch/base/BaseCommand.java +++ /dev/null @@ -1,478 +0,0 @@ -package com.storm.wind.xpatch.base; - -import java.io.File; -import java.io.OutputStreamWriter; -import java.io.PrintWriter; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.lang.reflect.Field; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -/** - * Created by Wind - */ -public abstract class BaseCommand { - - private String onlineHelp; - - protected Map optMap = new HashMap(); - - @Opt(opt = "h", longOpt = "help", hasArg = false, description = "Print this help message") - private boolean printHelp = false; - - protected String[] remainingArgs; - protected String[] orginalArgs; - - @Retention(value = RetentionPolicy.RUNTIME) - @Target(value = { ElementType.FIELD }) - static public @interface Opt { - String argName() default ""; - - String description() default ""; - - boolean hasArg() default true; - - String longOpt() default ""; - - String opt() default ""; - - boolean required() default false; - } - - static protected class Option implements Comparable