使用Go构建一款静态分析工具Owl详解

 更新时间:2022年06月10日 14:56:45   作者:LeonDing  
Owl是一款开源项目依赖分析工具,可以快速在指定的项目目录下查找符合某些特征的源代码文件或者依赖文件,这篇文章主要介绍了使用Go构建一款静态分析工具,需要的朋友可以参考下

介 绍

Owl是一款开源项目依赖分析工具,可以快速在指定的项目目录下查找符合某些特征的源代码文件或者依赖文件。为何开发了这款工具?例如很多时候我们项目太大,项目文件夹下有很多依赖文件,如一个Java项目引入了log4j这个jar依赖,在项目中某文件存在循环依赖问题。当某个依赖包出现了漏洞时,本工具能快速扫描项目目录下存在的可疑依赖文件,并且给出依赖文件所在的地址,帮助开发者能快速进行定位到可疑文件。

原 理

目前版本的功能比较简单,工作原理很简单,工具会对特定目录进行扫描通过内置的特征码算法匹配到特定文件,然后收集与其特征码匹配的文件地址,然后展示出来,也可以重定向到一个固定json文件中保存。

Owl类似于杀毒软件一样,和杀毒软件的工作原理差不多,Owl会根据依赖文件的特征码来扫描整个项目,和杀毒病毒库工作原理类似。当然如果严格按照杀毒软件那种标准做的话,可能涉及一些汇编相关的,目前owl功能实现还没有那么复杂,后面会版本会加入codeql代码分析引擎,通过codeql的数据库来做静态分析功能增强。

快速开始

如何使用owl?你可以克隆仓库然后通过如下命令:

git clone git@github.com:auula/owl.git

在仓库内部有一个Makefile文件可以快速帮助你构建相应平台的二进制文件,例如:

$: make help
make darwin	| Compile executable binary for MacOS platform
make linux	| Compile executable binary for Linux platform
make windows	| Compile executable binary for Windows platform
make clean	| Clean up executable binary

Owl起因也是为CodeAnalysis所编写的特征检测工具,所以你也可以在:https://github.com/Tencent/CodeAnalysis 这个项目下面的tools目录找到已经编译好的二进制可执行文件,下载对应平台的二进制文件即可。

如何使用

程序构建完成会得到一个二进制文件,程序名称为owl,如下为owl执行效果,一些子命令参数都已经列出:

