链接学习之obj文件探索

Windows的gcc环境,往官网http://sourceforge.net/project/showfiles.php?group_id=2435 下载MinGW,安装,安装完毕后按照包

配置环境变量

   

a.在PATH的值中加入"C:\Program Files\MinGWStudio\MinGW\bin"。这是寻找gcc编译器的路径。如果PATH中还有其他内容,需要用英文状态下分号进行分割

b.新建LIBRARY_PATH变量,在其值中加入"C:\Program Files\MinGWStudio\MinGW\lib"。这是标准库存放的路径。

c.新建C_INCLUDE_PATH变量,在其值中加入"C:\Program Files\MinGWStudio\MinGW\include"。这是Include查找头文件的路径。

   

先是一个及其简单的C程序

Hello.c

   

预处理

C:\Users\居士\Desktop\Update\Link C>gcc -E hello.c -o hello.i

   

i文件局部

如上图#后面的数字 210代表行号 stdio.h中能找到对应代码

   

编译

C:\Users\居士\Desktop\Update\Link C>gcc -S hello.i -o hello.s

编译后的 内容仍然是文本,打开s文件仍然可以看懂其内容

学过汇编的人能看懂里面表达啥,对于我而言只认得pushl,movl,andl等几个指令,以及%ebp,%esp这几个寄存器,还有常数$-16,$0。其余cif_offset这些就需要百度才知道了。总体来说还是看不懂的。

   

   

汇编

C:\Users\居士\Desktop\Update\Link C>gcc -c hello.s -o hello.o

汇编得到的是一个二进制的文件,是一个可重定向目标文件,里面包含着机体代码。这里虽然表面上是一个o文件,由于本人使用的是Windows平台,编译出来的还是类似于通过VC编译出来的obj格式的文件,而并非Linux平台下的ELF文件。

在网上找的命令可以通过下面命令看到格式化后的o文件

C:\Users\居士\Desktop\Update\Link C>readelf -a hello.o

但是在windows下生成的实际上是obj文件,用VS的另一个工具可以打开,该工具在以下目录

D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe

命令为dumpbin /all {目标文件文件名} > {输出文件的文件名}

因此之前看书上面说的ELF文件的格式就对不上了,文件的结构需要找别的资料去参考。这里借助了dumpbin以外还使用了CFF Explorer。

   

obj文件内容分析

在网上看过别人分析的obj文件是用在VC下写的一段很简单的C++代码生成的,和我这个用MinGW的gcc下的C程序有出入。

总的来说无论是obj还是o文件,都是基于COFF(Common Object File Format)文件,它与我们平常写的代码不一样,它是有一个一定格式的文件,链接器(或加载器)则按照这个结构来链接(或执行)这些文件,先罗列一下整个obj文件的结构

   

File Header 文件头

Optional Header

Section Header Table 节头部表

Section Raw Data 节的原始数据

Relocation Table 重定向表

Symbol Table 符号表

String Table 字符串表

   

再看通过dumpbin生成的文件

   

FILE HEADER:文件头

这个文件头在obj文件中占了0~13共14个字节。

这个文件头的大小是固定的,它实际上是winnt.h里面的一个结构体。细心的可以发现结构中一些值是直接以数值的形式存放在文件中,例如machine的值14C,存放为4C 01,符号表的地址指针1B8,存放成B8 01。我想表达的是因为windows是采用了小段法存放数据的机器,高低位间作了互换。Winnt.h文件在C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include目录中(我的是64位系统)。结构体定义如下

各个字段的解析可以参考MSDN上的内容

结构体解析 https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms680313(v=vs.85).aspx

大体就是说了编译时机器的情况,时间,还有与本文件关系大的符号表的位置,符号的数量,optional header的数量。

   

接下来就是各个节的说明了,先已第一个节作为例子,介绍完这个节的结构后再通过CFF Explorer对比o文件里的内容。再去介绍各个节的作用。

这里包含了节的头部,节的原始数据,还有一个重定向表,节的头部是这样的一个结构

头部的作用是描述整个节的信息,例如SizeOfRawData代表原始数据的数量,PointerToRawData即是原始数据起始的地址。NumberOfRelocations是重定向条目的数量。

节头部数据结构详情可参考MSDN中的以下位置 https://msdn.microsoft.com/en-us/library/windows/desktop/ms680341(v=vs.85).aspx

Raw Data则是节的原始数据,这里其实没啥结构的,不同的节就存放他们对应的数据。

Relocations是重定位信息,实际上它是重定位表的一部分,只属于这个节的一部分。这个重定向的一个条目结构如下,

