0 Abstract
深度学习技术可以自动从软件源代码中提取功能,从而广泛用于检测软件漏洞。大多数现有的深度学习方法都依赖整个功能或序列级程序切片来识别漏洞。但是,这些方法通常很难捕获全面的脆弱性语义,从而导致高误报率和假阴性率。在本文中,我们提出了GraphFVD,这是一种基于图形的新型属性细粒漏洞检测方法。
我们的方法从代码属性图中提取基于图形的属性切片,并引入了一个分层注意图卷积网络以学习图形嵌入。 GraphFVD提供了一个细粒的代码表示,该表示,捕获语法,控制流,数据流以及与漏洞相关的源代码的自然顺序顺序。我们评估了方法对两个现实世界漏洞数据集的有效性。实验结果表明,我们的方法在两个数据集上都优于现有的最新漏洞检测方法。
1 Intro
我们提出了一种新颖的细粒代码表示,从代码属性图中提取图形级程序切片(即基于属性图的漏洞候选或PRVC)。 PRVC结合了抽象语法,控制流,数据流和代码的顺序顺序,从而捕获了全面而精确的程序语义。
•我们设计一个分层注意力图卷积网络(HIERGCN),以学习PRVC的嵌入并预测漏洞。 HIERGCN在关系图卷积网络(RGCN)中引入了分层的关 ...
标题样式
title 1
title2
title3
title4
title5
文本
加粗:这是一段加粗文本
斜体:这是一段斜体文本
下划线:这是带下划线的文本
删除线:这是删除线文本
高亮:这是高亮文本
引用
这是一个引用块
警告框
[!NOTE]
note
[!TIP]
tip
[!IMPORTANT]
important
[!WARNING]
warning
[!CAUTION]
caution
代码块
缓冲区溢出是编程中的一种常见安全漏洞,它发生在当程序尝试向一个固定长度的缓冲区内写入过多数据时。这可能导致数据溢出到相邻的内存空间,可能会导致程序崩溃、数据损坏或安全漏洞,如执行任意代码。
下面是一个简单的C++缓冲区溢出示例代码,它演示了一个不安全的字符串拷贝操作:
12345678910111213#include <cstdio>void vulnerableFunction(char* src) { char buffer[10]; // 定义一个大小为10的字符数组 // 危险:没有检查src的长度,直接拷贝, ...
软件的加密与解密
软件的加密与解密技术是矛与盾的关系,它们是在互相斗争中发展进步的。
两者在技术上的较量归根到底是一种利益的冲突。软件开发者为了维护自身的商业利益,不断寻找各种有效的技术来保护软件的版权,推迟软件被解密的时间;而解密者则受盗版所带来的高额利润的驱使或纯粹出于个人兴趣,不断开发新的解密工具,针对新出现的保护方式进行跟踪分析,以找到相应的解密方法。
没有无法解密的保护。对软件的保护仅靠技术是不够的,最终要靠人们的知识产权意识和法制观念的进步及生活水平的提高。如果一种保护技术的强度能达到让解密者在软件的生命周期内都无法将其完全破解的程度,这种保护技术就是成功的。软件保护方式的设计应在一开始就作为软件开发的一部分来考虑,列入开发计划和开发成本,并在保护强度、成本、易用性之间进行折中考虑,选择一个平衡点。
作为一个合格的程序员,要上至需求分析、设计抽象、设计模式,下至系统核心,熟悉整个系统的底层结构。
软件逆向工程
逆向工程(Reverse Engineering)是指根据已有的产物和结果,通过分析来推导出具体的实现方法。
对软件来说,==“可执行程序->反编译-> ...
二进制分析
未读逆向工程开源引擎框架
Capstone, Keystone, Unicorn, Qemu 以及 QiLing 等工具
汇编与反汇编
Capstone
新加坡南洋理工大学团队在 Blackhat USA 2014 上发布的一个反汇编引擎
Capstone 反汇编引擎 官网The Ultimate Disassembly Framework – Capstone – The Ultimate Disassembler (capstone-engine.org)
项目主页:https://github.com/aquynh/capstone
多平台 Windows、*nix
多架构,例如 Arm、Mips 和 x86
支持 C/Python 接口
Keystone
新加坡南洋理工大学团队在 Blackhat USA 2016 上发布的一个汇编框架
Keystone 汇编框架 官网Keystone – The Ultimate Assembler (keystone-engine.org)
项目主页:https://github.com/keystone-engine/keyst ...
二进制分析
未读使用make更新函数库文件¶
函数库文件也就是对Object文件(程序编译的中间文件)的打包文件。在Unix下,一般是由命令 ar 来完成打包工作。
函数库文件的成员¶
一个函数库文件由多个文件组成。你可以用如下格式指定函数库文件及其组成:
1archive(member)
这个不是一个命令,而一个目标和依赖的定义。一般来说,这种用法基本上就是为了 ar 命令来服务的。如:
12foolib(hack.o) : hack.o ar cr foolib hack.o
如果要指定多个member,那就以空格分开,如:
1foolib(hack.o kludge.o)
其等价于:
1foolib(hack.o) foolib(kludge.o)
你还可以使用Shell的文件通配符来定义,如:
1foolib(*.o)
函数库成员的隐含规则¶
当make搜索一个目标的隐含规则时,一个特殊的特性是,如果这个目标是 a(m) 形式的,其会把目标变成 (m) 。于是,如果我们的成员是 %.o 的模式定义,并且如果我们使用 make foo.a(bar.o) 的形式调用Makefile时,隐含规 ...
二进制分析
未读隐含规则¶
在我们使用Makefile时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix下是 .o 文件,Windows下是 .obj 文件)。本章讲述的就是一些在Makefile中的“隐含的”,早先约定了的,不需要我们再写出来的规则。
“隐含规则”也就是一种惯例,make会按照这种“惯例”心照不喧地来运行,那怕我们的Makefile中没有书写这样的规则。例如,把 .c 文件编译成 .o 文件这一规则,你根本就不用写出来,make会自动推导出这种规则,并生成我们需要的 .o 文件。
“隐含规则”会使用一些我们系统变量,我们可以改变这些系统变量的值来定制隐含规则的运行时的参数。如系统变量 CFLAGS 可以控制编译时的编译器参数。
我们还可以通过“模式规则”的方式写下自己的隐含规则。用“后缀规则”来定义隐含规则会有许多的限制。使用“模式规则”会显得更智能和清楚,但“后缀规则”可以用来保证我们Makefile的兼容性。我们了解了“隐含规则”,可以让其为我们更好的服务,也会让我们知道一些“约定俗成”了的东西,而不至于使得我们在运行Ma ...
make 运行¶
一般来说,最简单的就是直接在命令行下输入make命令,make命令会找当前目录的makefile来执行,一切都是自动的。但也有时你也许只想让make重编译某些文件,而不是整个工程,而又有的时候你有几套编译规则,你想在不同的时候使用不同的编译规则,等等。本章节就是讲述如何使用make命令的。
make的退出码¶
make命令执行后有三个退出码:
0
表示成功执行。
1
如果make运行时出现任何错误,其返回1。
2
如果你使用了make的“-q”选项,并且make使得一些目标不需要更新,那么返回2。
Make的相关参数我们会在后续章节中讲述。
指定Makefile¶
前面我们说过,GNU make找寻默认的Makefile的规则是在当前目录下依次找三个文件——“GNUmakefile”、“makefile”和“Makefile”。其按顺序找这三个文件,一旦找到,就开始读取这个文件并执行。
当前,我们也可以给make命令指定一个特殊名字的Makefile。要达到这个功能,我们要使用make的 -f 或是 --file 参数( --makefile 参数也行 ...
二进制分析
未读使用函数¶
在Makefile中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能。make 所支持的函数也不算很多,不过已经足够我们的操作了。函数调用后,函数的返回值可以当做变量来使用。
函数的调用语法¶
函数调用,很像变量的使用,也是以 $ 来标识的,其语法如下:
1$(<function> <arguments>)
或是:
1${<function> <arguments>}
这里, <function> 就是函数名,make支持的函数不多。 <arguments> 为函数的参数,参数间以逗号 , 分隔,而函数名和参数之间以“空格”分隔。函数调用以 $ 开头,以圆括号或花括号把函数名和参数括起。感觉很像一个变量,是不是?函数中的参数可以使用变量,为了风格的统一,函数和变量的括号最好一样,如使用 $(subst a,b,$(x)) 这样的形式,而不是 $(subst a,b, ${x}) 的形式。因为统一会更清楚,也会减少一些不必要的麻烦。
还是来看一个 ...
二进制分析
未读使用条件判断¶
使用条件判断,可以让make根据运行时的不同情况选择不同的执行分支。条件表达式可以是比较变量的值,或是比较变量和常量的值。
示例¶
下面的例子,判断 $(CC) 变量是否 gcc ,如果是的话,则使用GNU函数编译目标。
123456789libs_for_gcc = -lgnunormal_libs =foo: $(objects)ifeq ($(CC),gcc) $(CC) -o foo $(objects) $(libs_for_gcc)else $(CC) -o foo $(objects) $(normal_libs)endif
可见,在上面示例的这个规则中,目标 foo 可以根据变量 $(CC) 值来选取不同的函数库来编译程序。
我们可以从上面的示例中看到三个关键字: ifeq 、 else 和 endif 。 ifeq 的意思表示条件语句的开始,并指定一个条件表达式,表达式包含两个参数,以逗号分隔,表达式以圆括号括起。 else 表示条件表达式为假的情况。 endif 表示一个条件语句的结束,任何一个条件表达式都应该以 endif 结束。
当我 ...
二进制分析
未读使用变量¶
在Makefile中的定义的变量,就像是C/C语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在“目标”,“依赖目标”, “命令”或是Makefile的其它部分中。
变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有 : 、 # 、 = 或是空字符(空格、回车等)。变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。传统的Makefile的变量名是全大写的命名方式,但我推荐使用大小写搭配的变量名,如:MakeFlags。这样可以避免和系统的变量冲突,而发生意外的事情。
有一些变量是很奇怪字串,如 < 、 @ 等,这些是自动化变量,我会在后面介绍。
变量的基础¶
变量在声明时需要给予初值,而在使用时,需要给在变量名前加上 $ 符号,但最好用小括号 () 或是大括号 {} 把变量给包括起来。如果你要使用真实的 $字符,那么你需要用 $ 来表示。
变量可以使用在许多 ...