20189220 余超《Linux内核原理与分析》第五周作业
扒开系统调用的三层皮?(上)
第4章的基础知识
- Linux系统调用的三层机制:xyz()(API函数)、system_call(系统调用处理入口) 、 sys_xyz()(系统调用内核处理函数)。
- 32位的X86机器上在用户态的时候只能访问0x00000000—0xbfffffff的地址空间,而在内核态下可以访问所有的地址空间。
- 中断,系统调用是最常用的两种方式,从用户态切换到内核态。
- int指令触发中断机制会在堆栈上保存一些寄存器的值,会保存用户态栈顶地址,当时的状态字,当时的CS:EIP的值。
- 中断发生后的第一件事就是保存现场,中断结束的最后一件事就是恢复现场。
- 系统调用的意义可以把用户从底层的硬件编程中解放出来,极大的提高了系统的安全性,使用户程序具有可移植性。
- API(应用程序编程接口)是函数定义,一个API可以对应多个系统调用,他们之间是多对多的关系。
- 使用EAX寄存器传递一个名为系统调用号的参数。
- Linux操作系统中采用了0和3两个特权级别,分别对应内核态和用户态。
- 在Linux中,系统调用是用户空间访问内核的惟一手段;除异常和中断外,它们是内核惟一的合法入口。 而kernel留给用户层的接口其实就只有一个:软中断(int 0x80)。用户态通过它来陷入内核态,完成系统调用。为了方便使用,kernel与用户层之间又增加了API与一些库(例如libc库)来封装这一过程。因此,目前的资料里大部分都写,调用一个系统调用有三种方法:
(1)通过 glibc 提供的库函数
(2)使用 syscall 函数直接调用
(3)通过 int 0x80指令陷入 - API/libc与系统调用的关系:既然API与libc对软中断进行了封装,那我们先一起看看它们之间的具体关系。一般情况下,应用程序通过应用编程接口(API)而不是直接通过系统调用来编程。这点很重要,因为应用程序使用的这种编程接口实际上并不需要和内核提供的系统调用一一对应。一个API定义了一组应用程序使用的编程接口。从程序员的角度看,系统调用无关紧要,他们只需要跟API打交道就可以了。相反,内核只跟系统调用打交道;库函数及应用程序是怎么使用系统调用不是内核所关心的。
系统调用实现机制
与调用函数一样,系统调用也需要输入输出参数。每个系统调用至少有一个参数,即系统调用号(由eax传递),其他参数依次由ebx、ecx、edx、esi、edi、ebp传入。 由于使用寄存器传递参数,因此对参数的长度做了限制:
(1)每个参数的长度不能超过寄存器的长度,即32位
(2)在系统调用号(eax)之外,参数的个数不能超过6个(ebx、ecx、edx、esi、edi、ebp)如果超过六个,可以传入一个地址,地址所在地存放多个参数
系统调用的三个层次依次是:xyz函数(API)、system_ call(中断向量)和 sys_ xyz(中断服务程序)。

触发一个系统调用的三种方式
1.API函数的方式
首先我选取的是20号的getpid系统调用

编译的结果如下:

2.嵌入式汇编方式

编译运行完的结果

3.调用库函数syscall

编译完运行的结果

4.用gdb进行调试看API的调用是否就是像我们之前分析的对系统调用的封装那样执行的
在getpid处设置断点,运行到断点处。

使用ni命令,对汇编指令逐条运行,前面的清理寄存器的值此处先不讨论,直接一直ni运行到传递系统调用号处(箭头所指的为下一条将要运行的指令, 利用info r命令来查看当前寄存器的值,系统调用号还未传入,eax还为0)。

ni一下,再次查看,发现系统调用号已经传入,确实是利用eax的。

再ni一下,此时该系统调用的实际工作已经完成了,结果(也就是pid)保存在eax中。

实验分析
- getpid是一种函数,功能是取得进程识别码。
- 函数原型:旧的原型为pid_t getpid(void);,推荐使用int _getpid( void );这种形式。注意,函数名第一个字符是下划线。
- 函数说明:getpid函数用来取得目前进程的进程ID,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。
- 返回值:目前进程的进程ID。
- 在Linux系统中是通过激活0x80中断来触发系统调用的,需要调用的系统调用号实现赋值给eax存储器,如果有传入参数可赋值给ebx寄存器,如果多于1个则按顺序赋值给ebx、ecx、edx、esi、edi、ebp,如果超过6个则通过指针变量指向另一片堆栈区,如果无参数传入则赋值为0。
汇编代码的分析
#include <stdio.h>
#include<unistd.h>
int main()
{
pid_t pid;
asm volatile(
"movl $0,%%ebx\n\t"//将ebx寄存器清零,系统调用传递第一个参数使用ebx,这里是null
"movl $0x14,%%eax\n\t"//将0xd放入eax中,0x14为20,传递系统调用号20
"int $0x80\n\t"
"movl %%eax,$0\n\t"//通过eax这个寄存器返回系统调用值,和普通函数一样
:"=m"(pid)
);
printf("this process's pid is : %u\n",pid);
return 0;
}
遇到的问题
1.我最开始在做书上给的38号系统调用的例子的时候,出现了下面的问题

后面再网上搜索资料可以得知是因为在64位系统下去编译32位的目标文件,这样是非法的。必须用”-m32”强制用32位ABI去编译,即可编译通过。
2.我在改写syscall函数的的时候,出现了下面的问题

