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


%E4%BD%BF%E7%94%%E8%BF%9B%E8%A1%8C%E5%86%85%E6%A0%
ARM
安卓模拟
源码阅读笔记-1 前言
是开源的一款无监督覆盖率引导的,支持包括 Linux、 等操作系统的测试 。
有很多个部件 。其中:
功能总结:编译系统调用模板的原理,可以理解成实现了一种描述系统调用的小型的编程语言 。
syz-
用途:解析并获取文件中的常量所对应的具体整型,并将结果存放至 xxx.txt.const 文件中
syz- main 函数位于 sys/syz-/.go 中 。
开头导入了一些包,我们 暂且不看import ("bytes""flag""fmt""io/ioutil""os""path/filepath""runtime""sort""strings""github.com/google/syzkaller/pkg/ast""github.com/google/syzkaller/pkg/compiler""github.com/google/syzkaller/pkg/osutil""github.com/google/syzkaller/pkg/tool""github.com/google/syzkaller/sys/targets")
main
在main函数中
func main() {flag.Parse()if *flagBuild && *flagBuildDir != "" {tool.Failf("-build and -builddir is an invalid combination")}
syz- 会尝试解析传入的参数,也就是flag
直接定义了我们的参数 和他的提示信息以及默认值
var (flagOS= flag.String("os", runtime.GOOS, "target OS")flagBuild= flag.Bool("build", false, "regenerate arch-specific kernel headers")flagSourceDir = flag.String("sourcedir", "", "path to kernel source checkout dir")flagIncludes= flag.String("includedirs", "", "path to other kernel source include dirs separated by commas")flagBuildDir= flag.String("builddir", "", "path to kernel build dir")flagArch= flag.String("arch", "", "comma-separated list of arches to generate (all by default)"))
? 接下来,便是尝试获取 OS 所对应的结构体;如果 OS 不存在则肯定取不到,直接报错:
OS := *flagOSextractor := extractors[OS]if extractor == nil {tool.Failf("unknown os: %v", OS)}
?数组如下所示,该数组为不同的 OS 实例化了不同的类 。其中 linux OS 所对应的实例(即那三个函数的实现)位于 sys/syz-/linux.go 中:
type Extractor interface {prepare(sourcedir string, build bool, arches []*Arch) errorprepareArch(arch *Arch) errorprocessFile(arch *Arch, info *compiler.ConstInfo) (map[string]uint64, map[string]bool, error)}var extractors = map[string]Extractor{targets.Akaros:new(akaros),targets.Linux:new(linux),targets.FreeBSD: new(freebsd),targets.Darwin:new(darwin),targets.NetBSD:new(netbsd),targets.OpenBSD: new(openbsd),"android":new(linux),targets.Fuchsia: new(fuchsia),targets.Windows: new(windows),targets.Trusty:new(trusty),}
? 回到 main 函数,syz- 要用已有的 OS 字符串、 字符串数组,以及文件名数组来生成出对应的结构体数组:
? 在旧的版本中,会有单另的用来生成arch字符串,file等
? 现在 合并在中,函数之类的 。
用已有的 OS 字符串、 字符串数组(调用()获得),以及文件名数组来生成出对应的结构体数组 。
arches, nfiles, err := createArches(OS, archList(OS, *flagArch), flag.Args())if err != nil {tool.Fail(err)}if *flagSourceDir == "" {tool.Fail(fmt.Errorf("provide path to kernel checkout via -sourcedir " +"flag (or make extract SOURCEDIR)"))}
准备工作已经做的差不多了,接下来让执行初始化操作:
if err := extractor.prepare(*flagSourceDir, *flagBuild, arches); err != nil {tool.Fail(err)}
这一步实际上会调用到 sys/syz-/linux.go 中的函数:
func (*linux) prepare(sourcedir string, build bool, arches []*Arch) error {if build {// Run 'make mrproper', otherwise out-of-tree build fails.// However, it takes unreasonable amount of time,// so first check few files and if they are missing hope for best.for _, a := range arches {arch := a.target.KernelArchif osutil.IsExist(filepath.Join(sourcedir, ".config")) ||osutil.IsExist(filepath.Join(sourcedir, "init/main.o")) ||osutil.IsExist(filepath.Join(sourcedir, "include/config")) ||osutil.IsExist(filepath.Join(sourcedir, "include/generated/compile.h")) ||osutil.IsExist(filepath.Join(sourcedir, "arch", arch, "include", "generated")) {fmt.Printf("make mrproper ARCH=%v\n", arch)out, err := osutil.RunCmd(time.Hour, sourcedir, "make", "mrproper", "ARCH="+arch,"-j", fmt.Sprint(runtime.NumCPU()))if err != nil {return fmt.Errorf("make mrproper failed: %v\n%s", err, out)}}}} else {if len(arches) > 1 {return fmt.Errorf("more than 1 arch is invalid without -build")}}return nil}