修复bug
This commit is contained in:
parent
0f2645ee04
commit
863739ea27
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -189,7 +189,13 @@ public class MainCommand extends BaseCommand {
|
|||
manifestFile.renameTo(manifestFileNew);
|
||||
|
||||
modifyManifestFile(manifestFilePathNew, manifestFilePath, applicationName);
|
||||
manifestFileNew.delete();
|
||||
|
||||
// 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)) {
|
||||
|
|
|
|||
|
|
@ -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.dex,classes2.dex,classes3.dex .....
|
||||
// 列出目录下所有dex文件,classes.dex,classes2.dex,classes3.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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 + " ");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* And:https://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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue