zlib解压报invalid distance too far back的原因及修复方向咨询
解决方向指引
1. 验证压缩流的完整性与格式合法性
- 确认捕获的9字节是否为完整的压缩流:TCP传输存在粘包/拆包可能,你捕获的片段可能只是完整流的一部分。
infgen提示"incomplete deflate stream"也印证了这一点——标准deflate动态霍夫曼块(你的流首字节0xCA标记为BTYPE=2的动态块)需要更多字节存储霍夫曼编码表和完整数据。 - 排查自定义封装:第三方可能在标准deflate/zlib流前后添加了自定义头部/尾部(比如流末尾的
0x00可能是自定义结束标记,而非deflate流的一部分)。尝试去掉末尾的0x00,用前8字节重新测试解压。 - 核对zlib头合法性:你当前用
inflateInit2(&strm, -15)启用raw deflate模式是正确的——流首字节0xCA+0x05计算得0xCA05 %31=9≠0,不满足标准zlib头的校验规则,说明这不是带zlib头的流。
2. 逆向第三方压缩逻辑(核心方向)
依托你已有的逆向工程基础,直接定位第三方生成压缩流的代码:
- 查看zlib调用参数:是否修改了窗口大小(
windowBits)、压缩级别等非标准参数?比如若第三方使用了大于32KB的窗口(标准zlib最大窗口为32KB),标准inflate会因距离超出窗口范围报错"invalid distance too far back"。 - 检查zlib源码篡改:第三方可能修改了zlib的压缩逻辑,比如允许生成超出当前输出缓冲区长度的回溯距离(这违反deflate标准),或修改了霍夫曼编码规则。对比第三方使用的zlib版本与官方1.2.13的差异,重点关注
deflate.c中距离校验、编码生成的逻辑。
3. 分析修改后zlib的输出差异
修改zlib后输出的0x6D 0x00*5 0x01 0x4E 0x00*5与目标未压缩数据的差异点具有指向性:
- 目标数据中
0x4D 0x7D 0x9B 0x7C 0x07(第2-6字节)和0x7D 0x9B 0x7C 0x07(第9-12字节)是重复片段,标准deflate会用长度+距离的引用编码生成。修改zlib后这些片段被替换为0x00,说明压缩流中对应的距离字段超出了当前输出缓冲区的长度(此时输出还未生成足够字节供回溯)。 - 推测第三方的压缩逻辑允许生成这种"无效"距离,你需要修改zlib的
inflate逻辑:当遇到超出当前输出长度的距离时,不是填充0x00,而是按照第三方的规则处理(比如从输出缓冲区起始位置循环回溯,或允许距离大于total_out)。
4. 手动解析压缩流字节
将压缩流拆分为二进制格式,逐段分析deflate块结构:
压缩流字节:0xCA 0x05 0xDB 0xC8 0xE8 0x07 0x22 0x01 0x00 二进制拆分: 0xCA → 11001010 → BFINAL=1(最后一个块),BTYPE=10(动态霍夫曼块) 后续字节依次对应动态块的HLIT/HDIST/HCLEN字段、霍夫曼编码表、数据段
手动解析可明确流中是否存在非标准编码,或缺失的关键部分,辅助逆向第三方的压缩规则。
内容的提问来源于stack exchange,提问作者szulak
相关产品推荐
相关产品推荐

