前一阵子京东入了个大法的WH-1000XM2,感觉程序有一些小毛病,而且那中文的语音实在是…作为一个不折腾会死星人,拿到手之后不久就研究能否刷机更新固件。上网谷歌了一圈,貌似已经发布了2.0.1的固件,但配套程序并没有更新提示,于是就怀疑是国行的问题。上网再查了一圈貌似并没有人折腾这玩意的固件,也没有人搞强制刷机,那只能自己动手丰衣足食了。

最终更新/FINAL UPDATE
这篇文章是1年半之前写的,Sony Headphone Connect已经更新迭代了数个版本,XM2/XM3等机子的更新也迭代了数个版本。这个文章的内容已经 不再适用 。鉴于我现在已经没有使用索尼的耳机(去年因为一些质量问题退回给京东了),我也没有继续研究下去的想法。Reddit上有一些新版本的教程,请善用Reddit的站内搜索和Google。
 
In English: This article was drafted back in 2018 and since then, both Sony headphones’ firmware and the Sony Headphone Connect app has been updated for times. Any information in this article is outdated, and since I have returned my WH-1000XM2 back to JD (a Chinese shopping platform where I bought the headphone), I have no thoughts to continue my research and update this article. I observed that there are some other modified versions of this tutorial on Reddit. Please make use of Reddit and Google for the latest way to change the region of your headphones’ firmware.

 

更新:WH-1000XM3(但不是XM2)的国行4.1.3版本带有语音语言切换功能。如果您WH-1000XM3的使用者并且仅对本功能有需求,我建议您不要看本教程,通过正规渠道升级到4.1.3即可。
 
另一条更新:这种修改逻辑不适用于2.0.1(国际版)更新到4.1.3(国内版),根据贴吧大佬的分析,原因在此。如果你按照本贴教程升级到了2.0.1但后悔了,想回滚到国内版本的4.1.3,或许你可以尝试这大佬的解决方案(我本人对刷回国行没有需求所以没有试过,请尝试的人仔细阅读他所提及的注意事项)。

提醒及警告

这篇博文讲的任何内容并不受Sony官方支持,本人也并不对此造成的保修作废、耳机变砖、耳机电池爆炸等等等等的任何问题负责。尝试本博文的方法带来的任何后果自负。本文所提供的内容仅适用于WH-1000XM2,其余型号请自行研究。本文所提供的内容仅针对Sony Headphone Connect 3.2.0版本。

根据LvWind的博客的文章,Headphone Connect 4.0+版本已经改掉了这些检测逻辑,需要修改的位置可能跟本教程不同。如果你需要WI-1000X或者WH-1000XM3的各版本MDRID,你也可以参考LvWind的文章。

准备工具

  • Apktool (旧版的可能有问题,建议最新的2.3.3)
  • 一个靠谱的文本编辑器

我的研究过程

提醒:你用别的方法反编译后类、方法、命名空间等的命名不一定与我的相同,建议善用文本搜索

TL,DR:如果你不想看我的研究过程只想看教程或者下载我打包的文件,请跳至页尾

首先上网找了个在线反编译的网站反编译了一遍,下到本地。用IJ尝试重新编译成APK,发现失败,于是放弃用在线的反编译工具,仅把这反编译的代码作为参考。然后用Apktool拆包了一下,看到一堆smali指令码,也没什么头绪从何入手。

然后我在手机那抓了个包,发现软件启动的时候请求http://info.update.sony.net/HP001/MDRID289202/info/info.xml,居然返回的是404。不负责任的猜测了一下MDRID289202是机身的内部型号(包括版本号)。全局搜索了一下源码发现info.update.sony.netcom.sony.songpal.mdr.automagic.AutoMagicManager里面。

    private URL m9721d(String str, String str2) {
        String str3 = "info.update.sony.net";
        if (str == null) {
            throw new IllegalStateException(String.format(Locale.getDefault(), "%s:code=%d", new Object[]{"AutoMagicManagerErrorDomain", Integer.valueOf(AutoMagicError.NoCategoryID.ordinal())}));
        } else if (str2 == null) {
            throw new IllegalStateException(String.format(Locale.getDefault(), "%s:code=%d", new Object[]{"AutoMagicManagerErrorDomain", Integer.valueOf(AutoMagicError.NoServiceID.ordinal())}));
        } else {
            try {
                return new URL(String.format(Locale.getDefault(), "http://%s/%s/%s/info/%s", new Object[]{str3, str, str2, "info.xml"}));
            } catch (Throwable e) {
                SpLog.m12039a(f5487a, e);
                return null;
            }
        }
    }

