69 个版本 (18 个重大变化)

新版本 0.216.0 2024 年 8 月 22 日
0.215.0 2024 年 7 月 31 日
0.214.0 2024 年 7 月 16 日
0.202.0 2024 年 3 月 26 日
0.2.1 2022 年 2 月 17 日

#620 in WebAssembly

Download history 5457/week @ 2024-05-02 4965/week @ 2024-05-09 10508/week @ 2024-05-16 7046/week @ 2024-05-23 9590/week @ 2024-05-30 8853/week @ 2024-06-06 12365/week @ 2024-06-13 11768/week @ 2024-06-20 11955/week @ 2024-06-27 8503/week @ 2024-07-04 10642/week @ 2024-07-11 12597/week @ 2024-07-18 13892/week @ 2024-07-25 13208/week @ 2024-08-01 15227/week @ 2024-08-08 13574/week @ 2024-08-15

每月下载量 58,173
用于 2 软件包

Apache-2.0…

2MB
45K SLoC

wasm-mutate

Bytecode Alliance 项目

wasm-mutate 是一个用于模糊测试 Wasm 编译器、运行时、验证器和其他 Wasm 消费程序的全新工具。

Crates.io version Download docs.rs docs

用法

wasm-mutate 添加到您的 Cargo.toml

$ cargo add wasm-mutate

您还可以使用 cli 工具突变 WebAssembly 二进制文件

wasm-tools mutate original.wasm --seed 0 -o out.wasm --preserve-semantics

功能

  • 语义等价转换: wasm-mutate 具有仅对输入 Wasm 模块应用语义保留更改的能力。当以这种方式使用时,突变后的 Wasm 在给定与原始 Wasm 模块相同的输入时计算相同的结果。

  • 确定性: wasm-mutate 是确定性的,即给定相同的输入 Wasm 模块和相同的种子,它总是产生相同的突变输出 Wasm 模块。

  • libfuzzer 集成: wasm-mutate 与基于突变的模糊器(如 libFuzzer)集成良好。它重用了模糊器的原始输入字符串。 wasm-mutateLLVMFuzzerCustomMutator 钩子和 libfuzzer_sys::fuzz_mutator! 宏一起工作。

    示例

    #![no_main]
    
    use libfuzzer_sys::{fuzz_mutator, fuzz_target};
    use std::io::{BufRead, Read, Write};
    use wasmparser::WasmFeatures;
    
    fuzz_target!(|bytes: &[u8]| {
        // Initialize the Wasm for example
    });
    
    fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
        // Generate a random Wasm module with `wasm-smith` as well as a RNG seed for
        let wasm = &data[..size];
        let features = WasmFeatures::default();
        let mut validator = wasmparser::Validator::new();
        validator.wasm_features(features);
        let validation_result = validator.validate_all(&wasm);
    
        // Mutate the data if its a valid Wasm file, otherwise, create a random one
        let wasm = if validation_result.is_ok() {
            wasm.to_vec()
        } else {
            let (w, _) = match wasm_tools_fuzz::generate_valid_module_from_seed(seed, |config, u| {
                config.exceptions_enabled = false;
                config.simd_enabled = false;
                config.reference_types_enabled = false;
                config.memory64_enabled = false;
                config.max_memories = 1;
                Ok(())
            }) {
                Ok(m) => m,
                Err(_) => {
                    return size;
                }
            };
            w
        };
    
        let mutated_wasm = wasm_mutate::WasmMutate::default()
            .seed(seed.into())
            .fuel(1000)
            .preserve_semantics(true)
            .run(&wasm);
    
        let mutated_wasm = match mutated_wasm {
            Ok(w) => w,
            Err(_) => wasm,
        };
    
        // The mutated Wasm should still be valid, since the input Wasm was valid.
        let newsize = mutated_wasm.len();
        data[..newsize].copy_from_slice(&mutated_wasm[..newsize]);
        newsize
    });
    
    
    
  • 测试用例减少(WIP): wasm-mutate 具有将突变限制为仅缩小 Wasm 模块大小的能力。如果以这种方式使用,wasm-mutate 实质上成为 Wasm 测试用例减少器。我们目前正在努力提供一个作为单独二进制文件的该功能原型。以下伪 Rust 提供了它作为标准爬山算法的一般概念。

      let wasmmutate = wasm_mutate::WasmMutate::default()
              .seed(seed)
              .fuel(1000)
              .preserve_semantics(true)
              .reduce(true);
    
      while MAX_ITERATIONS > 0 {
          let new_wasm = wasmmutate.run(&wasm);
          wasm = if check_equivalence(new_wasm, wasm) {
            wasm
          } else{
            panic!("No valid transformations")
          }
          MAX_ITERATIONS -= 1;
      }
    
      return wasm
    
    

许可证

本项目遵循Apache 2.0许可证,并包含LLVM例外条款。有关更多详细信息,请参阅许可证

贡献

除非您明确声明,否则根据Apache-2.0许可证定义,您提交的任何有意包含在本项目中的贡献,均应按上述方式授权,不附加任何额外条款或条件。

特别贡献

  • Javier Cabrera Arteaga(KTH的博士研究生)

依赖项

~1.8–2.8MB
~53K SLoC