Linux内核:系统调用
系统调用时现代操作系统中内核提供的用户进程与内核进行交互的一组接口。这些接口具有完成诸如访问硬件设备、进程间通信、申请操作系统资源等能力。实际上提供这些接口主要是为了保证系统稳定可靠,避免应用程序恣意妄行
与内核通信系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层的主要作用有:
第一,为用户空间提供了一种硬件的抽象接口。例如,当需要读写文件时,应用程序可以不去管磁盘类型和介质,不去管文件系统类型
第二,系统调用保证了系统的稳定和安全。作为硬件设备和应用程序之间的中间人,内核可以基于权限、用户类型和其他一些规则对需要进行的访问进行裁决
第三,每个进程都运行在虚拟系统中,而在用户空间和系统的其余部分提供这样一层公共接口,也是出于这种考虑
在Linux中,系统调用是用户空间访问内核的唯一手段;除异常和陷入外,它们是内核唯一的合法入口
系统调用要访问系统调用,通常通过C库中定义的函数调用来进行,它们通常都需要零个、一个或几个参数
系统调用最终具有一种明确的操作,例如getpid()系统调用,根据定义它会返回当前进程的pid,内核中它的实现非常简单:
1234SYSCALL_DEF ...
libprotobuf-mutator_fuzzing_learning
前言这是一个libprotobuf-mutator的练习项目
环境搭建参考
所有环境与代码已上传至GitHub
搭建安装Clang/LLVM & libfuzzer1sudo apt-get install clang-11 libfuzzer-11-dev
安装libprotobuf-mutator安装说明
安装相关依赖:
123sudo apt-get updatesudo apt-get install protobuf-compiler libprotobuf-dev binutils cmake \ ninja-build liblzma-dev libz-dev pkg-config autoconf libtool
然后编译测试,先把libprotobuf-mutator这个项目给git下来W
123456789101112cd libprotobuf-mutatormkdir buildcd build#编译动态库cmake .. -GNinja -DCMAKE_C_COMPILER=clang-11 \-DCMAKE_CXX_COMPILER=cla ...
基于EMUX(原ARMX)的固件仿真,来自Cyberweek 会议
前言这是一项来自Cyberweek会议的介绍,EMUX
该项目是一个固件仿真项目,原来叫ARMX,由于加入了mips仿真改为EMUX
原文视频及pdf地址
EMUX项目地址
项目原理及框架介绍固件的仿真一直以来都是IoT的一个问题,仿真可以让研究者更方便地进行实验,同时降低实验成本
但是,在仿真的过程中(例如qemu-system),不可避免地会遇到各种问题,这个相信很多人都遇到过
emux的模拟思路就是尽可能地提高还原度,从bootloader,到kernel,再到用户态,做到完全一样
emux已经完成了诸如Tenda AC15,Archer C9等设备的模拟,除此之外还有部分已经成功但未发布在公开版本中的设备
emux的整体框架emux,docker与qemuEMUX 是驻留在 /emux 目录中的脚本、内核和文件系统的集合。 它使用 qemu-system-arm、qemu-system-mips 和 qemu-system-mipsel 来启动虚拟 ARM 和 MIPS Linux 环境
运行 qemu-system-arm|mips|mipsel 的主机系统被分配了 IP 地 ...
CodeQL基础语法示例
前言由于CodeQL的特殊语法,其查询语句多数通过各种api调用来实现,因此,常常出现一个问题,想写代码不知该如何下手,看别人代码看不懂,直接看源码也不适合新手
同时CodeQL的官方文档其实也并非足够友好
在这里可以找到c/c++的api
CodeQL api for c/c++
官方文档提供了查询功能,但是解释得有些潦草
因此就需要借助各种示例来堆经验,才能独立写出合适的查询语句
本章借助一些基本示例来学习:
some examples
如果你也对这些示例感兴趣,可以本地编译一个玩玩,不过建议还是可以到lgtm上面玩,数据库多,用起来也方便
lgtm
addressof.ql1234567891011/* * @description Finds address-of expressions (`&`) that take the address of a reference variable */import cppfrom AddressOfExpr addr, VariableAccess access //取地址符 变量where access = addr.g ...
CodeQL for c/c++(十一):散列约束和值编号
前言在 C 和 C++ 数据库中,抽象语法树中的每个节点都由一个单独的对象表示。这允许分析和结果显示都引用一段语法的特定外观。但是,确定两个表达式在句法上或语义上是否等效通常很有用
hash consing库(在 semmle.code.cpp.valuenumbering.HashCons中定义)提供了一种机制来识别具有相同句法结构的表达式。global value numbering library(在semmle.code.cpp.valuenumbering.GlobalValueNumbering 中定义)提供了一种机制来识别在运行时计算相同值的表达式。两个库都将每个函数中的表达式划分为由对象表示的等价类。每个 HashCons对象表示一组具有相同解析树的表达式,而 GVN 对象表示将始终计算相同值的一组表达式。有关更多信息,请参阅维基百科上的哈希约束和值编号
示例 C 代码在下面的 C 程序中, x + y 和 x + z 将被分配相同的值编号但不同的哈希值
123456int x = 1;int y = 2;int z = y;if(x + y == x + z) ...
CodeQL for c/c++(十):使用范围分析
前言范围分析库(在semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis中定义)提供了一组谓词,用于确定表达式的恒定上限和下限,以及识别整数溢出。对于性能,库执行自动加宽,因此可能无法提供最严格的边界
边界谓词upperBound和lowerBound谓词提供表达式的常量边界。参数的转换不包含在边界中。在您的查询需要考虑转换的常见情况下,在转换后的表单上调用它们,例如 upperBound(expr.getFullyConverted())
溢出谓词exprMightOverflow和相关谓词保持相关表达式是否可能溢出,这由范围分析库确定。谓词的convertedExprMightOverflow系列将考虑转换
示例这个查询使用upperBound来判断snprintf的结果在循环中使用时是否检查
12345678910111213141516from FunctionCall call, DataFlow::Node source, DataFlow::Node sink, Expr convSinkwhere // the call i ...
CodeQL for c/c++(九):使用守卫库
前言守卫库(在 semmle.code.cpp.controlflow.Guards 中定义)提供了一个 GuardCondition 类,表示用于做出控制流决策的布尔值。 如果 GuardCondition 仅在以某种方式评估 GuardCondition 时才能到达该块,则该 GuardCondition 被视为保护基本块。 例如,在下面的代码中,x < 10 是一个 GuardCondition,它保护 return 语句之前的所有代码
12345678if(x < 10) { f(x);} else if (x < 20) { g(x);} else { h(x);}return 0;
控制谓词控制谓词有助于确定哪些块仅在 GuardCondition 以某种方式评估时才运行。guard.controls(block, testIsTrue)保存是否只有在此条件的值为 testIsTrue 时才进入块
在以下代码示例中,对 isValid的调用控制对 performAction和 logFai ...
CodeQL for c/c++(八):检测潜在的缓冲区溢出
前言您可以使用 CodeQL 通过检查 C 和 C++ 中等于 strlen 的分配来检测潜在的缓冲区溢出。 本主题介绍如何开发用于检测潜在缓冲区溢出的 C/C++ 查询
问题——检测内存分配忽略空终止字符的空间此查询的目标是检测分配与空终止字符串长度相等的内存量的 C/C++ 代码,而不添加 +1 来为空终止字符腾出空间。例如,下面的代码演示了这个错误,并导致缓冲区溢出:
12345678void processString(const char *input){ char *buffer = malloc(strlen(input)); strcpy(buffer, input); ...}
基本查询语句在编写查询之前,您需要决定要搜索哪些实体,然后定义如何识别它们
定义感兴趣的实体您可以通过搜索与第 3 行中对 malloc 的调用或第 5 行中对 strcpy 的调用类似的代码来解决此问题(参见上面的示例)。对于我们的基本查询,我们从一个简单的假设开始:任何仅使用 strlen 定义内存大小的 malloc 调用都可能在填充内存时导致错误 ...
CodeQL for c/c++(七):优化查询以解决边缘情况
前言本主题介绍如何开发 C++ 查询。 该示例介绍了递归谓词并演示了用于优化查询的典型工作流程。 有关可用于学习编写 C/C++ 代码查询的主题的完整概述,请参阅“C 和 C++ 的 CodeQL”
编写一个查询来检查构造函数是否初始化了所有私有字段似乎是一个简单的问题,但有几个边缘情况需要考虑
基本查询语句我们可以从查看类中的每个私有字段并检查该类中的每个构造函数是否初始化它们开始。一旦您熟悉了 C++ 库,这并不难做到
123456import cppfrom Constructor c, Field fwhere f.getDeclaringType() = c.getDeclaringType() and f.isPrivate() and not exists(Assignment a | a = f.getAnAssignment() and a.getEnclosingFunction() = c)select c, "Constructor does not initialize fields $@.", f, f.getName()
f.g ...
CodeQL for c/c++(六):分析数据流
前言数据流分析计算变量可以在程序中的各个点保持的可能值,确定这些值如何在程序中传播,以及它们的使用位置。 在 CodeQL 中,您可以对本地数据流和全局数据流进行建模。 有关建模数据流的更一般介绍,请参阅“关于数据流分析”
本地数据流本地数据流是单个函数内的数据流。本地数据流通常比全局数据流更容易、更快、更精确,并且足以满足许多查询
使用本地数据流本地数据流库位于DataFlow模块中,它定义了 Node 类,表示数据可以流经的任何元素。节点分为表达式节点(ExprNode)和参数节点(ParameterNode)。可以使用成员谓词 asExpr 和 asParameter 在数据流节点和表达式/参数之间进行映射:
123456789class Node { /** Gets the expression corresponding to this node, if any. */ Expr asExpr() { ... } /** Gets the parameter corresponding to this node, if any. */ ...