可执行程序的装载

可执行文件的创建

预处理:加入头文件执行宏替换等操作

gcc -E hello.c -o hello.i

编译:检查无误后转为汇编语言

gcc –S hello.i –o hello.s

汇编:转为二进制

gcc –c hello.s –o hello.o

链接:生成可执行文件

gcc hello.o –o hello

一步完成的命令为:

gcc hello.c -o hello

elf文件分为可重定位文件、可执行文件、共享文件等

查看elf文件的文件头可以用readelf

程序的入口地址是0x8048000

可执行文件的执行环境

  • 命令行参数和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文件 

$ 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文件

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

  • 运行

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

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

./main

可执行程序的装载

实验:

gdb跟踪内核函数sys_execve处理过程

内核准备

执行exec

gdb调试

执行结果

单步运行,可以看到do_execv函数

执行到start_thread查看入口地址

与readelf的结果一致

原文地址:https://www.cnblogs.com/huyufeng/p/5372598.html