You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为含嵌套Google Protobuf参数的函数做C++模糊测试的疑问与优化

LLVM Fuzzer测试Protobuf参数函数的常见疑问解答

首先是你用到的测试代码:

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    MyProtoBufferType proto;
    if (!proto.ParseFromArray(data, size)) {
        // Handle parse error if necessary
        return 0;
    }

    // Call your function with the populated protobuf object
    myFunction(proto);

    return 0;
}

疑问与解答

1. proto.ParseFromArray(data, size)为何能成功?解析正确性在此场景下重要吗?

首先要明确:ParseFromArray返回成功,不等于解析出的是完全符合你定义的合法Protobuf结构。Protobuf的解析机制是容错式的——它会跳过无法识别的字段、忽略局部格式错误的片段,只要数据的基础编码(比如字段标签、wire type)有部分能被识别,就会返回true。也就是说,随机数据里总有一小部分刚好踩中Protobuf的编码规则,让解析函数认为“可以提取出有效字段”。

其次,解析正确性在这个模糊测试场景里确实不是核心目标:我们的目的是排查myFunction的崩溃问题,而非验证Protobuf解析逻辑。哪怕解析出的是字段不全、甚至不符合业务逻辑的Protobuf对象,只要能进入myFunction的执行路径,就有可能触发内存越界、空指针引用这类崩溃点。当然,如果大部分随机数据都通不过解析,会严重降低测试效率——毕竟大部分输入都被直接过滤,没法覆盖更多代码路径。

2. 针对该场景,有哪些更推荐的实现方案?

有几种方案能大幅提升模糊测试的效率和覆盖率:

  • 用Protobuf专用变异器:比如LLVM Fuzzer配套的libprotobuf-mutator,它能基于你的Protobuf定义直接生成合法且带结构变异的输入,而非完全随机的字节流。生成的输入几乎都能通过解析,能高效覆盖myFunction的各种代码路径。示例代码大致如下:
    extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
        MyProtoBufferType proto;
        if (!protobuf_mutator::ParseFromArray(proto, data, size)) {
            return 0;
        }
        myFunction(proto);
        return 0;
    }
    
    编译时需要链接libprotobuf-mutator库,并确保Protobuf定义被正确处理。
  • 自定义输入处理逻辑:如果不想用第三方库,遇到解析失败时不要直接返回,可以尝试对输入做简单变异(比如调整字段标签、修改wire type)后再重试;或者直接把部分解析后的不完整对象传入myFunction——这类不完整对象反而更容易触发边界条件。
  • 直接构造内存对象:跳过字节流解析步骤,直接在内存中构造MyProtoBufferType对象,随机设置各个字段(包括嵌套字段)的值,再传入myFunction。这种方式能直接控制输入结构,精准测试复杂嵌套结构的各种边界场景。

内容的提问来源于stack exchange,提问作者kaixin liu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 13:06:05