最后发现是因为缺少必要的头文件,添加上 1 #include <unistd.h>2 #include <sys/syscall.h>3 #include <sys/types.h>即可
本章总结
- 在Linux中我们可以通过三种方式也进行系统的调用分为:API方式,C代码中嵌入式汇编语言,和库函数syscall。API方法实现系统调用实现非常便捷,只需知道函数原型即可。
- 经过这次实验,我们可以看到:
(1)要查看系统资源(如pid等),只有处于内核态(0级)的时候才可以。
(2)用户要从用户态(3级)切换到内核态(0级),就要通过软中断(int 0x80)来进行系统调用。
(3)通过eax传递系统调用号,然后由system_call交给system_service完成工作。
(4)system_service完成工作后,结果又由eax传递给用户态堆栈。
我对API系统调用的理解:

- 总之用户调用API函数,系统调用号和参数保存到 eax,ebx ,等寄存器中,通过 0x80 中断向量触发中断陷入内核态,中断服务程序根据系统调用号调用并执行对应的系统调用函数,执行完毕后将结果存放的 eax 中并返回给程序,程序返回用户态。
20189220 余超《Linux内核原理与分析》第五周作业的更多相关文章
- 20169212《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...
- 20169210《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...
- 2018-2019-1 20189221 《Linux内核原理与分析》第九周作业
2018-2019-1 20189221 <Linux内核原理与分析>第九周作业 实验八 理理解进程调度时机跟踪分析进程调度与进程切换的过程 进程调度 进度调度时机: 1.中断处理过程(包 ...
- 2017-2018-1 20179215《Linux内核原理与分析》第二周作业
20179215<Linux内核原理与分析>第二周作业 这一周主要了解了计算机是如何工作的,包括现在存储程序计算机的工作模型.X86汇编指令包括几种内存地址的寻址方式和push.pop.c ...
- 2019-2020-1 20199329《Linux内核原理与分析》第九周作业
<Linux内核原理与分析>第九周作业 一.本周内容概述: 阐释linux操作系统的整体构架 理解linux系统的一般执行过程和进程调度的时机 理解linux系统的中断和进程上下文切换 二 ...
- 2019-2020-1 20199329《Linux内核原理与分析》第二周作业
<Linux内核原理与分析>第二周作业 一.上周问题总结: 未能及时整理笔记 Linux还需要多用 markdown格式不熟练 发布博客时间超过规定期限 二.本周学习内容: <庖丁解 ...
- 2019-2020-1 20209313《Linux内核原理与分析》第二周作业
2019-2020-1 20209313<Linux内核原理与分析>第二周作业 零.总结 阐明自己对"计算机是如何工作的"理解. 一.myod 步骤 复习c文件处理内容 ...
- 2018-2019-1 20189221《Linux内核原理与分析》第一周作业
Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...
- 《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
- 2018-2019-1 20189221《Linux内核原理与分析》第二周作业
读书报告 <庖丁解牛Linux内核分析> 第 1 章 计算工作原理 1.1 存储程序计算机工作模型 1.2 x86-32汇编基础 1.3汇编一个简单的C语言程序并分析其汇编指令执行过程 因 ...
随机推荐
- JavaWeb项目目录结构
今天本来是准备学习spring mvc + mybatis,结果被idea的配置环境卡主了,自己刚刚接触JavaWeb不久,所以浪费了很多时间.最终我回归最简单的servlet & jsp,并 ...
- 身份证验证PHP类
PHP根据身份证号,自动获取对应的星座函数,然后自动返回对应的星座,自动返回性别,判断是否成年 <?php class IdcardAction extends Action{ // PHP根据 ...
- Oracle 数据类型比较规则
数值 较大的值被认为大于较小的值.所有负数都小于零,所有正数都小于零.因此,-1小于100:-100小于-1. 浮点值NaN(not a number))大于任何其他数值,且等于自身. 日期时间值 较 ...
- 总结一下NDK crash排查步骤
总结一下NDK crash排查步骤: 先在PC上跑通算法 用Visual Studio写算法的testbed,确保算法能跑通 抓log adb logcat -c; adb logcat > 1 ...
- SVN无法检出项目
情况说明: SVN的管理员给我一个项目的检出权限,我用浏览器可以访问,TortoiseSVN无法检出,提示没有访问URL的权限,不能检出. SVN管理员交流别人可以使用,我用同事的电脑,使用我的账号检 ...
- ELK-Elasticsearch 基础使用
一.基本概念 1 Node 与 Cluster Elastic 本质上是一个分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个 Elastic 实例.单个 Elastic 实例称为一个节点( ...
- varnish加速web
varnish主要功能是代理服务器和缓存,和nginx代理一样可以反向代理web服务器.但是varnish不能作为web服务器.但是它的优点是可以将访问过的网站还存在代理服务器上,以便于提升web的访 ...
- 《基于 UML 的教务系统设计方法研究》论文笔记(十五)
标题:基于 UML 的教务系统设计方法研究 时间:2009 来源:太原师范学院 关键词:UML:面向对象:建模:教务管理系统. 二.研究内容 UML 建模 UML 涵盖了面向对象的分析.设计和实现,融 ...
- 20199301《Linux内核原理与分析》第十二周作业
ShellShock攻击实验 一.环境搭建 下载 $ sudo su $ wget http://labfile.oss.aliyuncs.com/bash-4.1.tar.gz 安装 $ tar x ...
- 5、Python之包管理工具pip
pip提供我们各色各样的软件(第三方库),而这些第三方库又可以给我们实现各种各样不同的功能,科学计算.画图.操作文件.聊天-- 我们可以通过Cmd终端.Pycharm.Jupyter三种平台使用pip ...