$: ./owl
			 _____  _    _  __
			(  _  )( \/\/ )(  )
			 )(_)(  )    (  )(__
			(_____)(__/\__)(____) 🦉 v0.1.2
 A dependency module feature scanning detection tool for static analysis.

Usage:
  owl [command]
Available Commands:
  completion  Generate the autocompletion script for the specified shell
  help        Help about any command
  hex         File hex encoding
  md5         Collection file md5
  run         Execute the scanner
  version     Version information
Flags:
  -h, --help   help for owl
Use "owl [command] --help" for more information about a command.

如果不知道子命令如何使用,可以在对应的子命令后面参入--help参数,即可得到帮助信息:

例如如果你要查找log4j,你首先要通过owl计算log4j特征码,命令如下:

$: ./owl md5 --path=/Users/ding/Downloads/log4j-1.2.17.jar

注意这里的特征码计算必须使用owl程序的算法,因为owl里面的算法针对大文件我是采用分数据块方案计算的,提升程序运行速度,所以如果使用其他软件的算法那么就会出现问题!

结果如下:

你也可以使用十六进制字符串特征去查找:

$: ./owl hex --path=/Users/ding/Downloads/log4j-1.2.17.jar

程序会将对应的文件转成十六进制字符串展示,如下图:

现在就可以使用扫描器进行扫描了,匹配模式可以指定为md5或者hex,未来可能会添加跟多的模式,命令如下:

$: ./owl run --dir=/Users/ding/Downloads/ --mode=md5 --code=04a41f0a068986f0f73485cf507c0f40

搜索得到具体依赖文件:

搜索结果如果过多,可以通过--out参数将结果重定向保存到文件中保存,文件格式为json

SDK方式

上面介绍完是command line方式进行的,owl程序本身就是一个command line,核心逻辑在 github.com/auula/owl/scan 这个包中编写的,如果想二次开发,那么就可以直接使用go get github.com/auula/owl 安装这个模块到你项目里面,然后直接通过硬编码的方式进行自定义编程;

一个简单实例,通过自定义代码方式进行依赖文件扫描和收集:

package main
import (
    "fmt"
    "github.com/auula/owl/scan"
)
func main() {
    // 创建扫描器
    scanner := new(scan.Scanner)
    // 设置扫描器路径     
    scanner.SetPath("github.com/auula/owl") 
    // 返回对应路径所有文件特征码
    res, _ := scanner.List() 
    fmt.Println(res)
    // 设置指定的匹配器,其他匹配器查看API文档
    scanner.SetMatcher(new(scan.Md5Matcher))
    // 搜索包含特征码文件,返回文件记录集合
    res, _ = scanner.Search("xxxx")
    // 打开一个文件描述符
    file, _ := os.OpenFile("res.json", os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0666)
    // 将结果保存到指定文件中
    scanner.Output(file, res)
}

以上就是通过SDK方式自定义编码完成依赖特征检测。

其他

有问题欢迎提issue,工具不错的话记得按一个,仓库github.com/auula/owl

到此这篇关于使用Go构建一款静态分析工具的文章就介绍到这了,更多相关Go静态分析工具内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • golang recover函数使用中的一些坑解析

    golang recover函数使用中的一些坑解析

    这篇文章主要为大家介绍了golang recover函数使用中的一些坑解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • 提高golang源码阅读效率的六个高级技巧

    提高golang源码阅读效率的六个高级技巧

    随着业务的发展,自己对代码的审美的改变,我们不断的迭代这些代码,代码量可以说是与日俱增,代码的某些结构也会发生大大小的改变,这些都要求我们在阅读代码的时候,需要更快的效率和技巧
    2024-01-01
  • Go语言学习教程之反射的示例详解

    Go语言学习教程之反射的示例详解

    这篇文章主要通过记录对reflect包的简单使用,来对反射有一定的了解。文中的示例代码讲解详细,对我们学习Go语言有一定帮助,需要的可以参考一下
    2022-09-09
  • Go语言中错误处理实例分析

    Go语言中错误处理实例分析

    这篇文章主要介绍了Go语言中错误处理,实例分析了Go语言中针对错误处理的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go语言实现并发控制的常见方式详解

    Go语言实现并发控制的常见方式详解

    这篇文章主要为大家详细介绍了Go语言实现并发控制的几种常见方式,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下
    2024-03-03
  • golang 内存对齐的实现

    golang 内存对齐的实现

    在代码编译阶段,编译器会对数据的存储布局进行对齐优化,本文主要介绍了golang 内存对齐的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-08-08
  • Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例

    Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例

    这篇文章主要为大家介绍了Go中的格式化字符串fmt.Sprintf()和fmt.Printf()使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • Go指针数组和数组指针的具体使用

    Go指针数组和数组指针的具体使用

    go语言跟c语言一样,指针数组和数组指针概念容易搞混,本文主要介绍了Go指针数组和数组指针的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • Golang中unicode码和中文的互相转换函数使用

    Golang中unicode码和中文的互相转换函数使用

    这篇文章主要为大家介绍了Golang中unicode码和中文的互相转换函数使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Golang实现单元测试中的接口层

    Golang实现单元测试中的接口层

    接口层主要负责的就是请求的处理,最常见的就是 HTTP 请求的处理。这篇文章主要为大家介绍了Golang如何实现单元测试中的接口层,需要的可以参考一下
    2023-03-03

最新评论