Hello Derek, and thank you for your message. I must admit that I am new to these concepts and just wanted to explore the fascinating world of fuzzing. However, I have been spending a lot of time without successfully getting something to work properly. I'll describe to you what I've tried and I'd be grateful for your help.
1) I was guided by the following tutorial:
[Fuzzing With WinAFL] How to fuzz a simple C program with WinAFL. This tutorial was valuable in the sense that it explained many concepts. However, it was less helpful because the author's video keeps freezing, making it difficult to follow along. Moreover, the source code presented there and in the corresponding GitHub repository (
GitHub link) does not clone correctly, and there's no direct Windows code like the one presented in the video. Another source of confusion is that the program presented in the video targets a 32-bit system.
As a result, I had to rewrite it for my 64-bit system. The code defines a simplified image:
```
struct Image {
char header[4] = “IMG”;
int width;
int height;
char data[10];
};
```Along with the functions
`__declspec(noinline) int ProcessImage(TCHAR* filename)` and
`int _tmain(int argc, TCHAR* argv[])`, it provides a simple program where
`main` calls the
`ProcessImage` function, and this
`ProcessImage` function reads the file. This is aimed to be a target function for fuzzing. I wrote another function to create such a file format and it works correctly. Additionally, there are many vulnerabilities in the code to make it fun for the fuzzer.
I compiled the program in Visual Studio and it works well as a standalone. The project is called “Damn”, as an abbreviation of the original GitHub name, so that's why this word appears later in the text.
The tutorial provided two ways of invoking the program: one with the
`drrun.exe` application, the other one with the
`afl-fuzz.exe` application.
2) Based on the video, I used the following options for the
`drrun.exe` call:
```
drrun.exe -c winafl.dll -debug -target_module Damn.exe -target_offset 0x14f00 -fuzz_iterations 10 -nargs 2 -- Damn.exe 1.img
```In the log, I see that all the modules were loaded and the output matches exactly what was mentioned in the GitHub post from my initial message:
```
"WARNING: Target function was never called. Incorrect target_offset?
Coverage map follows:"
```That's it. There's nothing else in the log.
3) Also based on the video, I used the following options to try the
`afl-fuzz.exe` way:
```
afl-fuzz.exe -i inImage -o outImage -t 5000+ -D …<DynamoRIO folder>\bin64 -- -coverage_module Damn.exe -target_module Damn.exe -target_offset 0x14f00 -fuzz_iterations 5000 -call_convention thiscall -nargs 2 -covtype edge -- Damn.exe @@
```This generates the following output:
```
WinAFL 1.16b by ...
Based on AFL 2.43b by ...
…
[*] Creating hard links for all input files...
[*] Attempting dry run with 'id_000000'...
[!] WARNING: Test case results in a timeout (skipping)
[-] PROGRAM ABORT : All test cases time out, giving up!
Location : perform_dry_run(), …\winafl\afl-fuzz.c:3330
0 processes nudged
nudge operation failed, verify permissions and parameters.
```What's interesting here is that this message appears immediately, so it doesn't matter how large you set the timeout value. At this point, I don't fully understand what "nudging" means or what permissions or parameters I need to verify.
Following your message, I made the following steps:
4) I verified the offsets again. In WinDbg, I see that the offset
0x14f00 should be correct. In Ghidra, I see two offsets:
0x14f00 (imported function) and
0x11591 (thunk function). I tried both, but neither works. I thought that the function at
0x11591 might somehow be a starter for the function at
0x14f00, but I don't know why these two separate functions exist. According to your advice, I also debugged the program in WinDbg and Visual Studio, setting a breakpoint at the
`ProcessImage` function. Both debuggers reach this code point, and every time I see the same value of
0x14f00 for the offset.
5) I built DynamoRIO in Debug mode. The page you referenced mentions a "loglevel" option if DynamoRIO is compiled in Debug mode. I tried it out, but the flag was ignored and I got the
"UNRECOGNIZED OPTION: loglevel" output in my terminal. I looked into the
`winafl.c` code and I see the following struct there:
```c
typedef struct _winafl_option_t {
/* Use nudge to notify the process for termination so that
* event_exit will be called.
*/
bool nudge_kills;
bool debug_mode;
int persistence_mode;
int coverage_kind;
char logdir[MAXIMUM_PATH];
target_module_t *target_modules;
char fuzz_module[MAXIMUM_PATH];
char fuzz_method[MAXIMUM_PATH];
char pipe_name[MAXIMUM_PATH];
char shm_name[MAXIMUM_PATH];
unsigned long fuzz_offset;
int fuzz_iterations;
void **func_args;
int num_fuz_args;
drwrap_callconv_t callconv;
bool thread_coverage;
bool no_loop;
bool dr_persist_cache;
} winafl_option_t;
```If I'm not mistaken, there's no
loglevel parameter there. So, I was unable to generate a more descriptive log.
6) I had to recompile DynamoRIO with the
BUILD_TOOLS flag to get
`drcov`. It created a large log file for me, which I couldn't read, because I needed the
`drcov2lcov` tool. I used the tool, but without the
`-src_filter` flag it generates an error later:
```
genhtml: ERROR: cannot read …/shared/winerror.h
```
With the
`-src_filter` flag and pointing to the directory with the Damn project files, both
`drcov2lcov` and
`genhtml` work smoothly, but the resulting HTML file doesn't provide much information. It shows me that the coverage was 55.2% and that the code visited
`ProcessImage`, but I don't see any functions in the file. So I'm not sure how I should use it and how this can help.
In summary, I just wanted to try WinAFL and understand how it works. Up to now, I don't understand the errors that occur. In the
`drrun.exe` case, it tells me the offset is wrong, but I can verify the offset and see that the function was visited. In the
`afl-fuzz.exe` case, it tells me that the timeout was reached, but the message appears immediately, so there was no chance for the timeout to be reached.
I would appreciate any help that could assist me in understanding the nature of these errors and getting started with the library. Please note, as mentioned, I have no experience with WinAFL or DynamoRIO and wanted to try it out. So I am merely hoping that all the command-line arguments I passed to the
`afl-fuzz.exe` and
`drrun.exe` applications are correct.
Thank you.