minor fix
This commit is contained in:
parent
1dc5f03391
commit
4dae1df889
|
|
@ -86,14 +86,12 @@ public class LSPApplication {
|
||||||
XLog.d(TAG, "original application class " + originalApplicationName);
|
XLog.d(TAG, "original application class " + originalApplicationName);
|
||||||
XLog.d(TAG, "original signature info " + originalSignature);
|
XLog.d(TAG, "original signature info " + originalSignature);
|
||||||
|
|
||||||
if (isApplicationProxied()) {
|
try {
|
||||||
try {
|
doHook();
|
||||||
doHook();
|
initAndLoadModules(context);
|
||||||
initAndLoadModules(context);
|
}
|
||||||
}
|
catch (Exception e) {
|
||||||
catch (Exception e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -214,10 +212,12 @@ public class LSPApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void doHook() throws IllegalAccessException, ClassNotFoundException, IOException {
|
private static void doHook() throws IllegalAccessException, ClassNotFoundException, IOException {
|
||||||
hookContextImplSetOuterContext();
|
if (isApplicationProxied()) {
|
||||||
hookInstallContentProviders();
|
hookContextImplSetOuterContext();
|
||||||
hookActivityAttach();
|
hookInstallContentProviders();
|
||||||
hookServiceAttach();
|
hookActivityAttach();
|
||||||
|
hookServiceAttach();
|
||||||
|
}
|
||||||
if (fetchSigbypassLv() >= Constants.SIGBYPASS_LV_PM) {
|
if (fetchSigbypassLv() >= Constants.SIGBYPASS_LV_PM) {
|
||||||
byPassSignature();
|
byPassSignature();
|
||||||
}
|
}
|
||||||
|
|
@ -318,18 +318,11 @@ public class LSPApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
|
|
||||||
// 将applicationInfo中保存的applcation class name还原为真实的application class name
|
|
||||||
if (isApplicationProxied()) {
|
if (isApplicationProxied()) {
|
||||||
modifyApplicationInfoClassName();
|
modifyApplicationInfoClassName();
|
||||||
}
|
|
||||||
|
|
||||||
if (isApplicationProxied()) {
|
|
||||||
attachOrignalBaseContext(base);
|
attachOrignalBaseContext(base);
|
||||||
setLoadedApkField(base);
|
setLoadedApkField(base);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setApplicationLoadedApk(base);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attachOrignalBaseContext(Context base) {
|
private void attachOrignalBaseContext(Context base) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ public class LSPApplicationStub extends Application {
|
||||||
// load real lsp loader from asset
|
// load real lsp loader from asset
|
||||||
Context context = createAppContext();
|
Context context = createAppContext();
|
||||||
if (context == null) {
|
if (context == null) {
|
||||||
Log.e(TAG, "create context err");
|
throw new IllegalStateException("create context err");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
try (InputStream inputStream = context.getAssets().open("lsploader.dex");
|
try (InputStream inputStream = context.getAssets().open("lsploader.dex");
|
||||||
|
|
@ -57,13 +57,11 @@ public class LSPApplicationStub extends Application {
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
if (realLSPApplication != null) {
|
try {
|
||||||
try {
|
realLSPApplication.getClass().getDeclaredMethod("onCreate").invoke(realLSPApplication);
|
||||||
realLSPApplication.getClass().getDeclaredMethod("onCreate").invoke(realLSPApplication);
|
}
|
||||||
}
|
catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
||||||
catch (Exception e) {
|
throw new IllegalStateException("wtf", e);
|
||||||
throw new IllegalStateException("wtf", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,15 +69,13 @@ public class LSPApplicationStub extends Application {
|
||||||
protected void attachBaseContext(Context base) {
|
protected void attachBaseContext(Context base) {
|
||||||
super.attachBaseContext(base);
|
super.attachBaseContext(base);
|
||||||
|
|
||||||
if (realLSPApplication != null) {
|
try {
|
||||||
try {
|
Method method = realLSPApplication.getClass().getDeclaredMethod("attachBaseContext", Context.class);
|
||||||
Method method = realLSPApplication.getClass().getDeclaredMethod("attachBaseContext", Context.class);
|
method.setAccessible(true);
|
||||||
method.setAccessible(true);
|
method.invoke(realLSPApplication, base);
|
||||||
method.invoke(realLSPApplication, base);
|
}
|
||||||
}
|
catch (IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
|
||||||
catch (Exception e) {
|
throw new IllegalStateException("wtf", e);
|
||||||
throw new IllegalStateException("wtf", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,7 +113,7 @@ public class LSPApplicationStub extends Application {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
|
catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException | NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
throw new IllegalStateException("wtf", e);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ import com.wind.meditor.property.AttributeItem;
|
||||||
import com.wind.meditor.property.ModificationProperty;
|
import com.wind.meditor.property.ModificationProperty;
|
||||||
import com.wind.meditor.utils.NodeValue;
|
import com.wind.meditor.utils.NodeValue;
|
||||||
|
|
||||||
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.lsposed.lspatch.share.Constants;
|
import org.lsposed.lspatch.share.Constants;
|
||||||
import org.lsposed.patch.base.BaseCommand;
|
import org.lsposed.patch.base.BaseCommand;
|
||||||
import org.lsposed.patch.task.BuildAndSignApkTask;
|
import org.lsposed.patch.task.BuildAndSignApkTask;
|
||||||
import org.lsposed.patch.task.SaveApkSignatureTask;
|
import org.lsposed.patch.task.SaveApkSignatureTask;
|
||||||
import org.lsposed.patch.task.SaveOriginalApplicationNameTask;
|
import org.lsposed.patch.task.SaveOriginalApplicationNameTask;
|
||||||
import org.lsposed.patch.task.SoAndDexCopyTask;
|
import org.lsposed.patch.task.SoAndDexCopyTask;
|
||||||
import org.lsposed.patch.util.FileUtils;
|
import org.lsposed.patch.util.ZipUtils;
|
||||||
import org.lsposed.patch.util.ManifestParser;
|
import org.lsposed.patch.util.ManifestParser;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -123,7 +124,7 @@ public class LSPatch extends BaseCommand {
|
||||||
new SaveApkSignatureTask(apkPath, unzipApkFilePath).run();
|
new SaveApkSignatureTask(apkPath, unzipApkFilePath).run();
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
FileUtils.decompressZip(apkPath, unzipApkFilePath);
|
ZipUtils.decompressZip(apkPath, unzipApkFilePath);
|
||||||
|
|
||||||
System.out.println("decompress apk cost time: " + (System.currentTimeMillis() - currentTime) + "ms");
|
System.out.println("decompress apk cost time: " + (System.currentTimeMillis() - currentTime) + "ms");
|
||||||
|
|
||||||
|
|
@ -143,8 +144,7 @@ public class LSPatch extends BaseCommand {
|
||||||
applicationName = pair.applicationName;
|
applicationName = pair.applicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println("Get application name cost time: " + (System.currentTimeMillis() - currentTime) + "ms");
|
System.out.println("original application name: " + applicationName);
|
||||||
System.out.println("Get the application name: " + applicationName);
|
|
||||||
|
|
||||||
// modify manifest
|
// modify manifest
|
||||||
File manifestFile = new File(manifestFilePath);
|
File manifestFile = new File(manifestFilePath);
|
||||||
|
|
@ -152,7 +152,7 @@ public class LSPatch extends BaseCommand {
|
||||||
File manifestFileNew = new File(manifestFilePathNew);
|
File manifestFileNew = new File(manifestFilePathNew);
|
||||||
fuckIfFail(manifestFile.renameTo(manifestFileNew));
|
fuckIfFail(manifestFile.renameTo(manifestFileNew));
|
||||||
|
|
||||||
modifyManifestFile(manifestFilePathNew, manifestFilePath, applicationName);
|
modifyManifestFile(manifestFilePathNew, manifestFilePath);
|
||||||
|
|
||||||
// new manifest may not exist
|
// new manifest may not exist
|
||||||
if (manifestFile.exists() && manifestFile.length() > 0) {
|
if (manifestFile.exists() && manifestFile.length() > 0) {
|
||||||
|
|
@ -162,12 +162,10 @@ public class LSPatch extends BaseCommand {
|
||||||
fuckIfFail(manifestFileNew.renameTo(manifestFile));
|
fuckIfFail(manifestFileNew.renameTo(manifestFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
// save original main application name to asset file
|
// save original main application name to asset file even its empty
|
||||||
if (isNotEmpty(applicationName)) {
|
new SaveOriginalApplicationNameTask(applicationName, unzipApkFilePath).run();
|
||||||
new SaveOriginalApplicationNameTask(applicationName, unzipApkFilePath).run();
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy xposed so and dex files into the unzipped apk
|
// copy so and dex files into the unzipped apk
|
||||||
new SoAndDexCopyTask(dexFileCount, unzipApkFilePath).run();
|
new SoAndDexCopyTask(dexFileCount, unzipApkFilePath).run();
|
||||||
|
|
||||||
// copy origin apk to assets
|
// copy origin apk to assets
|
||||||
|
|
@ -178,14 +176,14 @@ public class LSPatch extends BaseCommand {
|
||||||
|
|
||||||
File[] listAssets = new File("list-assets").listFiles();
|
File[] listAssets = new File("list-assets").listFiles();
|
||||||
if (listAssets == null || listAssets.length == 0) {
|
if (listAssets == null || listAssets.length == 0) {
|
||||||
System.out.println("warning: No assets file copyied");
|
System.out.println("Warning: No assets file copyied");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
copyDirectory(new File("list-assets"), new File(unzipApkFilePath, "assets"));
|
copyDirectory(new File("list-assets"), new File(unzipApkFilePath, "assets"));
|
||||||
}
|
}
|
||||||
|
|
||||||
// save lspatch config to asset..
|
// save lspatch config to asset..
|
||||||
org.apache.commons.io.FileUtils.write(new File(unzipApkFilePath, "assets" + File.separator + Constants.CONFIG_NAME_SIGBYPASSLV + sigbypassLevel), "lspatch",
|
FileUtils.write(new File(unzipApkFilePath, "assets" + File.separator + Constants.CONFIG_NAME_SIGBYPASSLV + sigbypassLevel), "lspatch",
|
||||||
Charset.defaultCharset());
|
Charset.defaultCharset());
|
||||||
|
|
||||||
// compress all files into an apk and then sign it.
|
// compress all files into an apk and then sign it.
|
||||||
|
|
@ -194,18 +192,14 @@ public class LSPatch extends BaseCommand {
|
||||||
System.out.println("Output APK: " + outputPath);
|
System.out.println("Output APK: " + outputPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void modifyManifestFile(String filePath, String dstFilePath, String originalApplicationName) {
|
private void modifyManifestFile(String filePath, String dstFilePath) {
|
||||||
ModificationProperty property = new ModificationProperty();
|
ModificationProperty property = new ModificationProperty();
|
||||||
boolean modifyEnabled = false;
|
|
||||||
|
|
||||||
if (debuggableFlag >= 0) {
|
if (debuggableFlag >= 0) {
|
||||||
modifyEnabled = true;
|
|
||||||
property.addApplicationAttribute(new AttributeItem(NodeValue.Application.DEBUGGABLE, debuggableFlag != 0));
|
property.addApplicationAttribute(new AttributeItem(NodeValue.Application.DEBUGGABLE, debuggableFlag != 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
property.addApplicationAttribute(new AttributeItem("extractNativeLibs", true));
|
property.addApplicationAttribute(new AttributeItem("extractNativeLibs", true));
|
||||||
|
|
||||||
modifyEnabled = true;
|
|
||||||
property.addApplicationAttribute(new AttributeItem(NodeValue.Application.NAME, proxyName));
|
property.addApplicationAttribute(new AttributeItem(NodeValue.Application.NAME, proxyName));
|
||||||
|
|
||||||
FileProcesser.processManifestFile(filePath, dstFilePath, property);
|
FileProcesser.processManifestFile(filePath, dstFilePath, property);
|
||||||
|
|
@ -236,15 +230,4 @@ public class LSPatch extends BaseCommand {
|
||||||
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
|
||||||
return df.format(new Date());
|
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -2,11 +2,14 @@ package org.lsposed.patch.task;
|
||||||
|
|
||||||
import com.android.apksigner.ApkSignerTool;
|
import com.android.apksigner.ApkSignerTool;
|
||||||
|
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.lsposed.patch.LSPatch;
|
import org.lsposed.patch.LSPatch;
|
||||||
import org.lsposed.patch.util.FileUtils;
|
import org.lsposed.patch.util.ZipUtils;
|
||||||
import org.lsposed.patch.util.ShellCmdUtil;
|
import org.lsposed.patch.util.ShellCmdUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -33,7 +36,7 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
File unzipApkFile = new File(unzipApkFilePath);
|
File unzipApkFile = new File(unzipApkFilePath);
|
||||||
|
|
||||||
String unsignedApkPath = unzipApkFile.getParent() + File.separator + "unsigned.apk";
|
String unsignedApkPath = unzipApkFile.getParent() + File.separator + "unsigned.apk";
|
||||||
FileUtils.compressToZip(unzipApkFilePath, unsignedApkPath);
|
ZipUtils.compressToZip(unzipApkFilePath, unsignedApkPath);
|
||||||
|
|
||||||
String keyStoreFilePath = unzipApkFile.getParent() + File.separator + "keystore";
|
String keyStoreFilePath = unzipApkFile.getParent() + File.separator + "keystore";
|
||||||
|
|
||||||
|
|
@ -49,7 +52,10 @@ public class BuildAndSignApkTask implements Runnable {
|
||||||
keyStoreAssetPath = "assets/keystore";
|
keyStoreAssetPath = "assets/keystore";
|
||||||
}
|
}
|
||||||
|
|
||||||
FileUtils.copyFileFromJar(keyStoreAssetPath, keyStoreFilePath);
|
try (InputStream inputStream = getClass().getResourceAsStream(keyStoreAssetPath);
|
||||||
|
FileOutputStream out = new FileOutputStream(keyStoreFilePath)) {
|
||||||
|
IOUtils.copy(inputStream, out);
|
||||||
|
}
|
||||||
|
|
||||||
boolean signResult = signApk(unsignedApkPath, keyStoreFilePath, signedApkPath);
|
boolean signResult = signApk(unsignedApkPath, keyStoreFilePath, signedApkPath);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package org.lsposed.patch.task;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by xiawanli on 2019/4/6
|
* Created by xiawanli on 2019/4/6
|
||||||
|
|
@ -25,8 +26,7 @@ public class SaveOriginalApplicationNameTask implements Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
ensureDstFileCreated();
|
FileUtils.write(new File(dstFilePath), applcationName, Charset.defaultCharset());
|
||||||
FileUtils.write(new File(dstFilePath), applcationName);
|
|
||||||
}
|
}
|
||||||
catch (Exception err) {
|
catch (Exception err) {
|
||||||
// just crash
|
// just crash
|
||||||
|
|
@ -34,18 +34,4 @@ public class SaveOriginalApplicationNameTask implements Runnable {
|
||||||
throw new IllegalStateException("wtf", err);
|
throw new IllegalStateException("wtf", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ensureDstFileCreated() {
|
|
||||||
File dstParentFile = new File(dstFilePath);
|
|
||||||
if (!dstParentFile.getParentFile().getParentFile().exists()) {
|
|
||||||
if (!dstParentFile.getParentFile().getParentFile().mkdirs()) {
|
|
||||||
throw new IllegalStateException("mkdir fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!dstParentFile.getParentFile().exists()) {
|
|
||||||
if (!dstParentFile.getParentFile().mkdirs()) {
|
|
||||||
throw new IllegalStateException("mkdir fail");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
@ -20,7 +20,7 @@ import java.util.zip.ZipOutputStream;
|
||||||
/**
|
/**
|
||||||
* Created by Wind
|
* Created by Wind
|
||||||
*/
|
*/
|
||||||
public class FileUtils {
|
public class ZipUtils {
|
||||||
|
|
||||||
static final int BUFFER = 8192;
|
static final int BUFFER = 8192;
|
||||||
|
|
||||||
|
|
@ -82,18 +82,6 @@ public class FileUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static InputStream getInputStreamFromFile(String filePath) {
|
|
||||||
return FileUtils.class.getClassLoader().getResourceAsStream(filePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
// copy an asset file into a path
|
|
||||||
public static void copyFileFromJar(String inJarPath, String distPath) throws IOException {
|
|
||||||
// System.out.println("start copyFile inJarPath =" + inJarPath + " distPath = " + distPath);
|
|
||||||
try (InputStream inputStream = getInputStreamFromFile(inJarPath); FileOutputStream out = new FileOutputStream(distPath)) {
|
|
||||||
IOUtils.copy(inputStream, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void compressToZip(String srcPath, String dstPath) {
|
public static void compressToZip(String srcPath, String dstPath) {
|
||||||
File srcFile = new File(srcPath);
|
File srcFile = new File(srcPath);
|
||||||
File dstFile = new File(dstPath);
|
File dstFile = new File(dstPath);
|
||||||
Loading…
Reference in New Issue