任何手动练习,以了解如何将程序加载到内存中并执行

我很好奇在main()被调用之前发生的事情,比如将可执行文件加载到内存中,共享库的dynamic加载。 你有什么build议如何通过亲身实践来了解这些事情?

我知道的工具和现在使用的工具包括:

  • strace的
  • 拆卸
  • readelf
  • / proc /进程/图

注意:我知道这本好书的连接器和装载机 ,但实际操作可能比阅读本书更能教会我。

  • ld.so 手册页记录了几个环境变量,这些变量可以设置为调整动态链接过程或提供更多的细节。

例如

LD_DEBUG=all cat </dev/null 
  • 你可以很容易地获得所涉及的每个部分的源代码 – Linux内核,动态链接器,C库,启动代码(crt0.o或类似的)。 您可以从研究代码开始并进行实验性修改。

如果你想检查一个二进制文件是如何打包的,那么我认为最好的程序是objdump 。

选择任何可执行文件并执行

 objdump -S <executable> > myfile.S 

另一个好的练习是:

  • 创建一个使用外部库的程序
  • 使用静态链接编译程序
  • 运行程序
  • 重命名库文件并检查程序是否运行
  • 使用共享库编译程序
  • 重命名该库并检查程序是否运行

这将回答你的一些问题,关于在窗帘下面发生了什么,以及如何。

我发现了两个有趣的相关链接(至少对于Linux),比上面提到的书(链接器和装载器)略短一些。

当我在大学上课时,我们使用了墨西哥玉米片 。 它本身不是一个操作系统,而是一种在用户空间运行的操作系统“模拟”。 它是用C ++编写的,你可以交叉编译Nachos可以加载和运行的可执行文件。 您可以使用系统调用界面进行操作,并且可以随意使用代码进行一般的实验。

我们在Solaris实验室中运行它,在我的个人计算机上在Linux上运行时遇到了一些麻烦,但如果您愿意深入研究一些代码,它可能是一个有趣的玩具。

我意识到,这可能是很多你正在寻找,但编写自己的汇编器和连接器将是非常教育。 当我上大学的时候,我做到了,爱上了它。 我想起来,花了120个小时的时间,让它为我想做的基本事情工作。 我认为这个项目比任何事情都重要,这使我确信在编程方面的职业生涯对我来说是。