Skip to content

Instantly share code, notes, and snippets.

@iljavs
Last active June 20, 2025 18:48
Show Gist options
  • Save iljavs/eec3f5083239833f8e3d73475f847eb2 to your computer and use it in GitHub Desktop.
Save iljavs/eec3f5083239833f8e3d73475f847eb2 to your computer and use it in GitHub Desktop.
a simple wrapper for WinAFL. I absolutely despise how it takes arguments (afl-fuzz <afl> -- <DBI args> -- <program args>. Is just annoying. 1. it's inconsistent with AFL/AFL++ arguments 2. fucking cmd.exe is a horrible console/terminal and having to fidget around with the DBI arguments on the cmd.exe console is a giant pain in the ass. Instead I…
package main
import (
"fmt"
"log"
"os"
"os/exec"
"strings"
"github.com/saferwall/pe"
"gopkg.in/yaml.v3"
)
type WinaflConfig struct {
DynamoArgs []any `yaml:"dynamo_args"` // Accept arbitrary values
}
func flattenArgs(items []any) []string {
var out []string
for _, item := range items {
switch v := item.(type) {
case string:
out = append(out, v)
case map[string]any:
for key, val := range v {
out = append(out, key)
switch sub := val.(type) {
case []any:
for _, s := range sub {
out = append(out, fmt.Sprint(s))
}
case any:
out = append(out, fmt.Sprint(sub))
}
}
default:
log.Fatalf("Unsupported YAML dynamo_args entry: %v", v)
}
}
return out
}
func coverage_fixup(mod string) string {
pefile, err := pe.New(mod, nil)
if err != nil || pefile == nil {
return mod
}
pefile.Parse()
exp := pefile.Export
return exp.Name
}
func fixups(args []string) []string {
for idx, arg := range args {
if arg == "-coverage_module" {
args[idx+1] = coverage_fixup(args[idx+1])
return args
}
}
return args
}
func main() {
args := os.Args[1:]
var aflArgs []string
var dynArgs []string
var targetArgs []string
var yamlFile string
foundDoubleDash := false
for i := 0; i < len(args); i++ {
if args[i] == "-winafl" && i+1 < len(args) {
yamlFile = args[i+1]
i++
} else if args[i] == "--" {
foundDoubleDash = true
targetArgs = args[i+1:]
break
} else {
aflArgs = append(aflArgs, args[i])
}
}
if yamlFile == "" {
log.Fatal("Missing required -winafl <yamlfile> option")
}
if !foundDoubleDash {
log.Fatal("Missing '--' to separate target program arguments")
}
yamlData, err := os.ReadFile(yamlFile)
if err != nil {
log.Fatalf("Error reading YAML file: %v", err)
}
var config WinaflConfig
if err := yaml.Unmarshal(yamlData, &config); err != nil {
log.Fatalf("Error parsing YAML file: %v", err)
}
dynArgs = flattenArgs(config.DynamoArgs)
dynArgs = fixups(dynArgs)
finalArgs := append(aflArgs, "--")
finalArgs = append(finalArgs, dynArgs...)
finalArgs = append(finalArgs, "--")
finalArgs = append(finalArgs, targetArgs...)
fmt.Println("Translated command:")
fmt.Println("afl-fuzz " + strings.Join(finalArgs, " "))
cwd, err := os.Getwd()
if err != nil {
log.Fatalf("Error getting current working directory: %v", err)
}
aflcmd := cwd + "\\afl-fuzz.exe"
cmd := exec.Command(aflcmd, finalArgs...)
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
log.Fatalf("Failed to run afl-fuzz: %v", err)
}
}
@iljavs
Copy link
Author

iljavs commented Jun 20, 2025

the yaml file would look something like this:

dynamo_args:
  - -target_module:
      - foo.exe
  - -nargs:
      - 2
  - -coverage_module:
      - bar.dll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment