linux系统分析第二次实验

跟踪并分析Linux系统调用处理过程

学 号 : 413 \color {red} {学号:413} 413
原创作品转载请注明出处,本实验来源 https://github.com/mengning/linuxkernel/

实验要求:

编译内核5.0
qemu -kernel linux-5.0.1/arch/x86/boot/bzImage -initrd rootfs.img
选择系统调用号后两位与您的学号后两位相同的系统调用进行跟踪分析
https://github.com/mengning/menu
给出相关关键源代码及实验截图,撰写一篇博客(署真实姓名或学号最后3位编号)。

博客内容的具体要求如下:
  题目自拟,内容围绕系统调用进行;
  博客中需要使用实验截图
  博客内容中需要仔细分析系统调用、保护现场与恢复现场、系统调用号及参数传递过程
  总结部分需要阐明自己对系统调用工作机制的理解。

实验环境:

Ubuntu16.04虚拟机
qemu系统模拟器

实验步骤:

从孟宁老师所给的相关链接中下载linux5.0内核源码,从下面链接中选择5.0版本的内核源码进行下载:
https://www.kernel.org/

下载完成按如下步骤进行编译:

参数设置&编译
cd linux-5.0
make menuconfig 
选择Kernel hacking-->

选择Kernel hacking
选择Compile-time checks and compiler options —>
选择Compile-time checks and compiler options  --->

选择Compile the kernel with debug info —>
选择Compile the kernel with debug info --->

然后开始编译:

make -j8

编译完成界面如下:

编译完成

编译时遇到的问题:

https://blog.csdn.net/zxhio/article/details/80312316
在编译过程中,遇到的问题基本也就是这个博客中遇到的,故可参考上面的博客
下面对遇到的不同问题进行描述:

1.错误:make menuconfig时候出现:Makefile:21: recipe for target 'menuconfig' failed
解决办法:
安装ncurses库:sudo apt-get install libncurses5-dev

2. 错误: Makefile:1019:recipe for target 'vmlinux' failed 并提示内存耗尽
解决办法:
增加虚拟机内存重新编译

3. linux 内核编译时出现:scripts/sign-file.c:25:30: fatal error: openssl/opensslv.h: 没有那个文件或目
解决办法:
ubuntu下缺少了部分如下的组件,安装一下即可
sudo apt-get install libssl-dev

下载编译menuOS:

wget https://github.com/mengning/menu.git
make

编译时出现的问题

启动menuos是出现的问题

解决办法:

在编译内核时勾选取消勾选64位选项

menuOS使用

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

运行结果如下:

启动menuos

跟踪系统调用过程

qemu-system-i386 -kernel linux-5.0/arch/x86/boot/bzImage -initrd rootfs.img -S -s -append nokaslr

选取对应的系统调用(学号413)

选取213号系统调用

选取对应的系统调用
213号是setuid函数,即对uid进行设置。

setuid函数设置实际用户ID和有效用户ID。
  Linux的setuid函数和Unix中的setuid函数的行为是不同的。
  在Linux中, setuid(uid)函数的执行步骤为:
  (1)如果由普通用户调用,将当前进程的有效ID设置为uid.
  (2)如果由有效用户ID符为0的进程调用,则将真实,有效和已保存用户ID都设置为uid.
  在Unix中.setuid(uid)函数的行为为:
  (1)如果进程没有超级用户特权,且uid等于实际用户ID或已保存用户ID,则将有效的用户ID设置为uid.否则返回错误.
  (2)如果进程是有超级用户特权,则将真实、有效和已保存用户表示符都设置为uid.如果两个条件都不满足,则设置errno为EPERM。
函数在执行成功的时候返回0,在出错的时候返回-1。

在menu中编写程序并编译

建立mysetuid.c文件
gcc ./mysetuid.c -o myuid -m32 -static(生成可执行文件)
cd setuidfs/(建立文件夹并进入)
cp ../myuid init(拷贝之前的可执行文件,并修改名称为init)
find . | cpio -o -Hnewc | gzip -9 > ../rootfs.img
qemu-system-i386 -kernel ../bzImage -initrd rootfs.img(开启qemu)

得到的结果如下:

uid更新

其中uid(before)为原始uid,uid(after)为修改过的uid

实现代码如下:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>

int main(){

uid_t uid; 
uid = getuid();
printf("the uid(before)is %d\n",uid);
setuid(500);
uid = getuid();
printf("the new uid(after) is %d\n",uid);
while(1)
{
	getchar();
}
return 0;
}

结果分析

系统调用是应用程序和操作系统内核之间的功能接口。其主要目的是使得用户可以使用操作系统提供的有关设备管理、输入/输入系统、文件系统和进程控制、通信以及存储管理等方面的功能,而不必了解系统程序的内部结构和有关硬件细节,从而起到减轻用户负担和保护系统以及提高资源利用率的作用。
  在我们所用的Linux内核版本(RedHat 6.0,内核为2.2.5-15)中,第一个要修改的文件是:

/usr/src/linux/include/asm-i386/unistd.h 

该文件中包含了系统调用清单,用来给每个系统调用分配一个唯一的号码。文件中每一行的格式如下:
  
#define __NR_name NNN

其中,name用系统调用名称代替,而NNN则是该系统调用对应的号码。应该将新的系统调用名称加到清单的最后,并给它分配号码序列中下一个可用的系统调用号
setuid()用来重新设置执行目前进程的用户识别码. 不过, 要让此函数有作用, 其有效的用户识别码必须为0(root). 在Linux 下, 当root 使用setuid()来变换成其他用户识别码时, root 权限会被抛弃, 完全转换成该用户身份, 也就是说, 该进程往后将不再具有可setuid()的权利, 如果只是向暂时抛弃root 权限, 稍后想重新取回权限, 则必须使用seteuid().
  setuid函数是系统普通用户使用vi即可以编辑/etc/shadow文件,因为具备root身份,可以进行任意读写操作(比如可以把任何一个用户密码位清空,则用户登录不需要输入密码)。但是使用more、cat等命令仍然无法查看文件/etc/shadow的内容,只有被授予了SetUID的vi可以查看和修改。同样,vi如果具有了SetUID权限,普通用户可以vi编辑/etc/passwd文件把自己的UID改为0 ,则他的权限就和root一样;可以vi编辑/etc/inittab文件把缺省运行级别改成6 ,则Linux会开机后不停的重启。
  总之,利用setuid函数对用户id进行设置,从而对用户权限产生影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值