这个就是在链接时给引用外部的符号重定位时用的

   

以上仅是该o文件中最全的一个节的结构,当然还有可能会有其他的"节成员",只是当前这个C程序太简单,以致其他成员未出现。但是不是每个节都有原始数据,有些节是空的,有些节就不带重定向信息。

下面逐个看这个o文件里面的每个节。

第一个节是.text节,图不再截了,就之前的那个图,.text节存放的是已编译的机器代码。利用objdump工具可以看到这节的原始数据(也就是机器代码整理后的结果),命令如下

要看懂这些指令的话,还需要懂得处理器的指令集(参考《深入了解计算机系统》的第四章)。

第二节是是data节,按书上的介绍data节是存放已初始化的全局或静态C变量,这个C程序中没有用到全局变量或静态变量,这节就没有内容

第三节是bss节,是存放未初始化的全局或静态C变量,以及被初始化为0的全局或C变量,但是这个姐实际不占用控件

第四个节是rdata节,放的就是只读数据,这里存在了一个宏定义,"hello c!"这样的一个字符串,这部分数据就存放在这一节中

第五个节叫"/4",rdata$zzz估计是别名,不知具体的作用,貌似是存放了编译器的信息,版本之类的

第六个节叫"/15",eh_frame,更加不知道他的作用,貌似是有对.text节的引用,难道是调用main函数外层的东西?

节部分完结了之后就是符号表

符号表的介绍直接引用MSDN的内容

对于以符号号码开头的行,下列说明描述了含有与用户相关的信息的列:

  • 开头的 3 位数字是符号索引/号码。
  • 如果第三列包含 SECTx,则符号在对象文件的那一节中定义。 但如果出现 UNDEF,则它不在那个对象中定义并且必须在其他地方被解析。
  • 第五列 (Static, External) 说明符号是否只在那个对象的内部可见,或者是否是公共的(外部可见)。 静态符号 _sym 不会链接到公共符号 _sym;这些符号是名为 _sym 的函数的两种不同实例。

编号行中的最后一列是符号名(修饰名和未修饰名)

来自 <https://msdn.microsoft.com/zh-cn/library/b842y285.aspx>

   

每条符号表的记录是一下的结构

有几条记录是多出了一行的,那部分数据是对这个符号的补充说明,结构如下

在符号表之后就是字符串表了,但是在dumpbin生成d文件中只是列举了字符串表的大小

但在其他资料中介绍,字符串表示存放着节名的字符串。听过CFF Explorer中的内容查看,确实定义了4个字符川,就是重复的.rdata$zzz和.eh_frame

dumpbin如何分析得出这个o文件

那又有一个问题来了,编译系统是如何根据这份二进制的o文件来读取到这些信息呢,尝试一下通过CFF Explorer来分析读取到这个文件的信息,人为模拟一下dumpbin的工作。这个过程推导出前面那个obj文件结构这个结论。

首先是读取固定大小的文件头,通过文件头的结构获取到几个与本个o文件有关的信息:

  • 6个节
  • 符号表的起始位置是1B8,符号数量是12个

    那么就相当于把o文件已经分成了几块

文件头

未知部分1

符号表

未知部分2

0~13

14~1B7

1B8~??

??~329

那么节这部分有可能存放在未知部分1中。查看各个节的头部信息,分析出节1到节6是从104~18F。可以查看各个节的原始数据得出

   

其他节就不一一列举了

另外还有各个节头部信息中提及到的重定位信息,整个文件有中重定位信息只有两个节:节1的重定位是190开始;节6的重定位信息是1AE开始,节1的重定位项有3个,节6的重定位项有1个,粗略推断节1的重定位信息是重190~1AD,节6的重定位信息是1AE~1B7,每条重定位信息的长度大概是10个字节

是对应

0A 00估计对应Offset,10 00对应Symbol Index,14 00对应Type,可视Applied To这个就解析不清了,因为节6的重定位信息如下

还有字符串表的信息,字符串的大小是一个4字节用小端法存储的无符号整数,2E应该是2E 00 00 00,纵观整个文件存放了这个信息的就在位置为2FC处,因此估计字符串表是从2FC处到329结尾处了

文件头

未知部分1

节原始数据

重定向表

符号表

字符串表

0~13

14~103

104~18F

190~1B7

1B8~2FB

2FC~329

剩余的未知部分1应该就是存放节头部信息的节头部表,从14~103,也是通过数量以及数据的比对,节共有6个,此部分数据共240个,平均每个节头部信息占40个字节,下面就拿了40个字节的信息

