nwaku/vendor/nim-testutils/testutils/fuzzing/fuzzing_on_windows.md

149 lines
4.3 KiB
Markdown
Raw Normal View History

# Fuzzing on Windows
This is a supplemental guide to fuzzing on windows platform.
## Windows Subsystem for Linux(WSL) Ubuntu 20.04
Grab Ubuntu from Windows Store and install libFuzzer and afl.
But don't forget to update or upgrade the database if you start with a 'blank' Ubuntu.
```sh
sudo apt update
sudo apt upgrade
```
### Install clang and libFuzzer
Pick your clang version: 9, 10, or 11. In this example I'll use clang-10.
```sh
sudo apt install build-essential
sudo apt-get install clang-10 lldb-10 lld-10
sudo apt-get install libfuzzer-10-dev
```
Now copy the symlink in `/usr/bin` or whatever location of clang-10.
```sh
$> which clang-10
/usr/bin/clang-10 # this is the result of 'which clang-10'
$> sudo cp -P /usr/bin/clang-10 /usr/bin/clang
```
### Install afl
```sh
git clone https://github.com/google/AFL
cd AFL
make
sudo make install
```
Now go back to [Fuzzing instructions for Linux](readme.md)
## Real Windows instructions
There are a lot of things you need to install on Windows.
### Compiling with libFuzzer
* Download and install Clang 11 for Windows [here](https://llvm.org/builds/)
* Download and install Visual Studio 2019 [here](https://visualstudio.microsoft.com/downloads/)
You don't need to install all of the Visual Studio components, you only need to
choose “Desktop development with C++”. That will be enough and only download less than 2GB instead of 4GB+.
Perhaps you wonder why need to install two compiler? The answer is: libFuzzer does not work with MingW-GCC.
If you already prepare your test case, the instruction to build the binary is exactly the same with Linux version.
```Nim
nim c -d:libFuzzer -d:release -d:chronicles_log_level=fatal --noMain --cc=clang --passC="-fsanitize=fuzzer" --passL="-fsanitize=fuzzer" testcase
```
Now go back to [Starting the Fuzzer using libFuzzer](readme.md#Starting-the-Fuzzer)
### Compiling with winafl
We will use the same Visual Studio compiler like libFuzzer.
* Download and install Visual Studio 2019 [here](https://visualstudio.microsoft.com/downloads/)
Now open one of this terminal from VS 2019:
* Developer PowerShell for VS 2019
* x64 Native Tools Command Prompt for VS 2019
* x86 Native Tools Command Prompt for VS 2019
### Download and build winafl
No need to install cmake, VS 2019 already included cmake in it's installation package.
```sh
git clone https://github.com/googleprojectzero/winafl
cd winafl
git submodule update --init --recursive
```
#### 32/64 bit build using VS 2017
```sh
mkdir build32
cd build32
cmake -G"Visual Studio 15 2017" .. -DINTELPT=1
cmake --build . --config Release
mkdir build64
cd build64
cmake -G"Visual Studio 15 2017 Win64" .. -DINTELPT=1
cmake --build . --config Release
```
#### 32/64 bit build using VS 2019
```
mkdir build32
cd build32
cmake -G"Visual Studio 16 2019" .. -DINTELPT=1 -Ax86
cmake --build . --config Release
mkdir build64
cd build64
cmake -G"Visual Studio 16 2019" .. -DINTELPT=1 -Ax64
cmake --build . --config Release
```
Either you use VS 2017 or VS 2019, you'll get the binary in:
`winafl/build64/bin/Release` or `winafl/build32/bin/Release`
If you only need to use it occasionally, you can use this command to add the winafl binary path to
you env `PATH` instead of polluting it system wide.
* PowerShell: ```$env:path = ($pwd).path + "\bin\Release;" + $env:path```
* CMD Command Prompt: ```set PATH=%CD%\bin\Release;%PATH%```
#### Compiling testcase
Compiling the testcase is simpler than Linux version, you don't need to use afl-gcc or afl-clang,
you can use clang, vcc, or mingw-gcc as you like.
```Nim
nim c -d:afl -d:noSignalHandler -d:release -d:chronicles_log_level=fatal testcase
```
#### Starting the Fuzzer
Now run the command from Command Prompt terminal, the `@@` will not work with PowerShell.
Winafl needs the input data to be read from a file, not from stdin, that's why the presence of `@@`.
```sh
afl-fuzz.exe -i inDir -o outDir -P -t 20000 -- -coverage_module testcase.exe -fuzz_iterations 20 -target_module testcase.exe -target_method AFLmain -nargs 2 -- testcase.exe @@
```
* `inDir` is a directory containing a small but valid input file that makes sense to the program.
* `outDir` will be the location of generated testcase corpus.
* replace both `testcase.exe` with your executable binary.
* `-P` is Intel PT selector
* `-t` timeout in msec