From fe0bb0f732c0979d8f999873468f73846c637ced Mon Sep 17 00:00:00 2001 From: 327135569 Date: Mon, 5 Apr 2021 00:25:21 +0800 Subject: [PATCH] fix --- xpatch/build.gradle | 1 + .../com/storm/wind/xpatch/MainCommand.java | 28 +++-- .../wind/xpatch/task/SoAndDexCopyTask.java | 39 ++++--- .../com/storm/wind/xpatch/util/FileUtils.java | 107 ++++-------------- 4 files changed, 66 insertions(+), 109 deletions(-) diff --git a/xpatch/build.gradle b/xpatch/build.gradle index fd99b16..d384968 100644 --- a/xpatch/build.gradle +++ b/xpatch/build.gradle @@ -4,6 +4,7 @@ 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 { diff --git a/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java b/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java index 54198b4..2b3250d 100644 --- a/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java +++ b/xpatch/src/main/java/com/storm/wind/xpatch/MainCommand.java @@ -14,12 +14,15 @@ 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; @@ -72,8 +75,14 @@ public class MainCommand extends BaseCommand { new MainCommand().doMain(args); } + private void fuckIfFail(boolean b) { + if (!b) { + throw new IllegalStateException("wtf", new Throwable("DUMPBT")); + } + } + @Override - protected void doCommandLine() { + 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. "); @@ -95,7 +104,7 @@ public class MainCommand extends BaseCommand { return; } - String currentDir = new File(".").getAbsolutePath(); // 当前命令行所在的目录 + String currentDir = new File(".").getAbsolutePath(); System.out.println("currentDir: " + currentDir); System.out.println("apkPath: " + apkPath); @@ -122,11 +131,9 @@ public class MainCommand extends BaseCommand { String apkFileName = getBaseName(srcApkFile); - // 中间文件临时存储的位置 String tempFilePath = outputApkFileParentPath + File.separator + currentTimeStr() + "-tmp" + File.separator; - // apk文件解压的目录 unzipApkFilePath = tempFilePath + apkFileName + "-" + UNZIP_APK_FILE_NAME + File.separator; System.out.println("outputApkFileParentPath: " + outputApkFileParentPath); @@ -137,7 +144,6 @@ public class MainCommand extends BaseCommand { new SaveApkSignatureTask(apkPath, unzipApkFilePath).run(); } - // 先解压apk到指定目录下 long currentTime = System.currentTimeMillis(); FileUtils.decompressZip(apkPath, unzipApkFilePath); @@ -166,15 +172,15 @@ public class MainCommand extends BaseCommand { File manifestFile = new File(manifestFilePath); String manifestFilePathNew = unzipApkFilePath + "AndroidManifest" + "-" + currentTimeStr() + ".xml"; File manifestFileNew = new File(manifestFilePathNew); - manifestFile.renameTo(manifestFileNew); + fuckIfFail(manifestFile.renameTo(manifestFileNew)); modifyManifestFile(manifestFilePathNew, manifestFilePath, applicationName); // new manifest may not exist if (manifestFile.exists() && manifestFile.length() > 0) { - manifestFileNew.delete(); + fuckIfFail(manifestFileNew.delete()); } else { - manifestFileNew.renameTo(manifestFile); + fuckIfFail(manifestFileNew.renameTo(manifestFile)); } // save original main application name to asset file @@ -196,9 +202,7 @@ public class MainCommand extends BaseCommand { // copy origin apk to assets // convenient to bypass some check like CRC - if (!FileUtils.copyFile(srcApkFile, new File(unzipApkFilePath, "assets/origin_apk.bin"))) { - throw new IllegalStateException("orignal apk copy fail"); - } + copyFile(srcApkFile, new File(unzipApkFilePath, "assets/origin_apk.bin")); // excute these tasks for (Runnable executor : mXpatchTasks) { @@ -208,6 +212,8 @@ public class MainCommand extends BaseCommand { 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) { diff --git a/xpatch/src/main/java/com/storm/wind/xpatch/task/SoAndDexCopyTask.java b/xpatch/src/main/java/com/storm/wind/xpatch/task/SoAndDexCopyTask.java index 4a09165..bc966d4 100644 --- a/xpatch/src/main/java/com/storm/wind/xpatch/task/SoAndDexCopyTask.java +++ b/xpatch/src/main/java/com/storm/wind/xpatch/task/SoAndDexCopyTask.java @@ -1,8 +1,9 @@ package com.storm.wind.xpatch.task; -import com.storm.wind.xpatch.util.FileUtils; +import org.apache.commons.io.FileUtils; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -79,27 +80,33 @@ public class SoAndDexCopyTask implements Runnable { } for (File mySoFile : files) { File target = new File(apkSoFullPath, mySoFile.getName()); - FileUtils.copyFile(mySoFile, target); + try { + FileUtils.copyFile(mySoFile, target); + } catch (Exception err) { + throw new IllegalStateException("wtf", err); + } System.out.println("Copy " + mySoFile.getAbsolutePath() + " to " + target.getAbsolutePath()); } } } private void copyDexFile(int dexFileCount) { - boolean copyed = false; - // copy all dex files in list-dex - File[] files = new File("list-dex").listFiles(); - if (files == null || files.length == 0) { - System.out.println("Warning: Nothing dex file has been copied"); - return; - } - for (File file : files) { - String copiedDexFileName = "classes" + (dexFileCount + 1) + ".dex"; - File target = new File(unzipApkFilePath, copiedDexFileName); - FileUtils.copyFile(file, target); - System.out.println("Copy " + file.getAbsolutePath() + " to " + target.getAbsolutePath()); - dexFileCount++; - copyed = true; + try { + // copy all dex files in list-dex + File[] files = new File("list-dex").listFiles(); + if (files == null || files.length == 0) { + System.out.println("Warning: Nothing dex file has been copied"); + return; + } + for (File file : files) { + String copiedDexFileName = "classes" + (dexFileCount + 1) + ".dex"; + File target = new File(unzipApkFilePath, copiedDexFileName); + FileUtils.copyFile(file, target); + System.out.println("Copy " + file.getAbsolutePath() + " to " + target.getAbsolutePath()); + dexFileCount++; + } + } catch (Exception err) { + throw new IllegalStateException("wtf", err); } } diff --git a/xpatch/src/main/java/com/storm/wind/xpatch/util/FileUtils.java b/xpatch/src/main/java/com/storm/wind/xpatch/util/FileUtils.java index afd1d83..d0a0caf 100644 --- a/xpatch/src/main/java/com/storm/wind/xpatch/util/FileUtils.java +++ b/xpatch/src/main/java/com/storm/wind/xpatch/util/FileUtils.java @@ -1,5 +1,8 @@ package com.storm.wind.xpatch.util; +import org.apache.commons.io.FileSystemUtils; +import org.apache.commons.io.IOUtils; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedWriter; @@ -36,64 +39,51 @@ public class FileUtils { * @return 解压结果:成功,失败 */ @SuppressWarnings("rawtypes") - public static boolean decompressZip(String zipPath, String descDir) { + public static void decompressZip(String zipPath, String descDir) throws IOException { File zipFile = new File(zipPath); - boolean flag = false; if (!descDir.endsWith(File.separator)) { descDir = descDir + File.separator; } File pathFile = new File(descDir); if (!pathFile.exists()) { - if(!pathFile.mkdirs()){ + if (!pathFile.mkdirs()) { throw new IllegalStateException("mkdir fail " + pathFile.getAbsolutePath()); } } - ZipFile zip = null; - try { - try { - // api level 24 才有此方法 - zip = new ZipFile(zipFile, Charset.forName("gbk"));//防止中文目录,乱码 - } catch (NoSuchMethodError e) { - // api < 24 - zip = new ZipFile(zipFile); - } + try (ZipFile zip = new ZipFile(zipFile, Charset.forName("gbk"))) { for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) { ZipEntry entry = (ZipEntry) entries.nextElement(); String zipEntryName = entry.getName(); - InputStream in = zip.getInputStream(entry); - //指定解压后的文件夹+当前zip文件的名称 String outPath = (descDir + zipEntryName).replace("/", File.separator); - //判断路径是否存在,不存在则创建文件路径 - File file = new File(outPath.substring(0, outPath.lastIndexOf(File.separator))); + File file = new File(outPath); - if (!file.exists()) { - if(!file.mkdirs()){ + if (entry.isDirectory()) { + if (!file.mkdirs()) { throw new IllegalStateException("mkdir fail " + file.getAbsolutePath()); } - } - //判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压 - if (new File(outPath).isDirectory()) { continue; } - //保存文件路径信息(可利用md5.zip名称的唯一性,来判断是否已经解压) -// System.err.println("当前zip解压之后的路径为:" + outPath); - OutputStream out = new FileOutputStream(outPath); - byte[] buf1 = new byte[2048]; - int len; - while ((len = in.read(buf1)) > 0) { - out.write(buf1, 0, len); + + try (InputStream in = zip.getInputStream(entry)) { + if (file.getParentFile() != null && !file.getParentFile().exists()) { + if (!file.getParentFile().mkdirs()) { + throw new IllegalStateException("mkdir fail " + file.getAbsolutePath()); + } + if (System.getProperty("os.name", "").toLowerCase().contains("win")) { + Runtime.getRuntime().exec("fsutil file setCaseSensitiveInfo " + file.getParentFile().getAbsolutePath()); + System.out.println("Enable setCaseSensitiveInfo for " + file.getParentFile().getAbsolutePath()); + } + } + OutputStream out = new FileOutputStream(outPath); + IOUtils.copy(in, out); + out.close(); + } catch (Exception err) { + throw new IllegalStateException("wtf", err); } - close(in); - close(out); } - flag = true; - close(zip); - } catch (IOException e) { - e.printStackTrace(); } - return flag; } private static InputStream getInputStreamFromFile(String filePath) { @@ -125,53 +115,6 @@ public class FileUtils { } } - public static void copyFile(String sourcePath, String targetPath) { - copyFile(new File(sourcePath), new File(targetPath)); - } - - public static boolean copyFile(File source, File target) { - - FileInputStream inputStream = null; - FileOutputStream outputStream = null; - try { - inputStream = new FileInputStream(source); - outputStream = new FileOutputStream(target); - FileChannel iChannel = inputStream.getChannel(); - FileChannel oChannel = outputStream.getChannel(); - - ByteBuffer buffer = ByteBuffer.allocate(1024); - while (true) { - buffer.clear(); - int r = iChannel.read(buffer); - if (r == -1) { - break; - } - buffer.limit(buffer.position()); - buffer.position(0); - oChannel.write(buffer); - } - return true; - } catch (IOException e) { - e.printStackTrace(); - } finally { - close(inputStream); - close(outputStream); - } - return false; - } - - public static void deleteDir(File file) { - if (file.isDirectory()) { - File[] files = file.listFiles(); - if (files != null && files.length > 0) { - for (File f : files) { - deleteDir(f); - } - } - } - file.delete(); - } - public static void compressToZip(String srcPath, String dstPath) { File srcFile = new File(srcPath); File dstFile = new File(dstPath);