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. run `java -jar lspatch.jar`
## Dev
```
Android Studio Arctic Fox | 2020.3.1 +
```
## Build
```
Android Studio Arctic Fox | 2020.3.1 Beta 3
```
```
gradlew build[Debug|Release]
gradlew build<Debug|Release>
```
## Supported Android Versions
Same with [LSPosed](
https://github.com/LSPosed/LSPosed#supported-versions)
## Principle
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.
In theory, same with [LSPosed](https://github.com/LSPosed/LSPosed#supported-versions)
## Known issues
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).
1. Can't solve the signature verification issue perfectly

View File

@ -68,8 +68,6 @@ public class LSPApplication extends ApplicationServiceClient {
private static ClassLoader appClassLoader;
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 PER_USER_RANGE = 100000;
@ -277,27 +275,14 @@ public class LSPApplication extends ApplicationServiceClient {
}
}
private static void byPassSignature(Context context) throws ClassNotFoundException, IllegalAccessException {
Field[] pmStubFields = Class.forName("android.content.pm.IPackageManager$Stub").getDeclaredFields();
for (Field field : pmStubFields) {
if (!Modifier.isStatic(field.getModifiers()) || field.getType() != int.class) {
continue;
}
field.setAccessible(true);
int fieldValue = 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 int getTranscationId(String clsName, String trasncationName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Field field = Class.forName(clsName).getDeclaredField(trasncationName);
field.setAccessible(true);
return field.getInt(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() {
@Override
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")) {
return;
}
if (id == TRANSACTION_getPackageInfo_ID) {
if (id == TRANSACTION_getPackageInfo) {
out.readException();
if (0 != out.readInt()) {
PackageInfo packageInfo = PackageInfo.CREATOR.createFromParcel(out);
@ -352,13 +337,14 @@ public class LSPApplication extends ApplicationServiceClient {
out.setDataPosition(0);
}
} 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()) {
hookContextImplSetOuterContext();
hookInstallContentProviders();

View File

@ -38,6 +38,10 @@ import java.util.jar.JarFile;
public class LSPatch {
static class PatchError extends Error {
public PatchError(String message, Throwable cause) {
super(message, cause);
}
PatchError(String 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")) {
zFile.add(entryName, is, false); // no compress for so
} 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)
System.out.println("added " + entryName);