首页
社区
课程
招聘
[原创]syzkaller源码分析(一) syz-manager.go
发表于: 2021-6-20 17:19 10346

[原创]syzkaller源码分析(一) syz-manager.go

2021-6-20 17:19
10346

关于syzkaller的资料以安装居多,代码分析比较少,把自己的关于代码的理解稍微写一下,有理解错误的函数也请指正。下面内容主要就是syz-manager.go的主要流程,去掉了对核心流程不重要的部分以及具体实现,要是了解具体的实现还要去看源码。源码地址如下:779K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6Y4L8$3!0Y4L8r3g2Q4x3V1k6K6P5i4A6C8j5h3I4D9k6i4t1`.

md文件会附在最后

对syzkaller的简介可以去看 8f3K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5P5W2)9J5k6h3q4D9K9i4W2#2L8W2)9J5k6h3y4G2L8g2)9J5c8Y4c8Q4x3V1j5#2x3o6M7&6

syzkaller正常情况下都以syz-manager作为入口,syz-manager.go主要负责各种工作的启动(HTTP、RPC、dashboard等等)、调用fuzz以及repro的生成。

重点函数 minimizeCorpus()

重点函数repro.Run()

重点函数 ctx.repro

 
 
 
manager.go
 
func main() {
    RunManager(cfg)
}
 
func RunManager(cfg *mgrconfig.Config) {
    初始化: 文件 corpus.db &Manager HTTP RPC prometheus参数 dash
    go func() {
        log()
    }
 
    if *flagBench != ""  //bench: write execution statistics into this file periodically
        go func(){
            mgr.minimizeCorpus()
            写入文件
        }
 
    if mgr.dash != nil {
        go mgr.dashboardReporter()
    }
    mgr.vmLoop()
}
 
func (mgr *Manager) vmLoop() {
        启动instance
        初始化pendingRepro reproducing reproInstances
 
        //可以复现并且有剩余的instances
        for canRepro() && len(instances) >= instancesPerRepro {
            go func() {
                repro.Run()
            }
        }
 
        //没有可以复现的但是有剩余的instances
        for !canRepro() && len(instances) != 0 {
            go func(){
                //调用mgr.runInstanceInner;
                //mgr.runInstanceInner()调用了FuzzerCmd()启动fuzz; 有调用MonitorExecution()监控信息并返回Report对象
                //返回crash信息
                mgr.runInstance(idx)
            }
        }
        // 下面进行结果处理
        ...
    }
}
manager.go
 
func main() {
    RunManager(cfg)
}
 
func RunManager(cfg *mgrconfig.Config) {
    初始化: 文件 corpus.db &Manager HTTP RPC prometheus参数 dash
    go func() {
        log()
    }
 
    if *flagBench != ""  //bench: write execution statistics into this file periodically
        go func(){
            mgr.minimizeCorpus()
            写入文件
        }
 
    if mgr.dash != nil {
        go mgr.dashboardReporter()
    }
    mgr.vmLoop()
}
 
func (mgr *Manager) vmLoop() {
        启动instance
        初始化pendingRepro reproducing reproInstances
 
        //可以复现并且有剩余的instances
        for canRepro() && len(instances) >= instancesPerRepro {
            go func() {
                repro.Run()
            }
        }
 
        //没有可以复现的但是有剩余的instances
        for !canRepro() && len(instances) != 0 {
            go func(){
                //调用mgr.runInstanceInner;
                //mgr.runInstanceInner()调用了FuzzerCmd()启动fuzz; 有调用MonitorExecution()监控信息并返回Report对象
                //返回crash信息
                mgr.runInstance(idx)
            }
        }
        // 下面进行结果处理
        ...
    }
}
func (mgr *Manager) minimizeCorpus() {
    ...
 
    //返回的signal有elemType相同的,取其中prio最高的
    for _, ctx := range signal.Minimize(inputs) {
        ...
    }
    ...
 
    //为了防止出现corpus explosion,需要统计call的cov和count情况
    for call, info := range mgr.collectSyscallInfoUnlocked() {
        if 出现corpus explosion情况
            mgr.saturatedCalls[call] = true
    }
    写回db.filename
}
func (mgr *Manager) minimizeCorpus() {
    ...
 
    //返回的signal有elemType相同的,取其中prio最高的
    for _, ctx := range signal.Minimize(inputs) {
        ...
    }
    ...
 
    //为了防止出现corpus explosion,需要统计call的cov和count情况
    for call, info := range mgr.collectSyscallInfoUnlocked() {
        if 出现corpus explosion情况
            mgr.saturatedCalls[call] = true
    }
    写回db.filename

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回