应用签名获取方式(替换目标pkg)
PackageManager manager = context.getPackageManager()
PackageInfo packageInfo = manager.getPackageInfo("target package name", PackageManager.GET_SIGNATURES)
Signature[] signatures = packageInfo.signatures
String str = signatures[0].toCharsString()
如何变更签名(二次打包签名绕过)
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread")
Method currentActicityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread")
ActivityThread currentActivityThread = (ActivityThread) currentActicityThreadMethod.invoke(null)
Field sPackageManagerField = activityThreadClass.getDeclaredField("sPackageManager")
sPackageManagerField.setAccessible(true)
Object sPackageManager = sPackageManagerField.get(currentActivityThread)
Class<?> iPackageManagerInterface = Class.forName("android.content.pm.IPackageManager")
//代理替换
Object proxy = Proxy.newProxyInstance(iPackageManagerInterface.getClass().getClassLoader(), new Class[]{iPackageManagerInterface}, new HookSign(sPackageManager))
sPackageManagerField.set(currentActivityThread, proxy)
PackageManager pm = context.getPackageManager()
Field mPMField = pm.getClass().getDeclaredField("mPM")
mPMField.setAccessible(true)
mPMField.set(pm, proxy)
如何防止二次打包?
- 签名校验?貌似对上述方案不靠谱
- 代理check?听起来有点靠谱
- 其它方式,欢迎留言一起讨论!
检测系统Api是否被Hook过?
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && proxyClassCache.containsValue(cl);
}
PackageManager manager = context.getPackageManager();
Field mPM = manager.getClass().getDeclaredField("mPM");
mPM.setAccessible(true);
if (Proxy.isProxyClass(mPM.get(manager).getClass())) {
}