PowerToys/doc/Fuzzing/CppFuzzingGuide.md
leileizhang 4be6129835
[Fuzzing] Add PowerRename Fuzzing and C++ Project Setup Guidance (#38922)
* add fuzz

* update solution

* update pipeline

* update solution

* remove arm64

* use reference

* revert the code

* add fuzzing readme

* update solution

* fix spell-check

* Parent reference don't need update

* remove fuzzing config

* add debug config

* update the config
2025-04-23 17:05:29 +08:00

2.9 KiB

🧪 C++ Project Fuzzing Test Guide

This guide walks you through setting up a fuzzing test project for a C++ module using libFuzzer. .


🏗️ Step-by-Step Setup

1. Create a New C++ Project

  • Use Empty Project template.
  • Name it <ModuleName>.FuzzingTest.

2. Update Build Configuration

  • In Configuration Manager, Uncheck Build for both Release|ARM64, Debug|ARM64 and Debug|x64 configurations.
  • Note: ARM64 is not supported in this case, so leave ARM64 configurations build disabled.

3. Enable ASan and libFuzzer in .vcxproj

Edit the project file to enable fuzzing:

<PropertyGroup>
  <EnableASAN>true</EnableASAN>
  <EnableFuzzer>true</EnableFuzzer>
</PropertyGroup>

4. Add Fuzzing Compiler Flags

Add this to AdditionalOptions under the Fuzzing configuration:

/fsanitize=address
/fsanitize-coverage=inline-8bit-counters
/fsanitize-coverage=edge
/fsanitize-coverage=trace-cmp
/fsanitize-coverage=trace-div
%(AdditionalOptions)

In Linker → Input → Additional Dependencies, add:

$(VCToolsInstallDir)lib\$(Platform)\libsancov.lib

6. Copy Required Runtime DLL

Add a PostBuildEvent to copy the ASAN DLL:

<Command>
  xcopy /y "$(VCToolsInstallDir)bin\Hostx64\x64\clang_rt.asan_dynamic-x86_64.dll" "$(OutDir)"
</Command>

7. Add Preprocessor Definitions

To avoid annotation issues, add these to the Preprocessor Definitions:

_DISABLE_VECTOR_ANNOTATION;_DISABLE_STRING_ANNOTATION

🧬 Required Code

LLVMFuzzerTestOneInput Entry Point

Every fuzzing project must expose this function:

extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
{
    std::string input(reinterpret_cast<const char*>(data), size);

    try
    {
        // Call your module with the input here.
    }
    catch (...) {}

    return 0;
}

⚙️ Test run in the cloud

To submit a job to the cloud you can run with this command:

oip submit --config .\OneFuzzConfig.json --drop-path <your_submission_directory> --platform windows --do-not-file-bugs --duration 1

You want to run with --do-not-file-bugs because if there is an issue with running the parser in the cloud (which is very possible), you don't want bugs to be created if there is an issue. The --duration task is the number of hours you want the task to run. I recommend just running for 1 hour to make sure things work initially. If you don't specify this parameter, it will default to 48 hours. You can find more about submitting a test job here.

OneFuzz will send you an email when the job has started.