在windows下c语言编程的过程中,你有没有好奇过obj文件的格式呢?以及后续的 静态库,动态链接库.lib文件的格式,在这里我将带领大家 做一下 力所能及的简单分析,
在此过程中做好以下准备工作:
1.用VS创建一个工程:
该工程除了自带的一个stdafx.cpp文件之外,就是我自己创建的一个简单cpp文件了,环境截图如下
2.编译生成一个obj文件,我的cpp文件叫obj1.cpp,那么生成的obj文件就是obj1.obj了
3.来到VS默认安装时时生成的路径C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin ,搜索dumpbin.exe这是我第一次分析obj文件时用的工具,
我是通过 《程序员的自我修养》这本书,从而有了分析 obj文件的念头的,而且这本书做了很多有用的工作,虽然是那么的晦涩,但是我相信,大家在不断的阅读时
总会有自己的收获的,但是要记得取舍啊。。。
接下来,设置系统环境变量,path路径下添加 ;C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin (注意这是我这里的路径,你那儿情况可能不一样)
之后来到相应的obj文件目录,不选中任何项目,空白处按下shift键 同时点下鼠标右键,选择在 “此处打开命令行窗口” ,在cmd窗口中输入dumpbin
出现以上,说明path变量配置成功了,接下来输入,dumpbin /all obj1.obj > obj1.txt,在目录下生成一个txt文件,
打开观察
以上即是该工具对obj文件的解析,那么obj文件是什么呢?我们百度搜索一下,可以得到coff文件格式的头绪
以下链接是百度百科对coff文件格式的说明
http://baike.baidu.com/link?url=gnEyune8QQwzoa_XN13cvXM_ERTwM1F_SimFEp8yIelJGnP5tkkWLXSayoT0fWSrjzi2zAzrxUZL-Mb2NqsPfK
4准备相应的文件,工具
下图截自上述链接中,
4.1 Winnt.h头文件
上述只是形象的描述了一下,我们需要精确的数据结构,我这里用的是VS2013, 我可以在IDE中直接打开winnt.h头文件,也就是说我们需要一个winnt.h文件
来查询相关的结构体
4.2 16进制工具,010editor,hex editor,hex workshop均可以,将obj文件加载拖进去, 我们对照着
Winnt.h文件中相关的结构体,16进制工具,刚才dumpbin 生成的 obj1.txt文件,我们三者结合起来分析
5.分析
对照着obj1.txt文件逐段分析
FILE HEADER:
上附链接并没有说明FILE HEADER 结构体的 名称,只是给出了相应字段说明,其实我在这里提前透题吧,它对应的是Winnt.h头文件中的IMAGE_FILE_HEADER结构体
详细的你可以参考百度百科的说明,另外,获取你可以去获取一下 微软官网 的 coff文档说明,这里SizeOfOptionalHeader在obj文件,以及.lib文件都是0,在PE文件格式中非0
这点在你研究PE文件格式之前只需要记住就可以
接着我打开 Hex Editor 了
在这里你要注意的是X86平台的 小端字节序
当一个字段大于1BYTE 时,如Machine 字段,Hex Editor显示的是 4C 01,(地址从低到高)
而人类书写的格式 则是 0X014C ,这就是小端字节序的问题,上图贴图,读者可以自己数着指头戳着看了~,
OPTIONAL HEADER
由于之前提及到的在obj文件中optional header 大小为0,所以此段没有了
SECTION HEADER
这个结构体的名字 叫 Winnt.h/IMAGE_SECTIN_HEADER
#节1
一个程序的简单说明的周期 : 编写 》 编译 》链接 》 运行,上述红线框中的 字段跟 行号,链接时重定位表(注意运行时重定位和 链接时的重定位 是两回事)
链接时的重定位,是将各个obj文件对其他obj文件函数引用的处理, 运行时重定位是 由于 加载模块基址 和模块默认基址 不一样时的处理,链接重定位你可以参考《程序员的自我修养》,运行时的重定位的事情等到你分析 PE文件格式的时候再去想吧
(该段后面有个Linker Directive 提示说明是编译器通过这个obj文件传给链接器 的指示)
#节2
#节3
这里由于程序是Debug编译的,则该节显示了相关PDB文件(用于调试,显示符号名称的文件,也可手工分析) 目前前三个节都没有 行号项 和 重定位 项
#4
至于第一个是什么,我可以告诉你是
这个字符串的等价物,为什么等等看后面的符号表,
该节有4个重定位项。这4个重定位有不同的类型Type,在obj文件中相应处用00填充,等到链接完成后该处数字会发生改变
链接时重定位结构体
#5
最后了,符号表
符号表的数据结构
上上截图中显示符号,可序号为什么是断断续续的呢?一般来说应该是连续的啊?
我可以这样回答你的问题,看见上述结构体的最后一个字段吗? 辅助符号项的个数,
主符号项加上 辅助符号项 刚好每一行表示其中一类型的一项,只不过 主项显示序号
符号项字段的解析你可以在网上去搜搜,我在这里就不写了,晚上没精力了~
接下来就是字符串表了
最后:
文件布局: