距离我发布Pokemon Go Plus研究发现已近6个月,至今无人公开其Pokemon Go Plus密钥。其中一个原因是从OTP(一次性可编程)存储器提取密钥需要精密焊接技术。在我发表文章几周后,我在/r/pokemongodev提出了通过空中下载(OTA)更新提取Pokemon Go Plus密钥的设想。
该设想基于两个事实:
计划方案如下:
两个月前,Reddit用户jesus-bamford联系我并表示将实施该方案。进展看似顺利:
但好消息至此为止:通过OTA写入的固件无法启动。引导程序认为固件无效,会启动Pokemon Go Plus的原始固件。他发现软件更新过程中存在SDK源码未提及的额外验证机制,但无法确定具体验证方式或绕过方法。
在泰国泼水节假期期间,我通过逆向工程引导程序确认了额外验证机制的存在:
关键发现:
通过分析DA14580 SDK中的app_spotar_img_hdlr.c源码,发现关键函数:
ret = spi_flash_write_data(spota_all_pd,
(spota_state.mem_base_add + spota_state.suota_img_idx),
spota_state.suota_block_idx);
其中spota_all_pd包含来自更新应用的数据,第二个参数指定SPI闪存写入地址,第三个参数为数据大小。
更重要的是发现app_spotar_read_mem函数存在设计缺陷:该函数使用spota_state.mem_base_add存储临时值而非使用临时变量。当spota_state.mem_base_add大于2时函数会失败。
利用流程:
Jesus-bamford出色地实现了该方案并取得成功。相关固件已在GitHub开源:
https://github.com/Jesus805/PGP_Suota
目前Android版更新工具尚未发布(正在基于SDK代码重写)。完成后用户将无需拆机即可提取Pokemon Go Plus密钥。
虽然本应等待其工作完成再发布本文,但我希望更多人能参与开发:包括iOS版本实现、其他设备的Pokemon Go Plus适配,甚至通过EdXposed(兼容Pokemon Go的XPosed分支)或iOS BLE API拦截库实现相同功能。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。