| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 系统运维 -> linux elf 格式详解 -> 正文阅读 |
|
[系统运维]linux elf 格式详解 |
1.elf (Executable and Linkable Format) 是unix和类unix系统下得标准文件格式,包括常见地可执行文件,目标文件,库文件,coredump文件类型。维基百科里有elf格式的具体信息。elf wikihttps://en.wikipedia.org/wiki/Executable_and_Linkable_Format 2.elf 文件构成 file header segment section The segments contain information that is needed for?run time?execution of the file The sections contain important data for linking and relocation. 3.以可执行文件为例说明header segment section组织关系 header :描述了elf类型版本和平台信息,entry point是指程序的在内存里的执行入口。readelf -S a.out 能看到这个entry point 既是.text section的地址 program header:将多个具有相同权限和a对其属性的section合并成一个segment,在程序加载的时候,一起建立mem映射 section header:程序中某个具体的段比如.bss .init .text 以ubuntu 上gcc编译出的elf为例,section合并成segment(一个segment包含1个或多个section)的map如下? 4.elf可执行程序的加载与运行过程 在linux终端执行elf,如果没有指定命令解释工具的话(比如 bash -c),没有指定会用默认的sh 解释命令并与内核交互。sh会fork一个新的进程然后调用用户空间库函数execve然后内核系统调用do_execve。execve系统调用为elf的执行准备内存空间和用户权限,挂到某个cpu调度队列中。 在内核空间 struct linux_binprm用来记录一个可执行程序信息,struct linux_binfmt 是用来解释bin格式行为的结构体,以elf为例系统init阶段会注册好elf fmt的各种方法作为elf格式的binary hander ? bprm_mm_init初始化创建的进程的虚拟地址空间。参数和环境变量都设置完成后,prepare_binprm 中调用kernel_read 从filebuf中获取的前128字节,这里包含了elf header和program header,可以获取到文件的格式,之后execv_binprm --> search_binary_hadler(prm),找到提前注册好的elf文件的方法开始load_binary ? load_elf_binary (1)从128字节elf header和program header中检查elf magic 文件类型和架构支持 (2) loops over the program header entries, checking for an interpreter (PT_INTERP) and whether the program's stack should be executable (from the?PT_GNU_STACK?entry).? (3)flush_old_exec,执行命令时候是由sh fork出的进程(old_exec),从old_exec进程组分离出来,释放old_exec的mm设置bprm的mm 为new_mm, exec_mmap(bprm->mm),关闭old_exec的打开的文件 ? (4)? set_new_exec,设置new_exec的task->comm(a.out)和signal handler (5)设置程序的栈空间, randomize_stack_top 随机栈顶 (6)段描述的vaddr和size等信息为PT_LOAD类型的段map到对应的程序内存空间中 (7)设置bss段然后arch_setup_additional_pages (比如vdso page) ? (8)? create_elf_tables 把elf辅助向量 argc envc argv 等信息塞到stack之前的位置。on Linux systems it sits at the high end of the user address space, just above the (downwardly growing) stack, the command-line arguments (argv), and environment variables (environ). 动态链接器在加载so完成后会从辅助向量中的找到程序的entry和elf header。 (9)start_thread(current->regs, elf_entry, bprm->p), elf_entry作为返回用户空间后的pc。the?execve()?syscall returns to user space — but to a completely different user space, where the process's memory has been remapped, and the restored registers have values that start the execution of the new program 5.动态链接与elf 动态链接程序是在runtime时加载so的,.inter section指明了程序的链接器的绝对路径 readelf -p 1 ./a.out 可以查看.inter section中的内容 动态链接程序的本质也是一个类型是DYN的elf文件,在load_elf_binary中会将动态链接器load进内存,将interp的entry_point作为程序的elf_entry 返回userspace后interpret程序查找和加载so然后解析原程序中的未定义符号,完成这些之后会根据auxiliary vector 中的AT_ENTRY,启动程序。 6.重定位 7.阅读文章 elf 辅助向量阅读https://lwn.net/Articles/519085/ arch_setup_additional_pages vdsohttps://lwn.net/Articles/615809/stack randomize 查阅文章https://en.wikipedia.org/wiki/Stack_buffer_overflowstack randomize 查阅文章https://en.wikipedia.org/wiki/Stack_buffer_overflow elf GNU_STACK vdso 阅读文章https://en.wikipedia.org/wiki/Executable_space_protection |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/15 9:54:33- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |