系统调用

[轉]sendpage漏洞分析 CVE-2009-2692

我的未来我决定 提交于 2020-02-26 19:20:24
之前看了《 新爆内核高危漏洞sock_sendpage的利用分析的讨论 》这篇帖子,在九贱兄和诸位CUer的指引下,大致弄清了整个漏洞的始末。现与大家分享(引用自 我的空间 )。 有什么不足之处还望多多指教~ 内核的BUG 这个BUG首先得从sendfile系统调用说起。 考虑将一个本地文件通过socket发送出去的问题。我们通常的做法是:打开文件fd和一个socket,然后循环地从文件fd中read数据,并将读取 的数据send到socket中。这样,每次读写我们都需要两次系统调用,并且数据会被从内核拷贝到用户空间(read),再从用户空间拷贝到内核 (send)。 而sendfile就将整个发送过程封装在一个系统调用中,避免了多次系统调用,避免了数据在内核空间和用户空间之间的大量拷贝。 ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count); 虽然这个系统调用接收in和out两个fd,但是有所限制,in只能是普通文件,out只能是socket(这个限制不知道后来的内核版本有没有放宽)。 sendfile系统调用在内核里面是怎么实现的呢?这个还是比较复杂,它在内核里面做了原来要在用户态做的事情:创建一个pipe对象作buffer用、从in_fd中读数据到pipe中、将pipe中的数据写到out_fd

浅谈Java网络编程——非阻塞I/O

柔情痞子 提交于 2020-02-26 11:46:46
文件描述符(descriptors) Unix中I/O的基本组成元素是字节序列。大多数程序应用于字节流或I/O流。 进程通过描述符引用I/O流,也被称作文件描述符。管道、文件、POSIX IPC's(消息队列,信号量,共享内存),事件队列等都是通过文件描述符引用I/O流。 创建和释放描述符 描述符创建: 通过系统命令调用(open,pipe,socket等)创建; 继承自父进程。 描述符释放: 进程退出 系统调用 close 标记为 close on exec 的描述符在 exec 后释放 Close-on-exec 当进程 forks 时,所有描述符都会复制到子进程中。如果任意描述符被标记为 close on exec ,那么当子进程 execs 之前,父进程 forks 之后,这些描述符将关闭并且在子进程中不再可用。 使用描述符通过 read 、 write 命令调用的数据转换 File Entry 每个描述符都指向内核中的File entry的数据结构。file entry为每个描述符维度了一个file offset。系统调用命令 open 创建file entry. Fork/Dup and File Entries 由 fork 创建的描述符被父子进程共享,在file entry中引用同一个 offset 。 dup/dup2 的系统调用与此类似。 #include

UNIX环境高级编程--10. 信号

ぐ巨炮叔叔 提交于 2020-02-24 23:19:48
第十章 信号 信号是软中断,提供了一种处理异步事件的方法。例如,终端用户键入终端键,会通过信号机制停止一个进程, 或及早终止管道中的下一个程序。 每个信号都有一个名字,SIG开头。例如: SIGABRT:夭折信号,当进程调用abort函数时产生。 SIGALRM:闹钟信号,由alarm函数设定时器超时后将产生此信号。 当信号出现时,可以告诉内核按下列三种方式之一进行处理: (1)忽略此信号。butSIGKILL和SIGSTOP不能忽略。他们向内核和超级用户提供了使进程终止或停止的可靠方法。另外,硬件异常产生的信号也不能忽略。 (2)捕捉信号。 (3)执行系统默认动作。 函数signal: UNIX系统信号机制最简单的接口是signal函数。 void (*signal (int signo, void (*func)(int))) (int); 返回值:成功,返回以前的信号处理配置;出错,返回SIG_ERR。 signo信号名(SIGABRT等); func取值可以是: 常量SIG_IGN 表示忽略此信号 常量SIG_DFL 表示接到此信号后动作是系统默认动作 函数地址 信号发生时,调用该函数。 函数kill和raise: kill和raise函数用来发送信号。 kill函数将信号发送给进程或进程组。raise函数则允许进程向自身发送信号。 调用 raise(signo);

扒开系统调用的三层皮(下)

