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

一、预处理、编译和链接和目标文件的格式

1、可执行程序是怎么来的?

理解编译链接的过程和ELF可执行文件格式

过程:

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

再汇编成目标码.o,

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

最后可执行文件就可以加载到内存中执行。

2、目标文件的格式ELF

1)主要有三种目标文件

可重定位文件、可执行文件、共享文件

2)ELF文件加载到内存是如何加载的呢?

代码、数据都加载到内存中,默认ELF文件从0x开始加载,开始加载的是头部,会有一些信息,所以入口地址0x(这个地方就是程序的实际入口,可执行文件加载到内存中开始执行的第一行代码从这里开始)

3、静态链接的ELF可执行文件和进程的地址空间

入口地址为0x8048*00

二、可执行程序、共享库和动态链接

1、使用exec*库函数加载一个可执行文件

(1)动态链接分为可执行程序转载时动态链接和运行时动态链接

1)在linux下动态链接的文件是.so

2)libshlibexample.so文件(生成一个共享库文件)

libdllibexample.so(生成可动态加载文件)

(2)若是静态链接的,elf_entry就是指向可执行文件里边规定的那个头部,即main函数对应的位置,若这个可执行文件是需要依赖其它动态链接库的话,则elf_entry就是指向动态链接器的起点

2、

(1)execve:当前的可执行程序在执行execve这个系统调用的时候,它陷入到内核态,在内核态里它用这个execve加载的这个可执行文件把当前进程的可执行程序给覆盖掉,当execve这个系统调用返回的时候,返回的不是原来的那个可执行程序了,而是新的可执行程序了,它返回的是新的可执行程序的起点,即main函数大致的位置

(2)ELF文件加载到内存是如何加载的呢?

代码、数据都加载到内存中,默认ELF文件从0x开始加载,开始加载的是头部,会有一些信息,所以入口地址0x(这个地方就是程序的实际入口,可执行文件加载到内存中开始执行的第一行代码从这里开始)

•命令行参数和shell环境,一般我们执行一个程序的Shell环境,我们的实验直接使用execve系统调用。

•$ ls -l /usr/bin 列出/usr/bin下的目录信息

•Shell本身不限制命令行参数的个数,命令行参数的个数受限于命令自身

•例如,int main(int argc, char *argv[])

•又如, int main(int argc, char *argv[], char *envp[])

•Shell会调用execve将命令行参数和环境参数传递给可执行程序的main函数

•int execve(const char * filename,char * const argv[ ],char * const envp[ ]);

•库函数exec*都是execve的封装例程

命令行参数和环境串都放在用户态堆栈中

装载时动态链接和运行时动态链接应用举例

动态链接分为可执行程序装载时动态链接和运行时动态链接,如下代码演示了这两种动态链接。

•准备.so文件

shlibexample.h (1.3 KB) - Interface of Shared Lib Example

shlibexample.c (1.2 KB) - Implement of Shared Lib Example

编译成libshlibexample.so文件

1.$ gcc -shared shlibexample.c -o libshlibexample.so -m32

dllibexample.h (1.3 KB) - Interface of Dynamical Loading Lib Example

dllibexample.c (1.3 KB) - Implement of Dynamical Loading Lib Example

编译成libdllibexample.so文件

1.$ gcc -shared dllibexample.c -o libdllibexample.so -m32

•分别以共享库和动态加载共享库的方式使用libshlibexample.so文件和libdllibexample.so文件

main.c  (1.9 KB) - Main program

编译main,注意这里只提供shlibexample的-L(库对应的接口头文件所在目录)和-l(库名,如libshlibexample.so去掉lib和.so的部分),并没有提供dllibexample的相关信息,只是指明了-ldl

1.$ gcc main.c -o main -L/path/to/your/dir -lshlibexample -ldl -m32

2.$ export LD_LIBRARY_PATH=$PWD #将当前目录加入默认路径,否则main找不到依赖的库文件,当然也可以将库文件copy到默认路径下。

3.$ ./main

4.This is a Main program!

5.Calling SharedLibApi() function of libshlibexample.so!

6.This is a shared libary!

7.Calling DynamicalLoadingLibApi() function of libdllibexample.so!

8.This is a Dynamical Loading libary!

三、可执行程序的装载

1.可执行程序的装载相关关键问题分析

(1)可执行程序的装载实际上相当于系统调用。execve系统调用比较特殊。

(2)sys_execve内核处理过程:

  • do_execve -> do_execve_common -> exec_binprm
  • 最后根据给出的文件名加载文件头部信息寻找对应的文件格式处理模块。

(3)fmt->load_binary(bprm):用来解析ELF格式文件的执行的位置,这个位置是load_elf_binary。

(4)内核是如何支持多种不同可执行文件格式的?

本质上是观察者模式,通过修改内核堆栈中EIP的值作为新程序的起点。

(5)庄周(调用execve的可执行程序)入睡(调用execve陷入内核),醒来(系统调用execve返回用户态)发现自己是蝴蝶(被execve加载的可执行程序)。

2. sys_execve的内部处理过程

do_ execve调用do_ execve_ common,do_ execve_ common主要依靠exec_ binprm,其中重要的函数:search_binary_handler(bprm)。

  • 打开file文件,找到文件头部,把命令行参数和环境变量copy到结构体中:retval=copy_strings(bprm->envc, envp, bprm);
  • 寻找打开的可执行文件处理函数:ret= search_binary_handler(bprm);
  • 寻找能够解析当前可执行文件的模块,load_ binary加载这个模块,实际调用的是binfmt_ elf.c:retval=fmt->load_binary(bprm);
  • ELF可执行文件会被默认映射到0X8048000这个地址;
  • 需要动态链接的可执行文件先加载连接器ld;否则直接把ELF文件entry地址赋值给entry;
  • start_ thread(regs, elf_ entry, bprm->p)将CPU控制权交给ld来加载依赖库并完成动态链接。对于静态链接的文件elf_entry是新程序执行的起点

