修复bug

This commit is contained in:
Windy 2020-02-08 22:32:53 +08:00
parent 0f2645ee04
commit 863739ea27
9 changed files with 40 additions and 98 deletions

Binary file not shown.

Binary file not shown.

View File

@ -189,7 +189,13 @@ public class MainCommand extends BaseCommand {
manifestFile.renameTo(manifestFileNew);
modifyManifestFile(manifestFilePathNew, manifestFilePath, applicationName);
// new manifest may not exist
if (manifestFile.exists() && manifestFile.length() > 0) {
manifestFileNew.delete();
} else {
manifestFileNew.renameTo(manifestFile);
}
// save original main application name to asset file
if (isNotEmpty(applicationName)) {

View File

@ -36,7 +36,7 @@ public class ApkModifyTask implements Runnable {
String jarOutputPath = unzipApkFile.getParent() + File.separator + JAR_FILE_NAME;
// classes-1.0.dex
// classes.dex
String targetDexFileName = dumpJarFile(dexFileCount, unzipApkFilePath, jarOutputPath, applicationName);
if (showAllLogs) {
@ -104,12 +104,12 @@ public class ApkModifyTask implements Runnable {
cmd.doMain(args);
}
// 列出目录下所有dex文件classes-1.0.dexclasses2.dexclasses3.dex .....
// 列出目录下所有dex文件classes.dexclasses2.dexclasses3.dex .....
private ArrayList<String> createClassesDotDexFileList(int dexFileCount) {
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < dexFileCount; i++) {
if (i == 0) {
list.add("classes-1.0.dex");
list.add("classes.dex");
} else {
list.add("classes" + (i + 1) + ".dex");
}

View File

@ -58,7 +58,7 @@ public class BuildAndSignApkTask implements Runnable {
if (isAndroid()) {
boolean success = true;
try {
ShellCmdUtil.chmod((new File(apkPath)).getParent(), ShellCmdUtil.FileMode.MODE_755);
ShellCmdUtil.chmodNoException((new File(apkPath)).getParent(), ShellCmdUtil.FileMode.MODE_755);
net.fornwall.apksigner.Main.main
("--password", "123456", keyStorePath, apkPath, signedApkPath);
} catch (Exception e1) {
@ -83,7 +83,7 @@ public class BuildAndSignApkTask implements Runnable {
String localJarsignerPath = (new File(apkPath)).getParent() + File.separator + "jarsigner-081688";
localJarsignerFile = new File(localJarsignerPath);
FileUtils.copyFileFromJar("assets/jarsigner", localJarsignerPath);
ShellCmdUtil.chmod(localJarsignerPath, ShellCmdUtil.FileMode.MODE_755);
ShellCmdUtil.chmodNoException(localJarsignerPath, ShellCmdUtil.FileMode.MODE_755);
// ShellCmdUtil.execCmd("chmod -R 777 " + localJarsignerPath, null);
signCmd = new StringBuilder(localJarsignerPath + " ");
}

View File

@ -13,7 +13,9 @@ public class SoAndDexCopyTask implements Runnable {
private static final String SANDHOOK_SO_FILE_NAME = "libsandhook";
private static final String WHALE_SO_FILE_NAME = "libwhale";
private static final String SO_FILE_NAME_WITH_SUFFIX = "libsandhook";
private static final String SANDHOOK_SO_FILE_NAME_WITH_SUFFIX = "libsandhook.so";
private static final String WHALE_SO_FILE_NAME_WITH_SUFFIX = "libwhale.so";
private static final String XPOSED_MODULE_FILE_NAME_PREFIX = "libxpatch_xp_module_";
private static final String SO_FILE_SUFFIX = ".so";
@ -28,11 +30,14 @@ public class SoAndDexCopyTask implements Runnable {
private String unzipApkFilePath;
private String[] xposedModuleArray;
private boolean useWhaleHookFramework;
public SoAndDexCopyTask(int dexFileCount, String unzipApkFilePath,
String[] xposedModuleArray, boolean useWhaleHookFramework) {
this.dexFileCount = dexFileCount;
this.unzipApkFilePath = unzipApkFilePath;
this.xposedModuleArray = xposedModuleArray;
this.useWhaleHookFramework = useWhaleHookFramework;
String soFileName;
if (useWhaleHookFramework) {
@ -113,7 +118,13 @@ public class SoAndDexCopyTask implements Runnable {
// copy dex file to root dir, rename it first
String copiedDexFileName = "classes" + (dexFileCount + 1) + ".dex";
// assets/classes.dex分隔符不能使用File.seperater,否则在windows上无法读取到文件IOException
FileUtils.copyFileFromJar("assets/classes-1.0.dex", unzipApkFilePath + copiedDexFileName);
String dexAssetPath;
if (useWhaleHookFramework) {
dexAssetPath = "assets/dex/whale/classes-1.0.dex";
} else {
dexAssetPath = "assets/dex/sandhook/classes-1.0.dex";
}
FileUtils.copyFileFromJar(dexAssetPath, unzipApkFilePath + copiedDexFileName);
}
private String fullLibPath(String libPath) {
@ -129,7 +140,12 @@ public class SoAndDexCopyTask implements Runnable {
// get the file name first
// int lastIndex = srcSoPath.lastIndexOf('/');
// int length = srcSoPath.length();
String soFileName = SO_FILE_NAME_WITH_SUFFIX;
String soFileName;
if (useWhaleHookFramework) {
soFileName = WHALE_SO_FILE_NAME_WITH_SUFFIX;
} else {
soFileName = SANDHOOK_SO_FILE_NAME_WITH_SUFFIX;
}
// do copy
FileUtils.copyFileFromJar(srcSoPath, new File(apkSoParentFile, soFileName).getAbsolutePath());

View File

@ -3,12 +3,7 @@ package com.storm.wind.xpatch.util;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
/**
* Created by xiawanli on 2018/8/25
*/
public class ReflectUtils {
//获取类的实例的变量的值
@ -269,88 +264,4 @@ public class ReflectUtils {
return findField(base, name);
}
}
//表示Field或者Class是编译器自动生成的
private static final int SYNTHETIC = 0x00001000;
//表示Field是final的
private static final int FINAL = 0x00000010;
//内部类持有的外部类对象一定有这两个属性
private static final int SYNTHETIC_AND_FINAL = SYNTHETIC | FINAL;
private static boolean checkModifier(int mod) {
return (mod & SYNTHETIC_AND_FINAL) == SYNTHETIC_AND_FINAL;
}
//获取内部类实例持有的外部类对象
public static <T> T getExternalField(Object innerObj) {
return getExternalField(innerObj, null);
}
/**
* 内部类持有的外部类对象的形式为
* final Outer this$0;
* flags: ACC_FINAL, ACC_SYNTHETIC
* 参考https://www.jianshu.com/p/9335c15c43cf
* Andhttps://www.2cto.com/kf/201402/281879.html
*
* @param innerObj 内部类对象
* @param name 内部类持有的外部类名称默认是"this$0"
* @return 内部类持有的外部类对象
*/
private static <T> T getExternalField(Object innerObj, String name) {
Class clazz = innerObj.getClass();
if (name == null || name.isEmpty()) {
name = "this$0";
}
Field field;
try {
field = clazz.getDeclaredField(name);
} catch (NoSuchFieldException e) {
e.printStackTrace();
return null;
}
field.setAccessible(true);
if (checkModifier(field.getModifiers())) {
try {
return (T) field.get(innerObj);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
return getExternalField(innerObj, name + "$");
}
//获取当前对象的泛型类 added by xia wanli
public static Class<?> getParameterizedClassType(Object object) {
Class<?> clazz;
//getGenericSuperclass()获得带有泛型的父类
//Type是 Java 中所有类型的公共高级接口包括原始类型参数化类型数组类型类型变量和基本类型
Type genericSuperclass = object.getClass().getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
//ParameterizedType参数化类型即泛型
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
//getActualTypeArguments获取参数化类型的数组泛型可能有多个
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
clazz = (Class<?>) actualTypeArguments[0];
} else {
clazz = (Class<?>) genericSuperclass;
}
return clazz;
}
//获取当前对象的泛型类 added by xia wanli
public static Type getObjectParameterizedType(Object object) {
//getGenericSuperclass()获得带有泛型的父类
//Type是 Java 中所有类型的公共高级接口包括原始类型参数化类型数组类型类型变量和基本类型
Type genericSuperclass = object.getClass().getGenericSuperclass();
if (genericSuperclass instanceof ParameterizedType) {
//ParameterizedType参数化类型即泛型
ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
//getActualTypeArguments获取参数化类型的数组泛型可能有多个
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
return actualTypeArguments[0];
} else {
throw new RuntimeException("Missing type parameter.");
}
}
}

View File

@ -57,6 +57,15 @@ public class ShellCmdUtil {
return result.toString();
}
public static void chmodNoException(String path, int mode) {
try {
chmod(path, mode);
} catch (Exception e) {
e.printStackTrace();
System.err.println("chmod exception path --> " + path + " exception -->" + e.getMessage());
}
}
public static void chmod(String path, int mode) throws Exception {
chmodOnAndroid(path, mode);