这玩意用了两个字符串类的参数,然后在URL里面就是HP001和MDRID289202,于是猜测假如我篡改这个参数的获取程序使其获取成国外行货的代码,大概就能强制更新了(前提是硬件完全一样)。顺藤摸瓜检查m9271d这方法的调用,查到了保存这个参数的类com.sony.songpal.mdr.application.p061b.C1702a

    void m7942a(C2503b c2503b) {
        if (Command.fromByteCode(c2503b.m11224a()) == Command.UPDT_RET_PARAM) {
            cm cmVar = (cm) c2503b;
            if (cmVar.m11579e() != this.f4438n) {
                SpLog.m12040b(f4425a, this.f4438n + " expected, but received " + cmVar.m11579e());
                return;
            }
            af f = cmVar.m11580f();
            switch (cmVar.m11579e()) {
                case CATEGORY_ID:
                    this.f4429e = ((ag) f).m11716a();
                    break;
                case SERVICE_ID:
                    this.f4430f = ((ag) f).m11716a();
                    break;
                case NATION_CODE:
                    this.f4431g = ((ag) f).m11716a();
                    break;
                case LANGUAGE:
                    this.f4432h = ((ag) f).m11716a();
                    break;
                case SERIAL_NUMBER:
                    this.f4433i = ((ag) f).m11716a();
                    break;
                case BATTERY_POWER_THRESHOLD:
                    this.f4434j = ((ae) f).m11711a();
                    break;
                default:
                    throw new IllegalStateException("Invalid inquired type " + cmVar.m11579e() + " was expected");
            }
            if (this.f4437m != null) {
                this.f4437m.countDown();
            }
        }
    }

