cargo-fuzz icon indicating copy to clipboard operation
cargo-fuzz copied to clipboard

Add new build option to support Windows DLLs

Open cwshugg opened this issue 4 months ago • 2 comments

Hi - this PR implements a new build argument: --no-include-main-msvc - in order to help enable support for building and fuzzing Windows DLLs.

I recently ran into an issue when attempting to fuzz a Windows-only DLL (#386) where the /include:main linker argument that is added during FuzzProject::cargo() for MSVC-based builds gave the DLL a main symbol it could not resolve, which caused linking to fail:

LINK : error LNK2001: unresolved external symbol main
C:\....\depedency.dll : fatal error LNK1120: 1 unresolved externals

The DLL is, by nature, completely separate from the fuzzing targets in my cargo-fuzz repository, but I still wanted it to be a dependency listed in fuzz/Cargo.toml, so that it would be built and instrumented in the exact same way as the fuzzing target binaries. I found that by controlling whether or not /include:main is added to the cargo build arguments executed by cargo-fuzz, I was able to set up a "dummy" fuzzing target that provides its own main function:

# fuzz/Cargo.toml
# ...
[dependencies]
# the DLL is optional; only to be built with a specific feature
my_dll = { path = "..", optional = true }
# ...
[features]
build_dll = ["dep:my_dll"]
# ...
[[bin]]
name = "dummy_target_build_dll"
path = "fuzz_targets/dummy_target_build_dll.rs"
required-features = ["build_dll"]
test = false
doc = false
bench = false
# ... other binaries ...
// dummy_target_build_dll.rs
fn main()
{
    println!("DLL build complete! Now, copy the DLL to your desired location, `
              and use `cargo fuzz run` to run your other fuzzing targets.");
    // ... do other work, such as copying the DLL into the desired location ...
}

Then, by executing cargo fuzz run --no-include-main-msvc dummy_target, the DLL would be built successfully. I could then proceed to run all other fuzzing targets, which would load in the instrumented DLL and fuzz it.

TL;DR: This solution allows Windows DLLs to be instrumented & fuzzed, but only if manual control over /include:main is allowed (hence, --no-include-main-msvc). This resolves #386.

cwshugg avatar Oct 16 '24 17:10 cwshugg