-
Notifications
You must be signed in to change notification settings - Fork 0
/
gofuzzer.go
92 lines (83 loc) · 2.37 KB
/
gofuzzer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package gofuzzer
import (
"encoding/binary"
"fmt"
"github.com/ret2happy/gofuzzer/utils"
"io/ioutil"
"math/big"
"os"
"path/filepath"
"testing"
)
func UnmarshalCorpusFile(b []byte) ([]any, error) {
return utils.UnmarshalCorpusFile(b)
}
type FuzzCoreFunc func(corpus []any) (err error)
func DumpFuzzCoreCoverage(t *testing.T, corpusPath string, callback FuzzCoreFunc) {
files, err := ioutil.ReadDir(corpusPath)
if err != nil {
return
}
fmt.Printf("Collected %d corpus files.\n", len(files))
for idx, f := range files {
fmt.Printf("Processing %d/%d\r", idx, len(files))
filePath := filepath.Join(corpusPath, f.Name())
data, err := os.ReadFile(filePath)
if err != nil {
t.Fatal(err)
}
originData, err := UnmarshalCorpusFile(data)
if err != nil {
t.Fatal(err)
}
err = callback(originData)
if err != nil {
t.Fatal(err)
}
}
println("All corpus files processed.")
}
func ConsumeBool(cursor *int, fuzzData []byte) (bool, error) {
bakCursor := *cursor
*cursor += 1
if bakCursor >= len(fuzzData) {
return false, fmt.Errorf("exhausted all fuzz data")
}
return fuzzData[bakCursor]%2 == 0, nil
}
func ConsumeUint8Range(cursor *int, fuzzData []byte, maxNum uint8) (uint8, error) {
bakCursor := *cursor
*cursor += 1
if bakCursor >= len(fuzzData) {
*cursor = len(fuzzData)
return 0, fmt.Errorf("exhausted all fuzz data")
}
return fuzzData[bakCursor] % maxNum, nil
}
func ConsumeUint64(cursor *int, fuzzData []byte) (uint64, error) {
bakCursor := *cursor
byteLength := 8
if bakCursor >= len(fuzzData) || len(fuzzData)-bakCursor < byteLength {
*cursor = len(fuzzData)
return 0, fmt.Errorf("exhausted all fuzz data")
}
*cursor += byteLength
return binary.LittleEndian.Uint64(fuzzData[bakCursor : bakCursor+byteLength]), nil
}
func ConsumeInt64(cursor *int, fuzzData []byte) (int64, error) {
result, err := ConsumeUint64(cursor, fuzzData)
return int64(result), err
}
func ConsumeBigInt(cursor *int, fuzzData []byte, bitLength uint) (big.Int, error) {
bakCursor := *cursor
//byteLength := 32
targetByteLength := int(bitLength / 8)
var result big.Int
if bakCursor >= len(fuzzData) || bakCursor+targetByteLength > len(fuzzData) || targetByteLength > 32 {
*cursor = len(fuzzData)
return result, fmt.Errorf("exhausted all fuzz data")
}
*cursor += targetByteLength
result.SetBytes(fuzzData[bakCursor : bakCursor+targetByteLength])
return result, nil
}