可以看到节的名称.text 2E 74 65 78 74;原始数据的起始地址104,就是04 01 00 00;重定向表190,就是90 01 00 00,其他成员就不列举了。其他头部也不列举了。

最终得到的结构是

文件头

节头部表

姐原始数据

重定向表

符号表

字符串表

0~13

14~103

104~18F

190~1B7

1B8~2FB

2FC~329

再细分一下的就是

文件头

0~13

1头部

14~3B

2头部

3C~63

3头部

64~8B

4头部

8C~B3

5头部

B4~DB

6头部

DC~103

1原始数据

104~127

4原始数据

128~133

节5原始数据

134~157

节6原始数据

158~18F

1重定向表

190~1AD

6重定向表

1AE~1B7

符号表

1B8~2FB

字符串表

2FC~329

转载于:https://www.cnblogs.com/HopeGi/p/7549915.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/467642.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

http 请求默认时间_JMeter接口测试之HTTP请求默认值

不管是在UI级别的自动化测试还是在接口级别的自动化测试中&#xff0c;对公共数据数据的分离都是一种趋势&#xff0c;或者某种程度来说&#xff0c;这是自动化测试中必须要掌握的一种能力&#xff0c;是基本技能。这些公共数据就包含了测试地址&#xff0c;以及登录的账号密码…

有意思的select~

前言最近在写一个小程序&#xff0c;也就是简单的系统调用&#xff0c;但是神奇的是&#xff0c;我用的这个系统调用刚好就阻塞了。如果你也写过应用程序&#xff0c;肯定也会遇到过这样的问题。后来&#xff0c;发现了select这个好东西&#xff0c;可以用来监听文件描述。sele…

cesium 页面截图_Cesium开发入门篇 | 02开发环境搭建及第一个示例

开发环境准备利用Cesium API进行二次开发属于Web前端开发范畴&#xff0c;目前比较火的Web三剑客包括React、Vue、AngularJS&#xff0c;每个js库的详细介绍可转至官网查看&#xff0c;在此不做详细介绍。本次开发环境是基于Vue搭建的&#xff0c;需要安装(部署)的软件主要包括…

一个单片机ADC的挖坑填坑之旅

[导读] 本文来解析一个盆友在使用STM32采集电池电压踩过的坑。以STM32F4 的ADC属于逐次逼近SAR 型ADC为例进行分析&#xff0c;参考STM32F405xx Datasheet&#xff0c;对于如何编写ADC程序就不做描述了。先描述一下坑 采集电池电压&#xff0c;利用两个电阻将电池电压分压&…

of_property_read_string 剖析~

前言今天在一个群里面看到的一个朋友提交&#xff0c;说of_property_read_string 这个函数有两个定义&#xff0c;到底是用了哪个呢&#xff1f;所以这篇文章就说下这个函数。函数引用的头文件引用的头文件位置在\kernel-4.4\include\linux\of.h其中一个是extern int of_proper…

CPU频率和核心

设置CPU的核心数在/sys/devices/system/cpu目录下可以看到你的CPU有几个核心&#xff0c;如果是四核&#xff0c;就是cpu0&#xff0c;cpu1&#xff0c;cpu2,cpu3 4个文件夹。cpu0 常开。进一个其他文件夹&#xff0c;比如cpu1&#xff0c;里面有个online文件用cat命令查看该文…

关于“进程”与“线程”的最通俗解析

来源&#xff1a;电子工程专辑进程&#xff08;process&#xff09;和线程&#xff08;thread&#xff09;是操作系统的基本概念&#xff0c;但是它们比较抽象&#xff0c;不容易掌握。最近&#xff0c;我读到一篇材料&#xff0c;发现有一个很好的类比&#xff0c;可以把它们解…

要想选到音质好的耳机,你应该需要知道这些~

最近在一个音频公司调试我们设备的音频&#xff0c;从这次调试中&#xff0c;有所收获&#xff0c;希望这次的吹牛大家看完后&#xff0c;以后去买音频产品&#xff0c;可以分辨什么是好的&#xff0c;什么是不好的。有些产品硬件没有问题&#xff0c;但是产品经理因为个人喜好…

Fantasia (Tarjan+树形DP)

Time Limit: 1000 ms Memory Limit: 256 MB Description 给定一张N个点、M条边的无向图 $G$ 。每个点有个权值Wi。 我们定义 $G_i$ 为图 $G$ 中删除第 $i$ 号顶点后的图。我们想计算 $G_1, G_2, ..., G_n$ 这N张图的权值。 对于任意一张图 $G$ &#xff0c;它的权值是这样定义…

