Clean hook

This commit is contained in:
pengc 2021-08-09 18:12:35 +08:00
parent a10c8276c9
commit 0ef781a693
3 changed files with 26 additions and 46 deletions

View File

@ -14,33 +14,22 @@ LSPatch provides a way to insert dex and so into the target APK by repackaging.
1. download the artifact 1. download the artifact
1. run `java -jar lspatch.jar` 1. run `java -jar lspatch.jar`
## Dev
```
Android Studio Arctic Fox | 2020.3.1 +
```
## Build ## Build
``` ```
Android Studio Arctic Fox | 2020.3.1 Beta 3 gradlew build<Debug|Release>
```
```
gradlew build[Debug|Release]
``` ```
## Supported Android Versions ## Supported Android Versions
Same with [LSPosed](
https://github.com/LSPosed/LSPosed#supported-versions)
## Principle In theory, same with [LSPosed](https://github.com/LSPosed/LSPosed#supported-versions)
1. Decompress target APK.
1. Patch the app property of AndroidManifest.xml in the target APK, changing it to the Application class in the inserted dex.
1. Copy all files in `list-so`, `list-assets`, `list-dex` into target APK.
1. Package and sign target APK.
Running Stage:
1. Inserted dex initializes LSPosed
1. New ClassLoader from `assets/lsploader.dex`.
1. Loads the Xposed module installed in the system with new ClassLoader.
## Known issues ## Known issues
1. Can't solve the signature verification issue perfectly 1. Can't solve the signature verification issue perfectly
1. If you use under Windows, you need open `CMD/Powershell` with `Run as Administrator`, See [Code](https://github.com/LSPosed/LSPatch/blob/ab1a213161f90ec7ac604df47434201170b92b9a/patch/src/main/java/org/lsposed/patch/util/FileUtils.java#L67-L70).

View File

@ -68,8 +68,6 @@ public class LSPApplication extends ApplicationServiceClient {
private static ClassLoader appClassLoader; private static ClassLoader appClassLoader;
private static Object activityThread; private static Object activityThread;
private static int TRANSACTION_getPackageInfo_ID = -1;
final static public int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000; final static public int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
final static public int PER_USER_RANGE = 100000; final static public int PER_USER_RANGE = 100000;
@ -277,27 +275,14 @@ public class LSPApplication extends ApplicationServiceClient {
} }
} }
private static void byPassSignature(Context context) throws ClassNotFoundException, IllegalAccessException { private static int getTranscationId(String clsName, String trasncationName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Field[] pmStubFields = Class.forName("android.content.pm.IPackageManager$Stub").getDeclaredFields(); Field field = Class.forName(clsName).getDeclaredField(trasncationName);
for (Field field : pmStubFields) {
if (!Modifier.isStatic(field.getModifiers()) || field.getType() != int.class) {
continue;
}
field.setAccessible(true); field.setAccessible(true);
int fieldValue = field.getInt(null); return field.getInt(null);
String fieldName = field.getName();
field.setAccessible(false);
if (fieldName.equals("TRANSACTION_getPackageInfo")) {
TRANSACTION_getPackageInfo_ID = fieldValue;
break;
}
}
if (TRANSACTION_getPackageInfo_ID == -1) {
throw new IllegalStateException("getPackageInfo transaction id null");
} }
private static void byPassSignature(Context context) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
final int TRANSACTION_getPackageInfo = getTranscationId("android.content.pm.IPackageManager$Stub", "TRANSACTION_getPackageInfo");
XposedHelpers.findAndHookMethod("android.os.BinderProxy", appClassLoader, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() { XposedHelpers.findAndHookMethod("android.os.BinderProxy", appClassLoader, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
@Override @Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable { protected void afterHookedMethod(MethodHookParam param) throws Throwable {
@ -322,7 +307,7 @@ public class LSPApplication extends ApplicationServiceClient {
if (desc == null || desc.isEmpty() || !desc.equals("android.content.pm.IPackageManager")) { if (desc == null || desc.isEmpty() || !desc.equals("android.content.pm.IPackageManager")) {
return; return;
} }
if (id == TRANSACTION_getPackageInfo_ID) { if (id == TRANSACTION_getPackageInfo) {
out.readException(); out.readException();
if (0 != out.readInt()) { if (0 != out.readInt()) {
PackageInfo packageInfo = PackageInfo.CREATOR.createFromParcel(out); PackageInfo packageInfo = PackageInfo.CREATOR.createFromParcel(out);
@ -352,13 +337,14 @@ public class LSPApplication extends ApplicationServiceClient {
out.setDataPosition(0); out.setDataPosition(0);
} }
} catch (Throwable err) { } catch (Throwable err) {
err.printStackTrace(); // should not happen, just crash app
throw new IllegalStateException("lsp hook error", err);
} }
} }
}); });
} }
private static void doHook(Context context) throws IllegalAccessException, ClassNotFoundException, IOException { private static void doHook(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException {
if (isApplicationProxied()) { if (isApplicationProxied()) {
hookContextImplSetOuterContext(); hookContextImplSetOuterContext();
hookInstallContentProviders(); hookInstallContentProviders();

View File

@ -38,6 +38,10 @@ import java.util.jar.JarFile;
public class LSPatch { public class LSPatch {
static class PatchError extends Error { static class PatchError extends Error {
public PatchError(String message, Throwable cause) {
super(message, cause);
}
PatchError(String message) { PatchError(String message) {
super(message); super(message);
} }
@ -254,7 +258,8 @@ public class LSPatch {
try (var is = getClass().getClassLoader().getResourceAsStream("assets/so/" + (arch.equals("armeabi") ? "armeabi-v7a" : arch) + "/liblspd.so")) { try (var is = getClass().getClassLoader().getResourceAsStream("assets/so/" + (arch.equals("armeabi") ? "armeabi-v7a" : arch) + "/liblspd.so")) {
zFile.add(entryName, is, false); // no compress for so zFile.add(entryName, is, false); // no compress for so
} catch (Throwable e) { } catch (Throwable e) {
throw new PatchError("Error when adding native lib: " + e); // More exception info
throw new PatchError("Error when adding native lib", e);
} }
if (verbose) if (verbose)
System.out.println("added " + entryName); System.out.println("added " + entryName);