github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-trace2syz/trace2syz.go (about) 1 // Copyright 2018 syzkaller project authors. All rights reserved. 2 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 3 4 //go:build !codeanalysis 5 6 // syz-trace2syz converts strace traces to syzkaller programs. 7 // 8 // Simple usage: 9 // 10 // strace -o trace -a 1 -s 65500 -v -xx -f -Xraw ./a.out 11 // syz-trace2syz -file trace 12 // 13 // Intended for seed selection or debugging 14 package main 15 16 import ( 17 "flag" 18 "os" 19 "path/filepath" 20 "strconv" 21 22 "github.com/google/syzkaller/pkg/db" 23 "github.com/google/syzkaller/pkg/log" 24 "github.com/google/syzkaller/pkg/osutil" 25 "github.com/google/syzkaller/prog" 26 _ "github.com/google/syzkaller/sys" 27 "github.com/google/syzkaller/sys/targets" 28 "github.com/google/syzkaller/tools/syz-trace2syz/proggen" 29 ) 30 31 var ( 32 flagFile = flag.String("file", "", "file to parse") 33 flagDir = flag.String("dir", "", "directory to parse") 34 flagDeserialize = flag.String("deserialize", "", "(Optional) directory to store deserialized programs") 35 ) 36 37 const ( 38 goos = targets.Linux // Target OS 39 arch = targets.AMD64 // Target architecture 40 ) 41 42 func main() { 43 flag.Parse() 44 target := initializeTarget(goos, arch) 45 progs := parseTraces(target) 46 log.Logf(0, "successfully converted traces; generating corpus.db") 47 pack(progs) 48 } 49 50 func initializeTarget(os, arch string) *prog.Target { 51 target, err := prog.GetTarget(os, arch) 52 if err != nil { 53 log.Fatalf("failed to load target: %s", err) 54 } 55 target.ConstMap = make(map[string]uint64) 56 for _, c := range target.Consts { 57 target.ConstMap[c.Name] = c.Value 58 } 59 return target 60 } 61 62 func parseTraces(target *prog.Target) []*prog.Prog { 63 var ret []*prog.Prog 64 var names []string 65 66 if *flagFile != "" { 67 names = append(names, *flagFile) 68 } else if *flagDir != "" { 69 names = getTraceFiles(*flagDir) 70 } else { 71 log.Fatalf("-file or -dir must be specified") 72 } 73 74 deserializeDir := *flagDeserialize 75 76 totalFiles := len(names) 77 log.Logf(0, "parsing %v traces", totalFiles) 78 for i, file := range names { 79 log.Logf(1, "parsing file %v/%v: %v", i+1, totalFiles, filepath.Base(names[i])) 80 progs, err := proggen.ParseFile(file, target) 81 if err != nil { 82 log.Fatalf("%v", err) 83 } 84 ret = append(ret, progs...) 85 if deserializeDir != "" { 86 for i, p := range progs { 87 progName := filepath.Join(deserializeDir, filepath.Base(file)+strconv.Itoa(i)) 88 if err := osutil.WriteFile(progName, p.Serialize()); err != nil { 89 log.Fatalf("failed to output file: %v", err) 90 } 91 } 92 } 93 } 94 return ret 95 } 96 97 func getTraceFiles(dir string) []string { 98 infos, err := os.ReadDir(dir) 99 if err != nil { 100 log.Fatalf("%s", err) 101 102 } 103 var names []string 104 for _, info := range infos { 105 name := filepath.Join(dir, info.Name()) 106 names = append(names, name) 107 } 108 return names 109 } 110 111 func pack(progs []*prog.Prog) { 112 var records []db.Record 113 for _, prog := range progs { 114 records = append(records, db.Record{Val: prog.Serialize()}) 115 } 116 if err := db.Create("corpus.db", 0, records); err != nil { 117 log.Fatalf("%v", err) 118 } 119 log.Logf(0, "finished!") 120 }