首页 > 编程知识 正文

c语言条件编译例子,c语言exe反编译工具

时间:2023-05-06 09:32:57 阅读:151315 作者:1315

gcc生成可执行文件的过程是生成:源文件*.c文件(对象文件(*.o文件) );

链接程序ld,将对象文件*.o文件链接到可执行程序。

因此,要完全理解链接的过程,必须了解目标文件*.o的组织方式。

用一个简单的例子来说明:吧

#includeint global_var=5; extern int other_file_var; int main () { int a=1;

int b=a other_file_var; 返回0;

}gcc -c test.c -o test.o生成test.o;

查看test.o内容(vim test.o ) :

图1

看到的是乱码的山。 由于观点错误,因此目标文件(*.o )必须为elf格式,并使用objdump、readelf工具进行查看,就像mp3格式的文件必须在音乐播放器中播放一样。

从elf格式的官方文档中,可以看出elf格式的文件结构如下图所示为:

图2

分析一下每一个部分吧。

1. ELF文件头(头)分析

显示readelf-htest.oelf文件的标头信息

主要字段的含义如图所示。

根据Size of this headers,头部占64字节;

在hexdump -n 64 test.o中查看头部64字节的数据内容(十六进制格式); 图中的红框数据作为test.o文件的前64个字节(即elf头部),与前两个图相比,(图1 )的魔数7f454c4602010100000000000正好是图2 )的前16个字节)短语代码

头部信息结构参照/usr/include/elf.h中的ELf64_Ehdr,32位的是ELf32_Ehdr结构typedefstruct{

unsignedchare_ident[EI_NIDENT]; /*Magicnumberandotherinfo*/

Elf64_Halfe_type; /*Objectfiletype*/

Elf64_Halfe_machine;/*架构* /

Elf64_Worde_version;/*对象文件版本* /

Elf64_Addre_entry; /*Entrypointvirtualaddress*/

Elf64_Offe_phoff;/* programheadertablefileoffset * /

Elf64_Offe_shoff;/* sectionheadertablefileoffset * /

Elf64_Worde_flags;/*处理器-特殊标志* /

Elf64_Halfe_ehsize; /*ELFheadersizeinbytes*/

Elf64_Halfe_phentsize;/* programheadertableentrysize * /

Elf64_Halfe_phnum;/* programheadertableentrycount * /

Elf64_Halfe_shentsize;/* sectionheadertableentrysize * /

Elf64_Halfe_shnum;/* sectionheadertableentrycount * /

Elf64_Halfe_shstrndx;/* sectionheaderstringtableindex */} El f64 _ ehdr; 根据Start Of Section Header字段,test.o文件的656个字节包含“段标题表”。

2. ELF段头表(Section Header )分析

当在readelf -S test.o中查看“段的开头表”时,该表保存了文件中所有段的属性信息,例如段的名称、段的文件的开始位置、段的长度等:

图4

从图中可以看出,主要字段的含义从图中识别出来。

段表中的数据与文件开头0x290处的ELF Header Start Of Section Header字段相匹配。

该段共有12项,不同项描述了不同段落的属性;

2.1文本段

text段距离test.o文件的开头0x40字节,长度为0x20字节。 在hexdump -s0x40 -n0x20 test.o中查看文本段的十六进制内容。

图5

objdump -d test.o打印程序的反汇编代码,

图6

从上面的两个图可以看出,text部分的数据正好是main函数的机器代码,即text段中保存的是代码段。

2.2数据段

data段距离test.o文件的开头0x60字节,长度为04字节。 使用hexdump -s0x60 -n0x4 test.o查看data段的十六进制内容。

图7

4字节正好是int的长度,其中保存的数值是5,也就是全局变量global_var的值,验证了初始化的全局变量保存在data段中。

2.3 bss段

2.4.Rela.text(text的重新定位段) )。

main函数中的global_var是在另一个文件中定义的,后面的链接必须根据另一个文件确定其虚拟内存地址。 包含. rela.text段,因为text具有需要重新定位的变量。 readelf -r test.o

图8

offset列表示需要重新定位的符号段内的偏移。 这里表示从text段0xd的偏移。

info列的前四个字节是. symtab符号的索引。 请参阅下图。

图9

2.5 .symtab符号表

图9

ndx列是段表中符号的索引。 (1)例如,global_var的索引是3,图4中的索引3表示数据段,

也就是说,global_var这个符号位于data段; )2) UND )的情况下,表示该符号被定义在其他文件中,需要重新配置。 再配置信息参考“2.4 .rela.text”。

图10

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。