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;
|
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.CONFIG_ASSET_PATH;
|
||||||
import static org.lsposed.lspatch.share.Constants.ORIGINAL_APK_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.pm.Signature;
|
||||||
import android.content.res.CompatibilityInfo;
|
import android.content.res.CompatibilityInfo;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.system.Os;
|
import android.system.Os;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
@ -243,42 +242,18 @@ public class LSPApplication {
|
||||||
return field.getInt(null);
|
return field.getInt(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void bypassSignature(Context context) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
|
private static void bypassSignature(Context context) {
|
||||||
final int TRANSACTION_getPackageInfo = getTranscationId("android.content.pm.IPackageManager$Stub", "TRANSACTION_getPackageInfo");
|
String packageName = context.getPackageName();
|
||||||
XposedHelpers.findAndHookMethod("android.os.BinderProxy", null, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
|
Parcelable.Creator<PackageInfo> originalCreator = PackageInfo.CREATOR;
|
||||||
|
Parcelable.Creator<PackageInfo> proxiedCreator = new Parcelable.Creator<PackageInfo>() {
|
||||||
@Override
|
@Override
|
||||||
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
|
public PackageInfo createFromParcel(Parcel source) {
|
||||||
try {
|
PackageInfo packageInfo = originalCreator.createFromParcel(source);
|
||||||
Object object = param.thisObject;
|
if (packageInfo.packageName.equals(packageName)) {
|
||||||
|
|
||||||
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)) {
|
|
||||||
if (packageInfo.signatures != null && packageInfo.signatures.length > 0) {
|
if (packageInfo.signatures != null && packageInfo.signatures.length > 0) {
|
||||||
XLog.d(TAG, "Replace signature info (method 1)");
|
XLog.d(TAG, "Replace signature info (method 1)");
|
||||||
packageInfo.signatures[0] = new Signature(config.originalSignature);
|
packageInfo.signatures[0] = new Signature(config.originalSignature);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
||||||
if (packageInfo.signingInfo != null) {
|
if (packageInfo.signingInfo != null) {
|
||||||
XLog.d(TAG, "Replace signature info (method 2)");
|
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
|
@Override
|
||||||
out.setDataPosition(0);
|
public PackageInfo[] newArray(int size) {
|
||||||
|
return originalCreator.newArray(size);
|
||||||
}
|
}
|
||||||
} catch (Throwable err) {
|
};
|
||||||
// should not happen, just crash app
|
XposedHelpers.setStaticObjectField(PackageInfo.class, "CREATOR", proxiedCreator);
|
||||||
throw new IllegalStateException("lsp hook error", err);
|
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 {
|
private static void doSigBypass(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue