2019-2020-1 20199322《Linux内核原理与分析》第八周作业

本周主要研究的是可执行文件的工作原理

ELF(可执行与可链接格式)

Compiler(程序编译)

用一个例子来说明操作过程

预处理: gcc -E fuck.c -o fuck.i -m32
编译:gcc -S fuck.i -o fuck.s -m32
汇编:gcc -c fuck.s -o fuck.o -m32
默认衔接(动态库):gcc fuck.o -o fuck -m32
衔接静态库:gcc fuck.o -o fuck.static -m32 -static

前面是改menu内容,冻结内核,gdb调试,设置断点,这都是老生常谈的了,没什么可说的了。




分析

execve是一个比较有特别的系统调用
结合一个例子来说明一下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello", "world", NULL };
char *newenviron[] = { NULL };
if (argc != 2) 
{
fprintf(stderr, "Usage: %s <file-to-exec>\n", argv[0]);
exit(EXIT_FAILURE);
}
newargv[0] = argv[1];
execve(argv[1], newargv, newenviron);
perror("execve");   /* execve() returns only on error */
exit(EXIT_FAILURE);
}

另一段

#include <stdio.h>
#include <stdlib.h>
 int main(int argc, char *argv[])
{
int j;
for (j = 0; j < argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
}

总结

命令行参数和环境变量会通过shell传递给execve,excve通过系统调用参数传递,传递给sys_execve,最后sys_execve在初始化新进程堆栈的时候拷贝进去。当execve()系统调用终止且进程重新恢复它在用户态执行时,执行上下文被大幅度改变,要执行的新程序已被映射到进程空间,从elf头中的程序入口点开始执行新程序。
如果这个新程序是static link的,那么这个程序就可以独立运行,elf头中的这个入口地址就是本程序的入口地址;如果这个新程序是dynamic linking的,那么还需要装载共享库,elf头中的这个入口地址是动态链接器ld的入口地址。

posted @ 2019-11-08 15:18  汪振_20199322  阅读(142)  评论(0编辑  收藏  举报