Linux第7次实验——谢飞帆

原创作品转载请注明出处 + 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

这一周的主要内容是可执行程序的装载。

一、那么首先来看一下编译链接的过程和ELF可执行文件格式

1、这张图简明扼要的说明了可执行程序的产生。?

?大概过程是这样的:

?.c文件汇编成汇编代码.asm,

然后再汇编成目标码.o,

然后链接成可执行文件a.out,

这时可执行文件就可以加载到内存中执行了。

2、举个例子(对hello world .c文件进行编译链接):

?具体过程如图:

?3、ELF可执行文件格式

(1)ELF中的三种主要的目标文件

?可重定位文件:.o文件

共享目标文件:.so文件(链接编辑器=静态链接器)

(2)文件格式

(3)查看可执行文件的头部(readelf指令)

指明了版本号、OS/ABI、ABI的版本、是可执行文件还是目标文件、入口地址(程序的起点)。

(4)静态链接的ELF可执行文件和进程的地址空间

入口地址为0x(不唯一);

x86的系统有4G的进程地址空间(前面的1G:内核用;之后:用户态可访问);

当一个ELF可执行文件要加载到内存中时:

先把代码段和数据段加载到当中(默认从0x位置开始加载);

开始加载时,前面的都是ELF格式的头部信息,大小不尽相同,根据头部大小可确定程序的实际入口;

当启动一个刚加载过可执行文件的进程时,就可从这个位置开始执行。

二、接下来是使用exec*库函数加载一个可执行文件的过程

注:对于静态链接,只要传递命令行参数和环境变量等就可以正常工作了;但是对于绝大多数的可执行程序来讲,还是有一些对动态链接库的依赖。

?动态链接分为可执行程序装载时动态链接和运行时动态链接。

(1)引用视频中的例子

?在main函数中调用动态加载共享库时需要用到dlopen;

声明了一个函数指针【*func】;

找到函数名,根据函数名赋给指针。

这样就可以使用共享库中定义的函数了。

(2)怎样编译执行?

三、在跟踪分析之前稍微提一下关于可执行程序的装载的关键问题

?1、sys_execve内核处理过程:

do_execve-> do_execve_common -> exec_binprm //调用顺序

2、观察者和被观察者

3、sys_execve的内部处理过程?

?这是系统调用的入口:

do_execve:

1550行为用户态的指针;

1553行把命令行参数变成一个结构。

do_execve_common:

其中有几个关键的地方:

(1)do_open_exec:

打开要加载的可执行文件,还会加载它的文件头部。

创建了一个结构体bprm:

1505和1509行是把环境变量和命令行参数都copy到结构体中;

1513行开始是可执行文件的处理过程。

(2)exec_binprm:

其中关键的代码为search binary handler(寻找此可执行文件的处理函数):

在其中更关键的代码:

在这个循环中寻找能够解析当前可执行文件的代码。

1374行为加载可执行文件的处理函数,实际调用的是load_elf_binary函数:

查找一下可发现:

48行为此函数原型;

84行为赋值语句;

571行为函数的实现。

赋值的代码:

这是一个结构体变量。

此结构体变量是怎么进入内核的处理模块中的:

此函数中将这个结构体变量注册进了链表中,

如此当出现了一个ELF格式的文件时,在链表中寻找就能发现此结构体变量。

函数实现代码中较关键的代码:

注:ELF可执行文件会被默认映射到0x这个地址。?

如果进入到这个语句,即表示它需要依赖其他的动态库(不是静态链接的可执行文件);

它就会加载load_elf_interp(动态链接库动态链接文件),动态链接器的起点。

?如果它是一个静态链接,可直接进行以下赋值:

可发现在start_thread处会有两种可能:

小结:

如果是静态链接,elf_entry就指向了可执行文件中规定的头部,即main函数对应的位置,是新程序执行的起点;

如果是需要依赖其他动态库的动态链接,elf_entry是指向动态链接器的起点。

四、最后就是使用gdb跟踪分析一个execve系统的调用内核处理函数sys_execve

?(1)先把menu删掉,重新clone一份之后进入menu,覆盖test.c之后进入查看

(2)test.c

可发现增加了一句menuconfig(exec);

与fork源代码不同只在于增加了一句execlp。

(3)?Makefile

可发现其中编译了hello.c;

然后在生成根文件系统的时候把init和hello都放到rootfs.img中了。

(4)make rootfs

发现增加了exec。

(5)开始使用gdb跟踪?

(6)设断点

(7)开始执行

发现按了3个c之后程序才执行结束。

(8)执行exec?

发现它执行到这个地方就停止了。

注:?不知道是什么原因,每次执行到这一步实验楼就完全卡住。重新开始实验也是这样的结果。所以后面的步骤配图来自视频。(截图过多,适当省略了一点)

(9)list,然后继续s跟踪

发现跟踪到了do_execve处;

(10)c继续执行

?到了load_elf_binary处;

list,然后继续n跟踪:

此时追踪到start_thread处。

问题:new_ip到底指向哪里?

?(11)再次水平分割,然后执行readelf命令

?可发现new_ip指向入口点地址。

(12)关掉新窗口之后按n执行然后一直s执行

可以发现这里将new_ip和new_sp赋值,并设了一个新堆栈。

?(13)最后按c执行结束

?五、总结动态链接的过程中内核做了什么?

1、动态链接库的依赖关系会形成一个图?

2、问题:是由内核负责加载可执行程序依赖的动态链接库吗?

答:否。由动态连接器(libc的一部分)完成,是用户态做的事情。?

?3、动态链接库的装载过程是一个图的遍历

4、动态链接:由ld来动态链接可执行程序,完成各种工作之后再把控制权移交给可执行程序的入口,可执行程序然后执行。?

时间: 2024-10-19 16:39:39

Linux第7次实验——谢飞帆的相关文章

Linux第8次实验——谢飞帆

原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1.理解进程上下文的切换机制,以及与中断上下文切换的关系 用户态进程它在用户的时候,它没法直接调用schedule(),因为schedule是个内核函数,而且它也不是一个系统调用,没法直接调用它,只能间接的调用它,间接的调用schedule()的时机就是中断处理过程 对于用户态进程,它要从当前运行中的进程切换出去的话,那么它就必须要进入

Linux第四次实验——谢飞帆

原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 使用库函数API和C代码中嵌入汇编代码两种方式使用同一个系统调用,理解系统调用的工作机制. 本次实验选择24号和47号系统调用,分别获取当前用户uid(用户ID)和gid(组ID),即模拟Linux系统“id”命令. 编写两段代码,分别使用库函数API和C代码中嵌入汇编代码 uidgid.c(使用库函数API方式): 程序中通过调用ge

Linux第六次实验——谢飞帆

原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 在Linux中,task_struct其实就是通常所说的PCB.该结构定义位于: /include/linux/sched.h task_struct比较庞大,大致可以分为几个部分: 进程状态(State) 进程调度信息(Scheduling Information) 各种标识符(Identifiers) 进程通信有关信息(IPC:Inte

Linux下的ssh实验环境搭建与管理

Linux下的ssh实验环境搭建与管理 实验环境 服务端:xuegod-63   IP:192.168.1.63 客户端:xuegod-64   IP:192.168.1.64 客户端普通用户:ceshi  密码:123456 安装好扫描软件rpm -ivh /mnt/Packages/nmap-5.21-4.el6.x86_64.rpm 实验目标 1:SSHD服务介绍 2:SSHD服务安装配置 3:两Linux服务器之间数据拷贝 4:SSHD服务作用: 实验步骤 1:搭建环境 1):网桥模式

linux第四章实验报告

Linux第四章 用户和文件权限管理 实验环境 公司的linux主机即将提供给技术部作为开发服务器使用,根据部门内项目组的构成情况,首先需要建立相应的组账号.用户账号,并作为目录设置权限,还需要设置一个共用的数据存储目录,便于同事之间的数据交换. 需求描述 1.建立用户目录 创建目录/tech/benet和/tech/accp,分别用于存放各项目组中用户账号的宿主文件夹.例如,kylin用户的宿主目录应位于/tech/benet/kylin. 2.添加组账户 为两个项目组添加组账号benet,a

《Linux内核分析》实验一

陈智威,<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 课堂学习笔记: 作业截图: 汇编代码堆栈分析: 总结:计算机的工作是通过一系列的代码使其硬件能够按照所编写的指令进行运行,而此次实验就是具体介绍了一下Linux的运行方式,用汇编的语言,即更贴切计算机的语言来向我们介绍了计算机是如何进行工作的.

Linux第五次实验

北京电子科技学院(BESTI) 实     验    报     告 课程:信息安全系统设计基础                     班级: 201352 姓名:池彬宁 贺邦 学号:20135212 20135208 成绩:             指导教师:   娄嘉鹏  实验日期:2015.12.1 实验密级:         预习程度:             实验时间:15:30~18:20 仪器组次:          必修/选修:       必修          实验序号:4

Linux 基础入门第一次实验笔记

第一节.实验介绍 本节主要介绍 Linux 的历史,Linux 与 Windows 的区别等入门知识.如果你已经有过充分的了解,可以跳过本节,直接进入下一个实验. 一.Linux 为何物 Linux 就是一个操作系统,就像你多少已经了解的 Windows(xp,7,8)和 Max OS ,至于操作系统是什么,就不用过多解释了,如果你学习过前面的入门课程,应该会有个基本概念了,这里简单介绍下操作系统在整个计算机系统中的角色. 我们的 Linux 也就是系统调用和内核那两层,当然直观的来看,我们使用

linux ftps ftp-over-ssl 配置实验

本文为亲自实践  全文参考 http://www.linuxidc.com/Linux/2012-09/71129.htm ftps是借助ssl协议加密的,ssl是为http/smtp 等加密设置的.sftp是借助ssh加密,ssh是为telnet/ftp等加密,建立传输通道而设计的 ssh建立通道就是为了加密和传输,ftps 从原理上将就是 ftp-over-ssl的意思即ftp借助ssl协议加密传输,不但要用ftp服务器还要用ssl协 议加密.sftp协议是ssh中的一条独立的协议,利用sf