replace PackageInfo.CREATOR to hook creation of PackageInfo in all Parcel api (#117)
* replace PackageInfo.CREATOR to hook creation of PackageInfo in all Parcel api * also clear Parcel.sPairedCreators
This commit is contained in:
parent
eb870b593d
commit
030e1e54bc
|
|
@ -1,6 +1,5 @@
|
|||
package org.lsposed.lspatch.loader;
|
||||
|
||||
import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
|
||||
import static org.lsposed.lspatch.share.Constants.CONFIG_ASSET_PATH;
|
||||
import static org.lsposed.lspatch.share.Constants.ORIGINAL_APK_ASSET_PATH;
|
||||
|
||||
|
|
@ -12,8 +11,8 @@ import android.content.pm.PackageInfo;
|
|||
import android.content.pm.Signature;
|
||||
import android.content.res.CompatibilityInfo;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.system.Os;
|
||||
import android.util.Log;
|
||||
|
||||
|
|
@ -243,42 +242,18 @@ public class LSPApplication {
|
|||
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", null, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
|
||||
private static void bypassSignature(Context context) {
|
||||
String packageName = context.getPackageName();
|
||||
Parcelable.Creator<PackageInfo> originalCreator = PackageInfo.CREATOR;
|
||||
Parcelable.Creator<PackageInfo> proxiedCreator = new Parcelable.Creator<PackageInfo>() {
|
||||
@Override
|
||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
||||
try {
|
||||
Object object = param.thisObject;
|
||||
|
||||
int id = (int) param.args[0];
|
||||
Parcel write = (Parcel) param.args[1];
|
||||
Parcel out = (Parcel) param.args[2];
|
||||
|
||||
// forward check
|
||||
if (write == null || out == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent recurise call
|
||||
if (id == IBinder.INTERFACE_TRANSACTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
String desc = (String) XposedHelpers.callMethod(object, "getInterfaceDescriptor");
|
||||
if (desc == null || desc.isEmpty() || !desc.equals("android.content.pm.IPackageManager")) {
|
||||
return;
|
||||
}
|
||||
if (id == TRANSACTION_getPackageInfo) {
|
||||
out.readException();
|
||||
if (0 != out.readInt()) {
|
||||
PackageInfo packageInfo = PackageInfo.CREATOR.createFromParcel(out);
|
||||
if (packageInfo.packageName.equals(context.getApplicationInfo().packageName)) {
|
||||
public PackageInfo createFromParcel(Parcel source) {
|
||||
PackageInfo packageInfo = originalCreator.createFromParcel(source);
|
||||
if (packageInfo.packageName.equals(packageName)) {
|
||||
if (packageInfo.signatures != null && packageInfo.signatures.length > 0) {
|
||||
XLog.d(TAG, "Replace signature info (method 1)");
|
||||
packageInfo.signatures[0] = new Signature(config.originalSignature);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||
if (packageInfo.signingInfo != null) {
|
||||
XLog.d(TAG, "Replace signature info (method 2)");
|
||||
|
|
@ -288,24 +263,30 @@ public class LSPApplication {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
out.setDataPosition(0);
|
||||
out.setDataSize(0);
|
||||
out.writeNoException();
|
||||
out.writeInt(1);
|
||||
packageInfo.writeToParcel(out, PARCELABLE_WRITE_RETURN_VALUE);
|
||||
}
|
||||
return packageInfo;
|
||||
}
|
||||
|
||||
// reset pos
|
||||
out.setDataPosition(0);
|
||||
@Override
|
||||
public PackageInfo[] newArray(int size) {
|
||||
return originalCreator.newArray(size);
|
||||
}
|
||||
} catch (Throwable err) {
|
||||
// should not happen, just crash app
|
||||
throw new IllegalStateException("lsp hook error", err);
|
||||
};
|
||||
XposedHelpers.setStaticObjectField(PackageInfo.class, "CREATOR", proxiedCreator);
|
||||
try {
|
||||
Map<?, ?> mCreators = (Map<?, ?>) XposedHelpers.getStaticObjectField(Parcel.class, "mCreators");
|
||||
mCreators.clear();
|
||||
} catch (NoSuchFieldError ignore) {
|
||||
} catch (Throwable e) {
|
||||
Log.w(TAG, "fail to clear Parcel.mCreators", e);
|
||||
}
|
||||
try {
|
||||
Map<?, ?> sPairedCreators = (Map<?, ?>) XposedHelpers.getStaticObjectField(Parcel.class, "sPairedCreators");
|
||||
sPairedCreators.clear();
|
||||
} catch (NoSuchFieldError ignore) {
|
||||
} catch (Throwable e) {
|
||||
Log.w(TAG, "fail to clear Parcel.sPairedCreators", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void doSigBypass(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException {
|
||||
|
|
|
|||
Loading…
Reference in New Issue