Windows 10 免费升级结束了,其实伴随而来的,还有一个周年更新。公司早早就给我们推送了,然后发现,之前自己修改 ChsPinyinUDP.lex 文件添加的一些颜文字就酱紫丢!失!了! ̄へ ̄!!

怎么办呢?需要剧透的小伙伴请翻到最后,不需要剧透的小伙伴看完也别叫我傻逼。。

之前版本的 ChsPinyinUDP.lex 是一个纯文本,打开编辑编辑就完事了。这一次,俨然是一个二进制文件,自然无从下手。虽然说,这个输入法很可能还是楼里某个同事写的,但是还是算了,本着自己动手丰衣足食的态度,我决定逆向它的文件结构。

二进制文件,自然要有一个 Hex 的工具,想当年用的是 WinHex,当年年幼无知用盗版,现在不能这么干了,查了一下,发现依然不给免费用,遂继续查到一备胎 HxD,嗯,用着还不错呢。

首先大概看了一下,随便翻翻还是能看到一些零碎的表情信息的。因为是二进制文件嘛,所以,我脑子里优先考虑这些零碎的表情是不是有分隔符,很幸运,还是看出了点端倪:

0x0513

发现有不少 05 13 的数据在拼音之前。(其实准确说,如果你认真观察,应该是用 00 08 00 08 比较好的,不过嘛,它这个在拼音前,然而这个并无所谓。)

顺着这个分隔符往前查,想知道它的起始。

offset-1140

然后发现,在这个地方,就找不到前面的 05 13 了。精彩的地方来了,往上面以滚动,发现数据貌似很有规律,有很多列都是 00 00 的,有规律就是好事!首先看这个规律的数据的偏移范围,从 0x00000020 ~ 0x00001140,挺有代表性的是,都是 XX XX 00 00 这样子分段的,4个字节,很容易联想到 int32,再观察取值的规律,数值是从低地址到高地址是增长分布的!第一个还是0!不好意思,我立刻猜这个很可能就是后面数据段的偏移量。

好,酱紫就可以开始先段简单的代码验证一下了。大致代码就是,将偏移量数据段依次读出,两个相邻的作为一个区间,读取自 0x1140 后面的数据。然后用 UTF-16 打印出来。于是很开心地就看到了规律的字符和文字了。为什么是 UTF-16 呢?首先,观察到字符 a 对应的 61 后面跟着 00 ,aa 的就是 61 00 61 00,所以肯定不会是 UTF-8 了;然后细心一想,操作系统这种东西,多半是 C++ 写的吧,想他们也不喜欢变长字符集,所以大胆猜 UTF-16 就好了。

敲完代码,简单验证一下,发现偏移量正好覆盖了后面所有的数据,所以这个大体结构就明确了。

接下来分析每个子区间数据的结构。

08-00-08-00-0E-00-05-13-61-00-61-00-00-00-77-00-28-00-9F-FF-14-04-9F-FF-29-00-77-00-00-00

aa => w(゚Д゚)w

看上面这一段,首先,已知的是,敲 aa 会得到 w(゚Д゚)w 所以很容易划分出红色的部分,字符后面的 00 00 自然就是 C++ 字符结束的标志 \0 了。观察其他数据, 08 00 08 00 这个所有数据都有的,于是忽略。在观察使用情况,事实上并不是所有地方都有 05 13 的,测试一下,可以发现 05 实际上是这个组合自定义字符出现的位置。13 大家都一样,具体意义未知。最后未知的还有第5和第6字节。

好了,有了这些数据,可以尝试反推这个文件 0x00000000 ~ 0x00000020 的意义了。首先,敏感地统计一下有多少个自定义短语,转换成 16 进制(0x00000441),观察这头 32 字节,迅速发现了 0x18 位置的数值(提一下存储的时候,整型的低字节在低地址);再看看周围的几个4字节数,依次猜出 0x10 是数据段开始偏移量,0x14 是整个文件的大小。

正当我开心的觉得,水落石出的时候,准备动手拍一个UI来修改这个文件的时候,我转念一想,既然升级,这回 Windows 会不会提供一个 UI 设置这些东西呢?

想!不!到!真!有!(╯‵□′)╯︵┻━┻

Settings -> Time & language -> Region & language -> Languages (左边) -> 中文(中华人民共和国)-> Options -> Keywords -> Microsoft Pinyin -> Options -> Personalization -> User defined phrases -> Add。

windows-10-user-defined-phrases

好吧,我瞎折腾了。(#-_-)\┯━┯。