20242822《Linux内核原理与分析》第六周作业

news/2025/3/12 19:40:32/文章来源:https://www.cnblogs.com/20202215zxp/p/18516424

实验五——分析 system_call 中断处理过程

在上一次实验中我选择的4号系统调用write

一、打开shell并使用命令启动内核进入menu程序

cd ~/LinuxKernel/

qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img

进入menu程序后,可以看到该系统中仅有3个命令:helpversionquit

二、在该系统中添加两条命令:writewrite-asm

writewrite-asm这两个函数是系统调用sys_write的C语言版本和汇编版本)

打开test.c文件可以看到main函数如下:

  • MenuConfig("version", "XXX V1.0(Menu program v1.0 inside)", NULL); - 配置菜单项。这个函数的第一个参数是命令名称"version",第二个参数是命令的描述或帮助信息,"XXX V1.0(Menu program v1.0 inside)",第三个参数是执行这个命令时的函数指针,这里是NULL,表示这个命令不会执行任何操作,只显示信息。

  • MenuConfig("quit", "Quit from XXX", Quit); - 另一项菜单配置,设置了一个退出命令"quit",描述信息是"Quit from XXX",对应的函数指针为Quit`,用于退出菜单系统。

  • ExecuteMenu();` - 执行菜单,进入到菜单系统中并等待用户的输入指令。

main函数中添加write和和write-asm

