`
wsql
  • 浏览: 11786119 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

GeekOS之旅-Project1 (Parse an ELF executable Files) 与 ELF 文件格式的浅析

 
阅读更多

想知道这个Project的Assignment之前,我们首先需要把这个Project编译过并把bochs启动起来. 编译和前一个Project一样很快通过.但是bochs启动遇到一个错误

看了下 .boshrc 中有这样一句: 10 diskc: file=diskc.img, cyl=40, heads=8, spt=64

看了下刚才编译过的project1里面有个disk.img ,这个diskc.img是什么呢? 其实diskc.img是个硬盘映像,我们之所以要加载这个是因为我们下面肯定会用到. 所谓映像是原始设备的对应字节. 所以需要在.bochrc中配置 disk.img.

再.boshrc添加如下

这句话就是制定硬盘参数,type为(disk,cdrom) mode(flat<一个文件布局>, concat<多文件布局>, external, dll ....), path就是路径了, cylinders为柱面大小, heads为头部大小,spt为每磁道扇区数

这么一解释,也就清楚多了. 好加上去,并把 第10行注释掉. 然后启动.


启动成功! 可以看到这个Project的Assigment:Parse an ELF executable image.

仔细阅读附带的手册Project2 的 Required Reading 和Synopsis . 主要任务是实现 src/geekos/elf.c 的Parse_ELF_Executable() 这个函数. 函数的功能是读取ELF文件中的offset, length, user address for the executable's text and data segments . 然后fill in the Exe_Format中!

所以我们首先要进行了解ELF格式的文件. 分析的样本用 project1 user下提供的a.exe , 这个源码在 src/user下a.c .

可以从google中搜索 Elf format file来进行了解.这里 可以我们也可以探讨下ELF 文件:

-> ELF是Linux默认的可执行文件格式, ELF包含三种类型:可重定位的文件(比如.o 目标文件), 共享文件 , 可执行文件. ELF文件包含 ELF Header, Sections ,String Table , Symbol Table, Relocation(Relocation Types) 这几个重要的部分. 让我们大概来看下ELF文件的组织图.


上面第一个为连接视图, 第二个为执行视图, ELF header(ELF 头部) , Program header table(程序头表), Section header table(节头表)

我们从ELF头部的数据结构开始看起, 打开geekos/elf.c 看下面这个结构体

里面的相关信息 我已经注释上去了. 我们接着用readelf -h工具查看下a.exe文件 来对照着看下

可以对照的看下, 下面再研究 程序头表,继续看下它的结构体:

再用readelf -l 来看下a.exe的信息.

ELF深入可以看文档 看资料. 等提到ELF问题时 我们再来深入一下.

来做第一步 研究下Parse_ELF_Executable的原型.

exeFileData: 这个buffer包含了可执行的文件 也就是ELF文件.

exeFileLength: 这个是执行文件的长度

exeFormat: 这个结构体包含了文件的段和入口地址

返回值为int: ret返回0为成功

解析了elfHeader 和 ProgramHeader这两个结构体 剩下的就很轻松了, 分别用这两个结构体解析exeFileData的内容

exeFileData头部的指向肯定是从elfHeader开始的 因为之前我们已经分析过了,然后自带poff的属性 这是程序头部的偏移量,首地址+poff就可以得出programHeader的首地址了.

再继续看Exe_Format这个结构体.


segmentList是个段的数组.

numSegments是段的数目

entryAddr是入口地址.

其中numSegments就是 elfHeader中的phnum, entryAddr是 elfHeader 的entry

segmentList因为是个数组,但是里面的每个元素是个结构体 我们先搞清这个结构体的内容:


稍微思考下, 这些不就是programHeader的offset, fileSize, vaddr, memSize, flags 嘛

ok一切准备就绪,就剩下苦力把程序写上去了.


整个程序如上,需要注意的是 return 0; 别忘了放进去.
测试结果如下:


下面继续 Project 2.!


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics