Advertisement

windows平台下用elf作为目标文件格式

阅读量:

windows平台下用elf作为目标文件格式
------22:46 2008-10-8 ljhhh0123-

最近发现了两个C编译器工具:一个是Tiny C Compiler(基于ANSI-C),另一个是分别适用于Linux和Windows操作系统平台的版本。该编译器体积小巧且功能强大,在一定程度上继承了GNUCC的功能,并能够嵌入AT&T汇编指令。意外地发现该编译器生成的目标文件采用的是 elf(Relocatable) 格式,在Windows环境下最终生成的是独立的PE可执行文件,这一发现确实让人感到意外,请及时学习使用。我对符号 elf32_sym.st_shndx 取小于0值的意义以及 .rel.text 节的作用尚不理解。

附件为:test.zip.jpg 请去掉.jpg扩展名.

方法是:把test.o文件倾印下来边看资料边细分,并做注释.

工具:记事本程序+Hex Editor+IDA工具套件+若干elf格式学习资源(包括《elf_format.pdf》)+其他相关资源;软件:Tiny C Compiler v0.9.24版本(适用于Windows系统);作者:Fabrice Bellard

下载地址:
官网:http://bellard.org/tcc/

学习文件格式,就读二进制!

----开始----
7F454C46 01 01 01 000000000000000000 "/177ELF" 32位 little-endlian 版本1
0100 文件类型为可重定位文件
0300 i386
01000000 当前版本
00000000 入口的虚拟地址
00000000 程序头部表格的偏移量(没有即为0)
44020000 节区头部表格的偏移量
00000000 保存与文件相关的,特定于处理器标志
3400 elf头部大小(以字节计算)
0000 程序头部表格的表项大小
0000 程序头部表格的表项数目
2800 节区头部表格的表项大小
0800 节区头部表格的表项数目
0700 节区头部表格中与节区名称表相关的表项的索引
如果没有节区名称表,可为0.

--空隙(第0个节区)--
000000000000000000000000

----第一个节区 以 8D 字节对齐处理--
5589E581EC16 16 9 9 B4 51 C1 E8 2
8945F67F7B4D F7 B4 D7 B7 D8 B7
F3A5A822 F3A8 A2 F4 FC FF A A2
F3A8 F4FC FF FF A6A5 A822 F4FC FF
FFA6A5 A821 FF FF FCFF A4 DF CFC8 9DF
CFC7DFFC CF7DFFC
到此为止为 my_memcpy 函数的机器码, 大小共计为 4B 字节
...等数据

00000000000000000000000000000000
000000

----第二个节区0x14字节----
68656C6C6F20776F
726C64210A000000
00000000

--空隙--
000000000000000000000000

--第四个节区-0x90-符号表-
00000000000000000000000000000000 第一项为全0

字段 test.c 表示其名称对应于字符串表中的索引位置
字段 value 表示该值字段
字段 size 表示该长度字段
绑定属性字段 | 符号类型为STT_FILE(文件名)
字段 none 表示无特殊含义
字段 F1FF 表示有特殊的含义, 但目前尚不清楚具体内容: )

内存地址为12, 该标签标识为L..1/
在段落偏移量为2D的位置上定义了符号的取值位置
STB_LOCAL指令包含了高半字节局部符号, 并附加了对象类型信息于STT_OBJECT参数
位于.text节表中的特定条目

17000000 "L..2"
36000000 在节区偏移0x36的位置
00000000
01 STB_LOCAL + STT_OBJECT
00
0100

08000000 "my_memcpy"
00000000
4B000000 大小
12 绑定(全局) + 函数(STT_FUNC)
00
0100 在.text节区

1C000000 "buff"
00000000 在节区偏移0x0的位置
14000000 大小
11 全局(STB_GLOBAL)+对象(STT_OBJECT)
00
0200 .data节区

21000000 "buff2"
01000000
14000000 size
11 STB_GLOBAL | STT_OBJECT
00
F2FF 我不知此值的意义:)

27000000 "main"
4B000000
42000000 size
12 STB_GLOBAL | STT_OBJECT
00
0100

2C000000 "printf"
00000000
00000000
12 STB_GLOBAL | STT_FUNC
00
0000

--第五个节区-0x33-按四字节对齐--
00746573742E63006D795F6D656D6370
79004C2E2E31004C2E2E320062756666
006275666632006D61696E007072696E
746600

00

--第六个节区--0x48--
27000000020200003100000002030000
56000000010500005C00000002080000
6A000000010500007000000001060000
76000000020400007E00000001060000
8400000002080000

--第七个节区--0x36--
002E74657874002E64617461002E6273
73002E73796D746162002E7374727461
62002E72656C2E74657874002E736873
747274616200

0000 作填充之用

----节区头部表格8项----

Section Header 表示该字符在字符串中的位置索引
...
标志字段为零时表明该区域不活跃
后续字段无效

--第一个标记部分--
256 ".text字段名" 位于对应的索引位置,表示最后一个标记部分.

此节区存储着程序定义信息块。
该配置项SHF_ALLOC或SHF_EXECINSTR用于占用内存及可执行指令。

00000000 区域第一个字节应处的位置
40000000 区域的第一个字节与文件头部之间的偏移量
8D000000 区域长度
2888F5A1 64位区域头部表索引链接
6F7E79FF 附加信息
211D44E7 按32字节对齐处理
无项目。

--第二个--
07000000 ".data"
01000000 包含程序定义信息
03000000 可写和占用内存
00000000
E0000000 节区与文件头之间的偏移
14000000 长度
00000000
00000000
20000000 按32字节对齐
00000000

--第三个--
-bss区域起始地址为-bss
该段块不具备存储容量
该内存块可被赋值并分配内存空间
无长度字段
偏移量为-offset的位置
无长度字段

--第四个--
12000000 ".symtab"
02000000 节区类型为符号表 SHT_SYMTAB
00000000 未定义
00000000
00010000 同上个节起始位置一样,实际就是这个节起效用
90000000 长度
05000000 相关联的字符串节区头部索引
04000000 最后一个局部符号的索引值加1.
04000000 按四字节对齐
10000000

--第五个--
1A000000 ".strtab"
03000000 可写及给分配内存
00000000
00000000
90010000
33000000 长度
00000000
00000000
01000000
00000000

--第六个--
22000000 ".rel.text"
09000000
00000000
00000000
C4010000
48000000
04000000
01000000
04000000
08000000

-- 第七个(加上第\texttt{第} 个总共8个)--
2C,\texttt{.shstrtab}\quad表示包含字符串表字段\quad其中未定义值为无定义值\quad其余字段为空\quad其余字段为空\quad
偏移值为36C,长度为1F4C,剩余字段为空

-------------------------------------------
附录1:相关的数据结构格源码.
typedef __u32 Elf32_Addr;

typedef __u16 Elf32_Half;

typedef __u32 Elf32_Off;

typedef __s32 Elf32_Sword;

typedef struct elf32_hdr{
unsigned char E_ident[E_I_N_ident]; (注:容量为十六位)
Elf32_Half Elf_type;
Elf32_Half Elf_machine;
Elf32_Word Elf_version;
Elf32_Addr Elf_entry; /* 入口点 /
Elf32_Off Elf_phoff;
Elf32_Off Elf_shoff;
Elf32_Word Elf_flags;
Elf32_Half Elf_ehsize;
Elf32_Half Elf_phentsize;
Elf32_Half elf_phnum; (注:片内进程数目)
elf_shentsize; (注:片内函数数目)
elf_shnum; (注:片外进程数目)
elf_shstrndx); /
片外地址偏移 */
} elf_ Elf_ hdr;

该数据类型的别名定义为一个名为"Elf32_Shdr"的结构体。
结构体内包含以下字段:
- "elf_name": 类型为"Elf32_W"。
- "elf_type": 类型为"Elf32_W"。
- "elf_flags": 类型为"Elf32_W"。
- "elf_addr": 类型为"Elf32_Addr"。
- "elf_offset": 类型为"Elf32_Off"。
- "elf_size": 类型为"Elf32_W"。
- "elf_link": 类型为"Elf32_W"。
- "elf_info": 类型为"Elf32_W"。
- "elf_addralign": 类型为"Elf32_W"。
- "elf_entsize": 类型为"Elf32_W"

redefining a structure named Elf32_Sym{
Efl_Word member names and their types.
Efl_Address associated data fields.
Efl_Wdt member size specifications.
unsigned char additional metadata fields.
unsigned char other supplementary information.
Efl_Half indexed references.
}

/test.c/
#include <stdio.h>
void * my_memcpy(void * to, const void * from, size_t n)
{
int d0, d1, d2;
asm volatile(
"rep ; movsl/n/t"
"testb 2,%b4/n/t" "je 1f/n/t" "movsw/n" "1:/ttestb 1,%b4/n/t"
"je 2f/n/t"
"movsb/n"
"2:"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
:"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
: "memory");
return (to);
}
char buff[20]="hello world!/n/0";
char buff2[20];
void main(void){
printf(buff);
my_memcpy(buff2, buff, 20);
printf(buff2);
}

----本文完毕------

全部评论 (0)

还没有任何评论哟~