二 Syzkaller学习笔记---更新syz-manager(12)


alls()
功能:为生成 syz- 准备相关的数据,因此起名神似 生成()的数据 。具体来说,就是遍历 ,将对应的添加到 data.Calls 。
func generateExecutorSyscalls(target *targets.Target, syscalls []*prog.Syscall, rev string) ArchData {data := ArchData{ // [1] 创建 ArchData结构体,该结构体最后会返回给 main()Revision:rev,GOARCH:target.Arch,PageSize:target.PageSize,NumPages:target.NumPages,DataOffset: target.DataOffset,}if target.ExecutorUsesForkServer { // 若目标 OS & arch 对应的target结构体,设置了对 ForkServer 和 Shmem(共享内存)的支持, 则设置data中相应字段, 这样 syz-executor便能使用这两种技术加速fuzzdata.ForkServer = 1}if target.ExecutorUsesShmem {data.Shmem = 1}defines := make(map[string]string)for _, c := range syscalls { // [2] 遍历各个 Syscall 类型的结构体var attrVals []uint64attrs := reflect.ValueOf(c.Attrs) // 将变量 c 中结构体 SyscallAttrs 里的各个字段取出,并将其依次存放至整型数组 attrVals (bool值和整型值)last := -1for i := 0; i < attrs.NumField(); i++ {attr := attrs.Field(i)val := uint64(0)switch attr.Type().Kind() {case reflect.Bool:if attr.Bool() {val = 1}case reflect.Uint64:val = attr.Uint()default:panic("unsupported syscall attribute type")}attrVals = append(attrVals, val)if val != 0 {last = i}} // 再使用生成的 attrVals 数组进一步生成 SyscallData 结构体data.Calls = append(data.Calls, newSyscallData(target, c, attrVals[:last+1]))// Some syscalls might not be present on the compiling machine, so we// generate definitions for them.if target.SyscallNumbers && !strings.HasPrefix(c.CallName, "syz_") &&target.NeedSyscallDefine(c.NR) {defines[target.SyscallPrefix+c.CallName] = fmt.Sprintf("%d", c.NR)}}sort.Slice(data.Calls, func(i, j int) bool { // [3] 将生成的 data.Calls 数组进行排序,并返回 data 变量return data.Calls[i].Name < data.Calls[j].Name})// Get a sorted list of definitions.defineNames := []string{}for key := range defines {defineNames = append(defineNames, key)}sort.Strings(defineNames)for _, key := range defineNames {data.Defines = append(data.Defines, Define{key, defines[key]})}return data}
? .(c.Attrs) 在运行中获取c.Attrs 的值的意思嘛 反射
说明:
s
功能:生成 syz- 所使用的 C 代码头文件写入 /defs.h ,将系统调用名和对应的系统调用号写入 \.h 文件 。
func writeExecutorSyscalls(data *ExecutorData) {osutil.MkdirAll(filepath.Join(*outDir, "executor"))sort.Slice(data.OSes, func(i, j int) bool {return data.OSes[i].GOOS < data.OSes[j].GOOS})buf := new(bytes.Buffer) // [1] 生成 defs.h 文件if err := defsTempl.Execute(buf, data); err != nil {tool.Failf("failed to execute defs template: %v", err)}writeFile(filepath.Join(*outDir, "executor", "defs.h"), buf.Bytes())buf.Reset() // [2] 生成 syscalls.h 文件if err := syscallsTempl.Execute(buf, data); err != nil {tool.Failf("failed to execute syscalls template: %v", err)}writeFile(filepath.Join(*outDir, "executor", "syscalls.h"), buf.Bytes())}
代码中提到和 模板如下
模板
说明:syz- 会将把先前 alls 函数中所生成的结构体数据,导出至 /defs.h 文件中,供后续编译 syz- 所使用 。syz- 将所有OS所有架构所对应的数据全部导出至一个文件中,并使用宏定义来选择启用哪一部分的数据 。
模板如下:混杂着 C 宏定义与模板描述 。
var defsTempl = template.Must(template.New("").Parse(`// AUTOGENERATED FILEstruct call_attrs_t { {{range $attr := $.CallAttrs}}uint64_t {{$attr}};{{end}}};struct call_props_t { {{range $attr := $.CallProps}}{{$attr.Type}} {{$attr.Name}};{{end}}};#define read_call_props_t(var, reader) { \{{range $attr := $.CallProps}}(var).{{$attr.Name}} = ({{$attr.Type}})(reader); \{{end}}}{{range $os := $.OSes}}#if GOOS_{{$os.GOOS}}#define GOOS "{{$os.GOOS}}"{{range $arch := $os.Archs}}#if GOARCH_{{$arch.GOARCH}}#define GOARCH "{{.GOARCH}}"#define SYZ_REVISION "{{.Revision}}"#define SYZ_EXECUTOR_USES_FORK_SERVER {{.ForkServer}}#define SYZ_EXECUTOR_USES_SHMEM {{.Shmem}}#define SYZ_PAGE_SIZE {{.PageSize}}#define SYZ_NUM_PAGES {{.NumPages}}#define SYZ_DATA_OFFSET {{.DataOffset}}{{range $c := $arch.Defines}}#ifndef {{$c.Name}}#define {{$c.Name}} {{$c.Value}}#endif{{end}}#endif{{end}}#endif{{end}}`))