并给出WriteWrite_asm函数:

  • write(0, argv[i], strlen(argv[i]));:调用 write 函数,将 argv[i] 的内容写到文件描述符 0(标准输入/输出可能被重定向),字符串长度由 strlen(argv[i]) 决定。

  • write(0, "\n", 1);:写入一个换行符 \n

  • mov $4, %%eax:将系统调用号 4sys_write)放入 eax`,表示要执行写操作。

  • mov $1, %%ebx:将文件描述符 1(标准输出)放入 ebx

  • mov %2, %%ecx:将 str 的地址放入 ecx,指定要写入的字符串。

  • mov %3, %%edx:将字符串长度 len 放入 edx

  • int $0x80:触发中断 0x80,执行系统调用。

再次输入help可以看到以上两条命令已经添加:

三、分析系统调用的过程,从 system_call 开始到 iret 结束之间的整个过程

在 Linux 系统中,系统调用的过程通常是通过软件中断来完成的。以 x86 架构的 Linux 为例,系统调用的核心过程是通过 int 0x80 中断来触发内核中的 system_call 函数。以下是从 system_call 开始到 iret 返回的整个过程详细分析:

1. 触发系统调用:int 0x80

用户态程序执行 int 0x80 指令,触发系统调用中断 0x80,这会导致处理器进入内核态并跳转到系统调用入口,即 system_call 函数。以下是一些重要的准备工作:

  • 系统调用号:用户程序在 eax 寄存器中设置系统调用号,用于指定执行哪个系统调用(例如,sys_write 的系统调用号为 4)。
  • 参数:用户程序在 ebxecxedxesiedi 等寄存器中设置参数,这些寄存器将被 system_call 读取。

2. system_call 函数入口

系统调用的入口通常会执行以下操作:

  • 保存上下文system_call 首先将用户态的寄存器上下文(例如 eaxebxecxedx 等寄存器)保存到内核栈,以便系统调用完成后恢复用户态的状态。
  • 检查系统调用号system_call 会验证 eax 中的系统调用号是否合法。如果无效,则可能返回错误(例如 -ENOSYS 表示系统调用不存在)。

3. 调用相应的系统调用处理函数

根据系统调用号 eaxsystem_call 会从系统调用表中找到对应的系统调用处理函数并跳转执行。例如,如果系统调用号是 4(即 sys_write),则会执行 sys_write 函数。

  • 系统调用表(sys_call_table):这是一个函数指针数组,系统调用号用于索引该数组,从而找到相应的系统调用处理函数。例如 sys_writesys_read 等系统调用都在 sys_call_table 中有对应的函数指针。
  • 执行系统调用逻辑:系统调用处理函数(如 sys_write)执行相应的内核逻辑,通常涉及与硬件交互、文件操作、内存管理等。

4. 返回系统调用结果

系统调用处理函数执行完毕后,将返回一个结果值。通常情况下,返回值存放在 eax 寄存器中。

  • 错误处理:如果系统调用失败,内核会在 eax 中设置一个负数的错误码,例如 -EINVAL 表示无效参数。

5. 恢复用户态上下文

system_call 函数返回用户态之前,内核需要恢复用户态的寄存器上下文,以确保系统调用返回时用户态的执行环境不受影响。

  • 恢复寄存器:从内核栈中取出保存的寄存器值,恢复到各个寄存器。
  • 清理内核栈:清理在进入内核态时保存的上下文信息。

6. 返回用户态:iret

系统调用完成后,处理器会执行 iret 指令返回到用户态。iret 指令会从栈中弹出用户态的 CS:EIPEFLAGSSS:ESP 等寄存器,恢复用户态的指令指针、标志位和栈指针。

  • 切换回用户态iret 会将处理器的状态切换回用户态,并开始执行用户程序中系统调用之后的指令。
  • 返回结果:在用户程序中,系统调用的返回值将保存在 eax 寄存器中,这样用户程序可以通过检查 eax 的值来知道系统调用是否成功,以及获取到的结果。

四、总结

整个系统调用过程包括以下关键步骤:

  1. 用户态程序通过 int 0x80 触发系统调用中断。
  2. system_call 入口函数保存上下文,并根据系统调用号跳转到对应的系统调用处理函数。
  3. 系统调用处理函数执行内核逻辑并返回结果。
  4. system_call 恢复用户态上下文。
  5. iret 返回用户态,并让用户程序继续执行系统调用后的指令。

这个过程确保了系统调用的安全性和稳定性,使用户程序可以请求内核提供的服务而不会直接操作系统资源。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/824293.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《诛仙单机版系列一:六道轮回》安装教程|虚拟机一键端|GM工具包

今天给大家带来一款单机游戏的架设:诛仙-六道轮回-五职业。游戏版本:v1.2.4 只适用于单机娱乐,此教程是本人亲测所写,踩坑无数,如果你是小白跟着教程走也是可以搭建成功。 亲测视频演示 https://githubs.xyz/show/289.mp4游戏安装步骤 此游戏架设需要安装虚拟机,没有虚拟…

根据swagger.yaml生成harbor私库api调用代码

准备 下载https://github.com/goharbor/harbor/blob/main/api/v2.0/swagger.yaml 下载https://repo1.maven.org/maven2/io/swagger/swagger-codegen-cli/2.4.43/swagger-codegen-cli-2.4.43.jar生成调用代码 swagger-codegen-cli是用java写的, 但是支持生成多种语言的调用代码,…

网鼎杯

个人只做了一道web一道crypto Web02 打开赛题环境地址,是登录界面,进去后获取hash值用户名或密码随意我们访问到的flag界面 ** **进去后这里有个输入框测试下可以进行xss又根据/flag提示需要boss来访问这个路径,编写脚本构造payload进行访问,字符串编码下 import requests …

BuildCTF

主要做web方向,misc和crypto有几题也看了一下 Web ez!httpez_md5这里的<font style="background-color:rgb(249, 242, 244);">$_REQUEST</font>变量获得GET或POST的参数,值的注意的是,如果通过不同的方式获得相同变量的不同值,**<font style=&quo…

10.30 模拟赛

复盘 T1。好像很好做。先想了一个 \(\mathcal O(n |c_{i,j}|^2)\) 但是带四倍常数的做法。感觉加上一些优化和卡常后问题不大。于是开写。 代码好长!!!调试好久!!! 调完后样例 6 跑 20s,最终优化后还是 7s。实在优化不了了于是考虑换做法。 发现枚举三条边后,剩下的用类…

20222412 2024-2025-1 《网络与系统攻防技术》实验三实验报告

20222412 2024-2025-1 《网络与系统攻防技术》实验三实验报告 1.实验内容 (1)正确使用msf编码器,veil-evasion,自己利用shellcode编程等免杀工具或技巧正确使用msf编码器,使用msfvenom生成如jar之类的其他文件 veil,加壳工具 使用C + shellcode编程(2)通过组合应用各种技术…

Feign失败重试与全局异常捕获

feign注册 spring加载的时候通过@EnableFeignClients的FeignClientsRegistrar注册扫描所以得FeignClient以及Configuration,最终注册为ReflectiveFeign,最终通过代理类FeignInvocationHandler实现方法的调用,在 FeignInvocationHandler中通过SynchronousMethodHandler方法执…

地下工程和深基坑监测预警系统建设方案

随着城市化进程的加快,地下工程和深基坑工程在城市建设中扮演着越来越重要的角色。这些工程的安全性直接关系到人民生命财产的安全和城市的正常运行。因此,建立一个科学、有效的地下工程和深基坑监测预警系统至关重要。 一、系统建设的必要性地下工程和深基坑工程在施工过程中…

25. 深浅拷贝

一、什么是浅拷贝只对对象的最顶层进行的拷贝称为 浅拷贝。我们可以用 copy 模块中的 copy() 方法实现浅拷贝。import copya = [11, 22, 33] b = [44, 55, 66] c = [a, b] d = copy.copy(c)print(f"c: {c}") print(f"d: {d}") print(f"c == d: {c == …

为什么我越来越喜欢用DDD — DDD架构篇(1)

Hello DDDDDD 是一种软件设计方法,DDD 是指导我们做软件工程设计的一种手段。它提供了用切割工程模型的各类技巧,如;领域、界限上下文、实体、值对象、聚合、工厂、仓储等。通过 DDD 的指导思想,我们可以在前期投入更多的时间,更加合理的规划出可持续迭代的工程设计。 在D…

SpringBoot3.0整合Mybatis-plus实现多数据源(重构类方式)

背景 前段时间在做一个数据中台的项目,系统用到了不同数据库中的数据。自己又不想手写JDBC连接,既然我有这个需求,那功能应该有人实现了,于是开始了网上搜了,搜索后发现基本都是讲读写分离、主备切换的,后面也查略了Mybatis-plus的官网,里面有这个功能,但好像是我组件的…