public
class
Xposed implements IXposedHookLoadPackage {
private static
int
indexOf(byte[] array) {
final byte[] PATTERN
=
{
48
,
74
,
4
,
32
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
1
,
0
,
10
,
1
,
2
};
outer:
for
(
int
i
=
0
; i < array.length
-
PATTERN.length
+
1
; i
+
+
) {
for
(
int
j
=
0
; j < PATTERN.length; j
+
+
) {
if
(array[i
+
j] !
=
PATTERN[j]) {
continue
outer;
}
}
return
i;
}
return
-
1
;
}
@Override
public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {
try
{
KeyStore keyStore
=
KeyStore.getInstance(
"AndroidKeyStore"
);
KeyStoreSpi keyStoreSpi
=
(KeyStoreSpi) XposedHelpers.getObjectField(keyStore,
"keyStoreSpi"
);
XposedHelpers.findAndHookMethod(keyStoreSpi.getClass(),
"engineGetCertificateChain"
, String.
class
, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
Certificate[] certificates
=
(Certificate[]) param.getResultOrThrowable();
if
(certificates[
0
] instanceof X509Certificate cert) {
for
(Method method : cert.getClass().getMethods()) {
if
(method.getName().toLowerCase(Locale.ROOT).contains(
"verify"
)) {
/
/
verify 不抛出异常表示验证通过
XposedBridge.hookMethod(method, XC_MethodReplacement.DO_NOTHING);
}
}
/
/
获取证书编码,修改部分偏移的数据
/
/
修改Device locked:true
/
/
修改Verified boot state: Verified
byte[] bytes
=
cert.getEncoded();
if
(bytes
=
=
null || bytes.length
=
=
0
)
return
;
int
index
=
indexOf(bytes);
/
/
这个索引?
if
(index
=
=
-
1
)
return
;
bytes[index
+
38
]
=
1
;
bytes[index
+
41
]
=
0
;
/
/
替换证书
CertificateFactory certFactory
=
CertificateFactory.getInstance(
"X.509"
);
X509Certificate modCert
=
(X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(bytes));
certificates[
0
]
=
modCert;
param.setResult(certificates);
}
}
});
} catch (Throwable t) {
XposedBridge.log(t);
}
}
}