早过忘川 提交于 2020-02-24 07:03:44
扒开系统调用的三层皮(下) 20135109 高艺桐 《Linux内核分析》MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 一、给MenuOS增加time和time-asm命令 自己实验截图: (1)进入实验楼环境,使用rm menu -rf指令强制删除已有的内核,使用git clone https://github.com/mengning/menu.git重新克隆一个最新的内核。 (2)进入menu,找到test.c文件,将getpid和getpid-asm函数添加进去 (3)修改主函数 (4)使用make rootfs,自动编译、生成根文件系统,并自动启动menuOS (5)使用help查看指令,并查看getpid和getpid-asm的运行结果 给MenuOS增加time和tim-asm命令的步骤: 更新meun代码到最新版 在main函数中增加MenuConfig 增加对应的Time函数和TimeAsm函数 Make rootfs 二、使用gdb跟踪系统调用内核函数sys_time 自己实验截图: (1)将3.18内核带有的符号表加载进去: (2)设置断点,输入c继续执行到断点处: (3)在sys_time处设置一个断点(sys_time 为系统调用号13对应的内核处理函数),输入c继续执行: (4

Linux添加自定义系统调用

Deadly 提交于 2020-02-24 06:56:07
一、 什么是系统调用 在 Linux 的世界里,我们经常会遇到系统调用这一术语,所谓系统调用,就是内核提供的、功能十分强大的一系列的函数。这些系统调用是在内核中实现的,再通过一定的方式把系统调用给用户,一般都通过门 (gate) 陷入 (trap) 实现。系统调用就是用户空间应用程序和内核提供的服务之间的一个接口。由于服务是在内核中提供的,因此无法执行直接调用;相反,您必须使用一个进程来跨越用户空间与内核之间的界限。在特定架构中实现此功能的方法会有所不同。因此,本文将着眼于最通用的架构 —— i386 。 二、 系统调用的作用 系统调用在 Linux 系统中发挥着巨大的作用,如果没有系统调用,那么应用程序就失去了内核的支持。我们在编程时用到的很多函数,如 fork 、 open 等这些函数最终都是在系统调用里实现的,这里我们说到了两个函数,即 fork 和 exit, 这两函数都是 glibc 中的函数,但是如果我们跟踪函数的执行过程,看看 glibc 对 fork 和 exit 函数的实现就可以发现在 glibc 的实现代码里都是采用软中断的方式陷入到内核中再通过系统调用实现函数的功能的。具体过程我们在系统调用的实现过程会详细的讲到。 由此可见,系统调用是用户接口在内核中的实现,如果没有系统调用,用户就不能利用内核。 三、 系统调用的现实及调用过程 详细讲述系统调用的之前也讲一下

linux 内核与用户空间通信之netlink使用方法

﹥>﹥吖頭↗ 提交于 2020-02-22 18:37:06
摘自 https://www.cnblogs.com/x_wukong/p/5920437.html 转自:http://blog.csdn.net/haomcu/article/details/7371835 Linux中的进程间通信机制源自于Unix平台上的进程通信机制。Unix的两大分支AT&T Unix和BSD Unix在进程通信实现机制上的各有所不同,前者形成了运行在单个计算机上的System V IPC,后者则实现了基于socket的进程间通信机制。同时Linux也遵循IEEE制定的Posix IPC标准,在三者的基础之上实现了以下几种主要的IPC机制:管道(Pipe)及命名管道(Named Pipe),信号(Signal),消息队列(Message queue),共享内存(Shared Memory),信号量(Semaphore),套接字(Socket)。通过这些IPC机制,用户空间进程之间可以完成互相通信。为了完成 内核空间 与 用户空间 通信,Linux提供了基于socket的Netlink通信机制,可以实现内核与用户空间数据的及时交换。 本文第2节概述相关研究工作,第3节与其他IPC机制对比,详细介绍Netlink机制及其关键技术,第4节使用KGDB+GDB组合调试,通过一个示例程序演示Netlink通信过程。第5节做总结并指出Netlink通信机制的不足之处。

Linux添加系统调用的两种方法

怎甘沉沦 提交于 2020-02-22 04:40:19
前言 系统调用的基本原理 系统调用其实就是函数调用,只不过调用的是内核态的函数,但是我们知道,用户态是不能随意调用内核态的函数的,所以采用软中断的方式从用户态陷入到内核态。在内核中通过软中断0X80,系统会跳转到一个预设好的内核空间地址,它指向了系统调用处理程序( 不要和系统调用服务例程混淆 ),这里指的是在entry.S文件中的system_call函数。就是说,所有的系统调用都会统一跳转到这个地址执行system_call函数,那么system_call函数如何派发它们到各自的服务例程呢? 我们知道每个系统调用都有一个系统调用号。同时,内核中一个有一个system_call_table数组,它是个函数指针数组,每个函数指针都指向了系统调用的服务例程。这个系统调用号是system_call_table的下标,用来指明到底要执行哪个系统调用。当int ox80的软中断执行时,系统调用号会被放进eax寄存器中,system_call函数可以读取eax寄存器获得系统调用号,将其乘以4得到偏移地址,以sys_call_table为基地址,基地址加上偏移地址就是应该执行的系统调用服务例程的地址。 系统调用的传参问题 当一个系统调用的参数个数大于5时(因为5个寄存器(eax, ebx, ecx, edx,esi)已经用完了),执行int 0x80指令时仍需将系统调用功能号保存在寄存器eax中

