如何绕过摩托罗拉软件更新校验

众所周知啊,摩托罗拉软件更新会检测系统环境是否正常,异常就会拒绝更新,从网上找到的方法说把boot还原到原厂就可以正常更新,奈何本人不知什么原因,依然显示"正在下载的更新包与设备上的当前软件版本不兼容。" (本人设备为Moto X30 Pro)

被这个问题困扰了一段时间后,终于痛下决心,准备自己写一个Xposed模块劫持摩托罗拉软件更新,去除校验,过程出乎意料的顺利,只用了一下午就从0写了出来,代码也只是寥寥几十行,反编译apk得到的关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void verifyPayloadMetadata(final String str, final boolean z) {
new Thread(new Runnable() { // from class: com.motorola.ccc.ota.installer.updaterEngine.common.UpdaterEngineHelper.1
@Override // java.lang.Runnable
public void run() {
Logger.debug("OtaApp", "UpdaterEngineHelper:verifyPayloadMetadata");
Context globalContext = OtaApplication.getGlobalContext();
boolean zBooleanValue = false;
try {
UpdaterEngineHelper.setUpdateEngineObject();
zBooleanValue = ((Boolean) UpdaterEngineHelper.updateEngine.getDeclaredMethod("verifyPayloadMetadata", String.class).invoke(UpdaterEngineHelper.mUpdateEngine, str)).booleanValue();
} catch (ClassNotFoundException | IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) {
Logger.error("OtaApp", "exception in UpdaterEngineHelper:verifyPayloadMetadata " + e);
}
Logger.debug("OtaApp", "UpdaterEngHelper:verifyPayloadMetadata:isVerifySuccessful=" + zBooleanValue);
if (z) {
UpgradeUtilMethods.sendActionVerifyPayloadStatus(globalContext, zBooleanValue);
} else if (zBooleanValue) {
UpgradeUtilMethods.sendActionVerifyPayloadStatus(globalContext, "success", UpgradeUtilConstants.DownloadStatus.STATUS_OK, null);
} else {
UpgradeUtilMethods.sendActionVerifyPayloadStatus(globalContext, "Payload metadata verification failed ", UpgradeUtilConstants.DownloadStatus.STATUS_FAIL_PAYLOAD_METADATA_VERIFY, ErrorCodeMapper.KEY_PAYLOAD_METADATA_VERIFICATION_FAILED);
}
}
}).start();
}

代码看起来很明确,开了一个新的线程,用一个反射方法执行检测,检测结束后发送一个广播进行下一步,那么我们的思路就是在校验方法被调用时劫持它,直接返回true,绕过检测,具体实现代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void hook(XC_LoadPackage.LoadPackageParam lpparam) {
findAndHookMethod(
"android.os.UpdateEngine",
lpparam.classLoader,
"verifyPayloadMetadata",
String.class,
new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
XposedBridge.log("[BypassOTACheck] Bypassing android.os.UpdateEngine.verifyPayloadMetadata");
param.setResult(true); // 直接返回true,绕过校验
}
}
);
}

编译运行,Lsposed中激活模块,再次点击更新,成功通过校验,不过记得在校验完成后必须是原厂boot镜像,否则Native模块在写入时还是会校验boot是否更改,这个校验不通过会导致半途报错,所以我推荐刷入原厂boot,然后使用修补后带root的boot临时启动,即 fastboot boot boot.img 这样就可以在保持原厂boot的情况下使用Xposed模块

更新完成后(其实在更新到大约30%-40%的时候boot就已经更新完毕),在root管理器中安装到未使用的槽位,更新完毕后就可以愉快使用啦!

附模块项目地址及下载:Github地址