导致微信崩溃二维码
2023-4-24 20:46:57 Author: 网络安全透视镜(查看原文) 阅读量:35 收藏

今天一大早打开微信,点进群里,微信一直闪退。

闪退四五次后终于好了,一群屌毛一直转发一个二维码,一旦打开后,微信立马闪退。

测了一会发现,并不是所有的都会闪退,苹果的好像不会。有些一打开看到图片就会闪退,有些是扫码才会闪退。

先放出二维码

这个需要扫码才会崩溃

此bug是利用了微信扫码识别功能的缺陷

微信的扫码代码是开源的,就在 https://github.com/opencv/opencv_contrib/blob/4.x/modules/wechat_qrcode/ ,直接看就好了。

wechat_qrcode/src/zxing/qrcode/decoder/decoded_bit_stream_parser.cpp:198 行,有

// try to repair count data if count data is invalidif (count * 8 > available) {    count = (available + 7 / 8);}ArrayRef<char> bytes_(count);char* readBytes = &(*bytes_)[0];  // CRASH HEREfor (int i = 0; i < count; i++) {    //    readBytes[i] = (char) bits.readBits(8);    int readBits = available < 8 ? available : 8;    readBytes[i] = (char)bits.readBits(readBits, err_handler);}

count 为 0,这个时候还在分配 readBytes 读了它第 1 个元素,所以崩溃了。简单修复方法就是 count <= 0 那么 return 掉。

为什么会这样呢?二维码中数据分为不同区段(segment),其中有一个比较灵活的字节段(byte segment)。在二维码原始信息中字节段这样储存:

Version 1-9:

ModeChar CountData
0100 (Byte)00000001 (8 bits in Byte or Kanji Mode)(…)

所以当我们构建一个这样的二维码:

(正常段)+(字节模式指示位 4 + 长度位 00000001(8位)) ,并让这段数据刚好占用完二维码的所有数据容量,这样扫码的程序看到字符数量应该有1,会来读这个段,但之后又没有数据,从而造成了上面的错误。

为什么要用二维码的字节段呢?因为字节段的长度位正好是8位,其实日语段用的也是8位,同样可以。数字模式是10位、字符数字段是9位,触发不了这个 bug (但没看有没有其他的 bug)。


文章来源: http://mp.weixin.qq.com/s?__biz=MzIxMTg1ODAwNw==&mid=2247494666&idx=1&sn=5a3505dd77f6e02d887562b1ff66d82d&chksm=974c4b32a03bc2243b0a48b8fef0bae8a68036f78c1d0c1c93f5f5ae98ece2c2a646cfbde942#rd
如有侵权请联系:admin#unsafe.sh