SMALI指令码对应如下(com.sony.songpal.mdr.application.b.a

.line 156
    :pswitch_1
    check-cast v0, Lcom/sony/songpal/tandemfamily/message/mdr/param/ag;

    invoke-virtual {v0}, Lcom/sony/songpal/tandemfamily/message/mdr/param/ag;->a()Ljava/lang/String;

    move-result-object v0

    iput-object v0, p0, Lcom/sony/songpal/mdr/application/b/a;->f:Ljava/lang/String;

    goto :goto_1

把这玩意的SERVICE_ID那改成外国行货的ID就好了。比如

                case SERVICE_ID:
                    this.f4430f = "MDRID123456";
                    break;

但问题来了,不知道外国行货的ID是多少,于是@Lucifer提出了可能ID是连着的,于是我试了试MDRID289200,确认有这个型号。于是修改Apktool解包的SMALI为

.line 156
    :pswitch_1
    #check-cast v0, Lcom/sony/songpal/tandemfamily/message/mdr/param/ag;

    #invoke-virtual {v0}, Lcom/sony/songpal/tandemfamily/message/mdr/param/ag;->a()Ljava/lang/String;

    #move-result-object v0

    const-string v0, "MDRID289200"

    iput-object v0, p0, Lcom/sony/songpal/mdr/application/b/a;->f:Ljava/lang/String;

    goto :goto_1

重新用Apktool打包,然后用自己的证书签名。传到手机那,成功检测到更新。然后发给勇士@Lucifer来试了一下(我有点怂不敢试,毕竟如果变砖了我寄回国内可是相当麻烦)。实测貌似没啥毛病,更新成了国外版本的2.0.1固件并且语音变成了英文。于是自己也试了一下,更新后貌似确实没啥毛病。

装回原版程序后再次用抓包抓了一下,发现请求的service id已经变成了MDRID289200。大概不用担心以后又变回国行固件的问题。

简要教程

  1. 用Apktool解包:apktool d a.apk(我为了方便文件名改成了a.apk),这一步会创建一个名为a的文件夹
  2. 进入文件夹,全局搜索invoke-virtual {v0}, Lcom/sony/songpal/tandemfamily/message/mdr/param/ag;->a()Ljava/lang/String;,打开包含这一行的文件。
  3. 跳至.line 156,把里面的内容修改成我上面所述的内容
  4. 重新打包:apktool b a -o b.apk,这会生成b.apk
  5. 给b.apk签名,这个网上都有教程我就不写了
  6. 把原本的App卸掉,安装这个APK,然后连接耳机,如果没毛病的话应该会见到底部的更新提示,按部就班更新就行
  7. 更新完后卸掉这个魔改的App,安装回原版的App,enjoy

我打包的程序

我知道肯定有人会懒得自己动手,于是就把自己打包的给发上来了。警告:仅适用于WH-1000XM2。
最终更新 :这个打包了的apk已经不再适用,请勿尝试。

百度网盘:https://pan.baidu.com/s/1KrbW6yb0fJho4u7VjtGr0A,密码:5qgc。

    • 我觉得没戏,毕竟你没法选择你要刷哪个版本,只能在有更新时使用更新功能刷新固件。
      当然,如果你能下载到旧版固件,或许进一步魔改这个App能实现回滚,但这就在我知(乱)识(蒙)范围外了,或许你可以去贴吧之类的地方求助大神。

      • 你好,1000xm3 国行版已经推出4.1.3固件更新,由于之前在贴吧下了升级国际版包,导致现在不能升级国行版,目前还没有看到有刷回国行版魔改版APK,想自己动手做一个,但是完全是行外人,想问下大佬,是否可以考虑将id固定输入为国行id升级1000xm3?为了弄清楚怎么改,下载了大佬你的包,昨天弄了一天,解包之后,用的vs2017文件夹全局搜索搜索不到大佬上面提供的代码,请指教。

  1. dalao您认为国行xm2会像国行xm3一样更新 来在Headphones Connect内原生支持提示语言切换吗 主要不想刷 但是也实在受不了大妈音

    • 可能吧,那自然是最好的解决方案了。
      实际上我认为语音语言切换是个蛮鸡肋的功能…需求量不大的话,可能不会增加这个功能(假如硬件比如FLASH空间一开始就没有这么设计的话)

    • 我只是个萌新我懒得搞了,况且手上也没有WI-1000X。贴吧上面有现成的旧版1000X的魔改Headphones Connect,刷成外国固件之后再装回原版的4.0 apk再刷一遍就行,因为刷成外国固件后系统的识别号应该会变成外国行货,再更新的时候就会自动下外国的最新版。

  2. 老哥,现在1000xm2国行推送了4.1.3的固件,怎么刷回国行4.1.3固件呀,我下载了官方4.1.0的Headphones Connect,改编号为MDRID289202,还是检测不到升级,不知道是不是我改的有问题,老哥有时间可以看下嘛

    • 这就很有意思了。我访问了一下https://info.update.sony.net/HP001/MDRID289202/info/info.xml还是404。国行推送如果也是通过这个Headphones Connect推送的话应该会有更新信息才对。
      我猜测是新版Headphones Connect针对国行设备有一套不同的更新逻辑。这个有待研究。
      因为我自己并没有这种需求也没空去弄,就交给别的大佬们了。

  3. 我刷了,为啥使用Google Assistant声音听不清,呜哇呜哇的,就是没有一个单词是完整发音的。听歌又是正常的。这是为啥

    • 按我帖子这思路来搞就行
      但根据贴吧大神的研究,如果没有对应版本的升级逻辑的话我这种改法是不可用的。或许你可以参考一下那些强刷的方案(参见贴吧)

发表评论