-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathsignature_mock.java
68 lines (58 loc) · 3.02 KB
/
signature_mock.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
public class SignatureMock implements InvocationHandler {
public String mOriginalSignature;
public String mPackageName = "";
public Object mPackageManager;
public SignatureMock(Object pm, String originalSignature, String packageName) {
this.mPackageManager = pm;
this.mOriginalSignature = originalSignature;
this.mPackageName = packageName;
}
@Override // java.lang.reflect.InvocationHandler
public Object invoke(Object obj, Method inMeth, Object[] args) {
PackageInfo packageInfo;
SigningInfo signingInfo;
// Hook getPackageInfo
if ("getPackageInfo".equals(inMeth.getName())) {
String pkgName = (String) args[0];
int flags = ((Integer) args[1]).intValue();
// Handle both
// GET_SIGNATURES (0x00000040) - Deprecated in API 28
// GET_SIGNING_CERTIFICATES (0x08000000)
if ((flags & PackageManager.GET_SIGNATURES) != 0 && this.mPackageName.equals(pkgName)) {
PackageInfo fakePkgInfo = (PackageInfo) inMeth.invoke(this.mPackageManager, args);
// Fake the signature
fakePkgInfo.signatures[0] = new Signature(this.mOriginalSignature);
return fakePkgInfo;
} else if (Build.VERSION.SDK_INT >= 28 &&
(flags & GET_SIGNING_CERTIFICATES) != 0 &&
this.mPackageName.equals(pkgName) &&
(signingInfo = (packageInfo = (PackageInfo) method.invoke(this.mPackageManager, args)).signingInfo) != null) {
Field FieldSigningDetails = signingInfo.getClass().getDeclaredField("mSigningDetails");
FieldSigningDetails.setAccessible(true);
Object mSigningDetails = FieldSigningD.get(packageInfo);
Signature[] fakeSigArray = {new Signature(this.mOriginalSignature)};
Field FieldSignatures = mSigningDetails.getClass().getDeclaredField("signatures");
FieldSignatures.setAccessible(true);
FieldSignatures.set(FieldSigningDetails, fakeSigArray);
return packageInfo;
}
}
return inMeth.invoke(this.mPackageManager, args);
}
}
public static void proxifySignatureCheck(Context context) {
String packageName = context.getPackageName();
Class<?> aThreadCls = Class.forName("android.app.ActivityThread");
Object mCurrentActivityThread = aThreadCls.getDeclaredMethod("currentActivityThread", new Class[0]).invoke(null, new Object[0]);
Field sPackageManager = aThreadCls.getDeclaredField("sPackageManager");
sPackageManager.setAccessible(true);
Object pm = sPackageManager.get(mCurrentActivityThread);
Class<?> IPackageManager = Class.forName("android.content.pm.IPackageManager");
SignatureMock mock = new SignatureMock(pm, "30820 [ ... ] aa001f55", packageName)
Object newProxyInstance = Proxy.newProxyInstance(IPackageManager.getClassLoader(), new Class[]{IPackageManager}, mock);
sPackageManager.set(mCurrentActivityThread, newProxyInstance);
PackageManager packageManager = context.getPackageManager();
Field mPM = packageManager.getClass().getDeclaredField("mPM");
mPM.setAccessible(true);
mPM.set(packageManager, newProxyInstance);
}