通过实验用gdb跟踪分析一个execve系统调用内核处理函数sys_execve ,验证对Linux系统加载可执行程序所需处理过程的理解

实验过程:

把menu删掉,重新克隆一份

进入test.c中查看:

进入makefile中查看:

开始使用gdb跟踪​:

new_ip是返回到用户态的第一条指令的地址 看该可执行程序的入口点地址,发现和new_ip的位置是一样的。

退出调试状态,输入redelf -h hello可以查看hello的EIF头部:

四、浅谈Linux内核装载和启动一个可执行程序

  检查ELF可执行文件的有效性,寻找动态链接的“.interp”段,设置动态链接器路径(与动态链接有关),根据ELF可执行文件的程序头表的描述,对ELF文件进行映射,比如代码,数据,只读数据,代码、数据都加载到内存中,默认ELF文件从0x开始加载,开始加载的是头部,会有一些信息,所以入口地址0x(这个地方就是程序的实际入口,可执行文件加载到内存中开始执行的第一行代码从这里开始),初始化ELF进程环境,比如进程启动时EDX寄存器的地址应该是DT_FINI的地址(和动态链接有关),将系统调用的返回地址修改为ELF可执行文件的入口,这个入口点取决于程序的链接方式,对于静态链接的可执行文件,若是静态链接的,elf_entry就是指向可执行文件里边规定的那个头部,即main函数对应的位置,若这个可执行文件是需要依赖其它动态链接库的话,则elf_entry就是指向动态链接器的起点。

《Linux内核分析》第七周笔记 可执行程序的装载的更多相关文章

  1. Linux内核分析第七周学习笔记——Linux内核如何装载和启动一个可执行程序

    Linux内核分析第七周学习笔记--Linux内核如何装载和启动一个可执行程序 zl + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study. ...

  2. LINUX内核分析第七周学习总结:可执行程序的装载

    LINUX内核分析第七周学习总结:可执行程序的装载 韩玉琪 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  3. Linux内核分析 第七周 可执行程序的装载

    张嘉琪 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 Linux内核分析 第七 ...

  4. Linux内核分析第七周———可执行程序的装载

    Linux内核分析第七周---可执行程序的装载 李雪琦+原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/US ...

  5. LINUX内核分析第七周学习总结

    LINUX内核分析第七周学习总结 标签(空格分隔): 20135328陈都 陈都 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.c ...

  6. LINUX内核分析第七周学习总结——可执行程序的装载

    LINUX内核分析第六周学习总结——进程的描述和进程的创建 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cours ...

  7. 20135327郭皓--Linux内核分析第七周 可执行程序的装载

    第七周 可执行程序的装载 郭皓 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 ...

  8. linux内核分析 第七周

    一.课堂相关 (一)预处理.编译.链接和目标文件的格式 1.可执行程序是怎么得来的 C代码--预处理--汇编代码--目标代码--可执行文件 预处理负责把include的文件包含进来及宏替换工作. he ...

  9. "Linux内核分析"第七周

    可执行程序的装载 张文俊+原创作品转载请注明出处+<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.预 ...

随机推荐

  1. 菜鸟水平如何在Android Studio中添加uiautomator测试框架

    1.启动AS,弹出创建Android Studio项目 2.选择 "Start a new Android Studio project",输入 application name ...

  2. Django 通过 session 保存个人信息

    通过 session 保存 个人 信息 登录的视图函数中: def login(request): ''' 登录 ''' err, user, pwd = '', '', '' if request. ...

  3. Android实践--apk反编译

    版权声明:本文为博主原创文章.转载请注明出处. https://blog.csdn.net/ysjian_pingcx/article/details/25468867 Android apk反编译一 ...

  4. 面试被问http协议?这篇文章足够覆盖所有相关问题!

    http使用面向连接的TCP作为传输层协议.http本身无连接. 请求报文 CRLF是回车换行     方法为GET的请求报文     方法为POST的请求报文     方法 OPTIONS:这个方法 ...

  5. win10下SVN图标不显示

    win10系统的SVN图标不现实了.正常情况下,会在文件夹上有一个对勾 但是对勾以及所有的SVN图标都突然消失了,都不知道文件什么状态了. 经过一通搜索,发现问题所在(都指向注册表图标被占用).原因就 ...

  6. navicate使用小技巧

    以下效果是按住alt+按住鼠标左键,往左往右移动,即可

  7. 网站性能优化小结和spring整合redis

    现在越来越多的地方需要非关系型数据库了,最近网站优化,当然从页面到服务器做了相应的优化后,通过在线网站测试工具与之前没优化对比,发现有显著提升. 服务器优化目前主要优化tomcat,在tomcat目录 ...

  8. springadmin环境搭建

    一路走过来都是坑,记录下来以后避免在踩 springboot版本信息2.0.3 admin服务端 maven配置信息 <properties> <project.build.sour ...

  9. jQuery 动画效果

    推荐网址:http://www.php100.com/manual/jquery/,用法教学,包括实例. 分类:显示隐藏.淡入淡出.滑动.自定义. <%@ Page Language=" ...

  10. ubuntu 下使用 jsoncpp库

    做项目的时候需要用c++解析json文件, 之前使用的是libjson 库, 但当g++ 开启 -std=c++11 选项时, 该库的很多功能不能用, 而且还有一些其他的问题, 不推荐使用. 后来采用 ...