找寻微信撤回的图片(再续)

找寻微信撤回的图片(再续)

WechatImageDecoder支持PNG、GIF了。

引子

根据@icaca的反馈,WID无法解密PNG、GIF图片,现已支持。

上两篇文章有提到,解密的关键在于寻找magic码。通过magic码与加密的图片异或,即可实现解密。

magic码并不固定,微信的朋友说了算。不过不要紧,只要做一个简单的假设,即可获得magic码。

原始思路

假设:所有的图片都是JPEG格式。

则:magic码 异或 文件头的第一个字节 = JPEG文件头的第一个字节(0xFF)。

这个思路正是WID的核心解密逻辑,可以解密绝大部分图片。问题也很显然,无法解密其他格式的图片。

支持PNG等格式

加密后的图片命名为*.dat,我们无法得知这是哪一种格式。最简单粗暴的思路是——猜。

怎么猜?

常见的图片格式都试一下,然后看是否能够打开?

这里取图片的头两个字节,使用首字节计算magic码,然后基于得到的magic解密第二个字节看能否命中JPEG、PNG、GIF等图片文件头的第二个字节。

如果命中,则猜测成功。

def do_magic(header_code, buf):
    return header_code ^ list(buf)[0] if buf else 0x00

def decode(magic, buf):
    return bytearray([b ^ magic for b in list(buf)])

def guess_encoding(buf):
    headers = {
        'jpg': (0xff, 0xd8),
        'png': (0x89, 0x50),
        'gif': (0x47, 0x49),
    }
    for encoding in headers:
        header_code, check_code = headers[encoding] 
        magic = do_magic(header_code, buf)
        _, code = decode(magic, buf[:2])
        if check_code == code:
            return (encoding, magic)
    print('Decode failed')
    sys.exit(1)

参考