买书这件事

知识这种东西&#xff0c;你只有不断的补充才不会觉得匮乏&#xff0c;我每年都会买点书&#xff0c;我喜欢买书&#xff0c;但是却不看书&#xff0c;很多书籍我都是当成工具书来用。我记得在2015年的时候&#xff0c;我需要自己写专利&#xff0c;但是我对写专利这个事情一窍…

Linus Torvalds的最新电脑配置

大家好&#xff0c;祝大家6.1节日快乐最近Linus Torvalds 公布了他的电脑配置&#xff0c;有了这个配置清单之后&#xff0c;每个人都可以拥有一台和Linux之父一样的电脑&#xff0c;当你拥有了一台之后&#xff0c;你可以发个朋友圈&#xff0c;「我今天用Linus 的电脑解了一个…

马上就校招了,是要去实习还是复习?

昨天晚上&#xff0c;遇到一个特别纠结的同学&#xff0c;他现在收到一份实习的通知&#xff0c;他犹豫是要去实习呢还是继续在学校复习学习技术。实习的话可以增加自己校招的筹码&#xff0c;比如在和面试官侃大山的时候&#xff0c;可以把实习这件事情拿出来说&#xff0c;这…

嵌入式杂谈之makefile补充

我看了下自己的文章库存&#xff0c;好像还没有一篇关于Makefile的文章&#xff0c;所以这篇刚好可以弥补自己的缺失。makefile预定义变量预定义变量即系统自带的变量预定义变量作用AR库文件维护程序的名称&#xff0c;默认为arAS汇编程序的名称&#xff0c;默认为asCCc编译器的…

安卓9.0马达框架分析

前言最近需要将之前的一些驱动接口转为安卓标准接口&#xff0c;方便上层应用或者第三方应用去适配。这篇文章先从简单的马达框架入手进行讲解。正文整个马达框架比较简单&#xff0c;安卓官方已经帮我们实现了framework到HAL层&#xff0c;我们需要实现的就只有驱动层。这篇文…

PYQT4 Python GUI 编写与 打包.exe程序

工作中需要开发一个小工具&#xff0c;简单的UI界面可以很好的提高工具的实用性&#xff0c;由此开启了我的第一次GUI开发之旅&#xff0c;下面将自己学习的心得记录一下&#xff0c;也做为学习笔记吧&#xff01;&#xff01;&#xff01; 参考&#xff1a;http://www.qaulau.…

你知道嵌入式,那你看过这个吗?

大家好&#xff0c;因为最近各种原因&#xff0c;我身边的很多同事都转行摆地摊了&#xff0c;可能因为那是一份自由的职业&#xff0c;摆地摊可以从事的范围很广&#xff0c;也不用起早贪黑了&#xff0c;而且收入并不低。也是因为这样&#xff0c;很多嵌入式方面的岗位越来越…

mvc一对多模型表单的快速构建

功能需求描述 Q:在实际的开发中&#xff0c;经常会遇到一个模型中包含有多个条目的表单。如何将数据提交到后台&#xff1f; A: 以数组的形式提交到后台就Ok了(真的那么简单么&#xff0c;如果再嵌套一层呢&#xff1f;) A2&#xff1a;拆分多个模型&#xff0c;映射就没啥问题…

c语言中 if(x) 、if(0) 、if(1)

解释if 语句里面包含真和非真&#xff0c;但是如果我们没有写清楚真和非真的话&#xff0c;会如何呢&#xff1f;if(x)相当于if(x ! 0)如果是指针的话&#xff0c;相当于if(x ! NULL)而if(1)相当于if(1 ! 0)还有if(0)相当于if(0 ! 0)举个例子#include<stdio.h> int main(…

看Linus骂人,真解气

感受下Linus骂人的感觉吧&#xff0c; 这样你会觉得工作中遇到的那些不愉快就算个鸟事背景一个Linux主线的内核维护者提交了一份patch&#xff0c;并说明问题产生的原因是因为应用传的音频有问题。Linus回复如下你他娘的给老子闭嘴&#xff01;这是一个内核bug好不好&#xff0…

不就是要个30K的薪资,他还问我Nginx调优

我是一个运维“老鸟”&#xff0c;目前在到处找工作阶段。周三刚面试完一家公司&#xff0c;还是非常中意的公司。结果是我中意公司&#xff0c;公司不中意我&#xff0c;妥妥的黄了。面试完我才知道&#xff0c;Linux云计算工程师必须能精通20多个企业级服务器优化。我之前不是…