linux系统高级编程

核能气质少年 提交于 2020-02-20 11:45:54
linux下高级编程的特点;涉及到内核向用户空间提供的接口(函数) 接口的功能 参数 返回值 I/O 文件IO 头文件:unistd.h fcntl.h 是从用户空间角度考虑的输入输出 从内核读数据或从文件中读数据叫 输入 read函数 写数据到内核或写数据到文件中叫 输出 write 函数 打开或创建一个文件 open函数 关闭一个文件 close函数 open(char*,flag,mode) char* 要打开的文件名和路径 一般用命令行参数传入(main参数) { 参数2(flags) flags分为两类:主类,副类 主类:O_RDONLY 以只读方式打开 / O_WRONLY 以只写方式打开 /O_RDWR 以可读可写方式打开 三这是互斥的 副类: O_CREAT 如果文件不存在则创建该文件 O_EXCL 如果使用O_CREAT选项且文件存在,则返回错误消息 O_NOCTTY 如果文件为终端,那么终端不可以调用open系统调用的那个进程的控制终端 O_TRUNC 打开一个文件删除文件中原有数据 O_APPEND 以追加的方式打开不删除里面数据 主副可以配合使用,例如:O_RDWR|O_CREAT|O_TRUNC ———————————————— 版权声明:本文为CSDN博主「大根菌」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

cmcc_simplerop

爷,独闯天下 提交于 2020-02-19 10:50:44
  这是一道系统调用+rop的题。   先来就检查一下保护。   32位程序,只开启了堆栈不可执行。ida看一下伪代码。   代码也很简洁,就是直接让你溢出。这里ida反汇编显示的v4具体ebp的距离是0x14,再加上0x8也就是0x1c就到返回地址了,但是在实际上,偏移不是这么多。这里我们用pwndbg测试。首先cyclic生成一些数字。      用pwndbg调试。   这里测出偏移是32,也就是距离返回地址是0x20。   接下来就是看看有些什么我们可以利用的函数吧!😊   首先就是可以看见有int 0x80,我们可以系统调用,关于系统调用的指令,我们可以参考这个博客,总结的很全。 https://blog.csdn.net/xiaominthere/article/details/17287965   接下来就是我们需要找一些通用的可以给寄存器赋值的命令。       在这里们我选择这两条,因为系统调用,需要我们执行这样的命令。   int80(11,"/bin/sh",null,null)   后面的四个参数分别是eax、ebx、ecx、edx。   所以上面的两条命令刚刚好。   接下来就是想办法找binsh的字符串,这道题是找不到的,需要我们自己输入。输入就需要调用函数,一般我们是选择调用read函数,将binsh字符串写入bss段,直接调用

Linux Hook 笔记

匆匆过客 提交于 2020-02-18 18:10:18
相信很多人对"Hook"都不会陌生,其中文翻译为"钩子".在编程中, 钩子表示一个可以允许编程者插入自定义程序的地方,通常是打包好的程序中提供的接口. 比如,我们想要提供一段代码来分析程序中某段逻辑路径被执行的频率,或者想要在其中 插入更多功能时就会用到钩子. 钩子都是以固定的目的提供给用户的,并且一般都有文档说明. 通过Hook,我们可以暂停系统调用,或者通过改变系统调用的参数来改变正常的输出结果, 甚至可以中止一个当前运行中的进程并且将控制权转移到自己手上. 基本概念 操作系统通过一系列称为系统调用的方法来提供各种服务.他们提供了标准的API来访问下面的 硬件设备和底层服务,比如文件系统. 以32位系统为例,当进程运行系统调用前,会先把系统调用号放到寄存器 %eax 中,并且将该系统调用的参数依次放入寄存器 %ebx, %ecx, %edx 以及 %esi 和 %edi 中. 以write系统调用为例: write(2, "Hello", 5); 在32位系统中会转换成: movl $1, %eax movl $2, %ebx movl $hello,%ecx movl $5, %edx int $0x80 其中 1 为write的系统调用号, 所有的系统调用号码定义在 unistd.h 文件中. $hello表示字符串 "Hello"的地址;