0x00 概论
因为TI的DSP输出文件与传统的ELF文件不符,所以本人就顺道研究了一下现在的ELF的文件格式。
会将其陆续完成在文章中。
阅读本文之前,您需要掌握的技能有:
技能名称 | 技能熟练度 | 技能教程链接 |
---|---|---|
C语言 | 了解 | 暂无 |
0x10 ELF文件介绍与说明
ELF文件是一种跨平台的可执行文件,主要是用于对于不同的文件格式进行统一。几乎能够满足除了windows意外所有的平台进行读取。
一个完整的ELF主要包括以下几个部分:
对轻度使用者(旨在编译完成后查看数据段的排列与分布是否争取,但是还不如去看link输出的map文件)而言,真正需要的数据也就是程序段头表、段属性表、区域头表。但是如果你是IDE、debug开发者,可能就需要对调试数据区域、标号表的数据有较为全面的了解。
0x20 数据格式定义
起始位置仅在文件头,文件会使用ELF
进行标注,以告知软件其为ELF文件的结果。
读取的时候就可以使用文件头判断当前文件是否为ELF文件,而elf文件存在32位和64位的类型,其中基本上只存在与编码格式的区别:
32位软件定义 | 长度 | 说明 |
---|---|---|
Elf32_Addr | 4 | 无符号程序指令 |
Elf32_Half | 2 | 无符号中等定义的整形数据 |
Elf32_Offest | 4 | 无符号文件位置指针 |
Elf32_SWord | 4 | 有符号标准整形数据 |
Elf32_Word | 4 | 无符号标准整形数据 |
Elf32_Char | 1 | 无符号短整形 |
而64位的基本上都会比32位长一倍,但是char还是基本的1byte。
64位软件定义 | 长度 | 说明 |
---|---|---|
Elf64_Addr | 8 | 无符号程序指令 |
Elf64_Offest | 8 | 无符号文件位置指针 |
Elf64_Sxword | 8 | 有符号长整形 |
Elf64_Xword | 8 | 无符号长整形 |
Elf64_Sword | 4 | 有符号标准整形数据 |
Elf64_Word | 4 | 无符号标准整形数据 |
Elf64_Half | 2 | 无符号中等定义的整形数据 |
Elf64_Char | 1 | 无符号短整形 |
0x20 文件定义
软件定义直接存在初始化的位置,而排列基本如下
其中,特殊数据码部分虽然可以随便定义,比如找一个修改的软件,然后把开头改成这样:
但是基础是你的解析软件支持这个解析的方式,否则就是大型车祸现场:
0x30 解析文件
解析的话也是很简单,因为数据就在最前面,所以直接使用下面这个结构体套进去就可以。
软件定义 | 数据类型 | 数据个数 | 数据解释 |
---|---|---|---|
identification | Elf32_Char | 16 | 文件的身份码,可以自定义,用于校验 |
type | Elf32_Half | 1 | 对于文件的辅助判断码,有自有的定义 |
Machine | Elf32_Half | 1 | 文件对应的机器码,基本是协议编码固定的 |
Version | Elf32_Word | 1 | 文件版本 |
Entry | Elf32_Addr | 1 | 真实的软件入口 |
Program Header Offest | Elf32_Offest | 1 | 软件程序头表相对于文件的偏移位置 |
Section Header Offest | Elf32_Offest | 1 | 段头表相对于文件的偏移位置 |
Flags | Elf32_Word | 1 | 标志位,与Machine正相关 |
ELF Header Size | Elf32_Half | 1 | 文件头的长度 |
Program Header Size | Elf32_Half | 1 | 程序头表数据段的单段基础标准数据长度 |
Program Header Number | Elf32_Half | 1 | 程序头表数据段个数 |
Section Header Size | Elf32_Half | 1 | 段头部的数据段单段基础标准数据长度 |
Section Header Number | Elf32_Half | 1 | 段表的数据段个数 |
String & Section Index | Elf32_Half | 1 | 字符串和段表的个数 |
这个表的定义我也已经在之前的图片上将其一一指出了。
identification数据虽说没有严格的定义,但是还是有数据的排列规范的。
文件定义 | 文件偏移 | 解释 |
---|---|---|
Ident Megic Code 0 | 0 | 文件标识0 |
Ident Megic Code 1 | 1 | 文件标识1 |
Ident Megic Code 2 | 2 | 文件标识2 |
Ident Megic Code 3 | 3 | 文件标识3 |
Ident Class | 4 | 标识类 |
Ident Data | 5 | 标识数据 |
Ident Version | 6 | 标识版本 |
OS Code | 7 | 操作系统类型的编码 |
ABI(Application Binary Interface) version | 8 | ABI接口版本 |
Ident Pad | 9 | 填充标识位置 |
Ident number ident buffer | 16 | 标识空间长度 |
上面就是这16位文件的长度的定义了,但是从上面可以看出有很多的数据都是可以重新定义的。
数据的长度一般为16位,但是32位的文件仅有11个byte被使用了,而其他的数据都是可以修改的,还有4个数据段是关于文件定义的数据,Version、Class、Data都是自己可以确认并且全部写死,所以一共有12个数据可以自定义,巧了!GreenDreamer
也有12个数据,就可以直接写到里面了(自己的文章就是要硬核广告植入~~),最后的结果就像是前文的图片上的效果了。
而如果需要进行软件的版权声明也可以在这个文件内部进行一些修改,来完成隐式的版权插入。
至于其中的Machine、Version、Class、Data,他们的定义如下:
0x31 Machine
此为芯片类型的定义
#define EM_NONE 0 /* No machine */
#define EM_M32 1 /* AT&T WE 32100 */
#define EM_SPARC 2 /* SUN SPARC */
#define EM_386 3 /* Intel 80386 */
#define EM_68K 4 /* Motorola m68k family */
#define EM_88K 5 /* Motorola m88k family */
#define EM_486 6 /* Intel 80486 */
#define EM_860 7 /* Intel 80860 */
#define EM_MIPS 8 /* MIPS R3000 (officially, big-endian only) */
#define EM_S370 9 /* IBM System/370 */
#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian (Oct 4 1999 Draft) Deprecated */
#define EM_res011 11 /* Reserved */
#define EM_res014 14 /* Reserved */
#define EM_PARISC 15 /* HPPA */
#define EM_res016 16 /* Reserved */
#define EM_VPP550 17 /* Fujitsu VPP500 */
#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
#define EM_960 19 /* Intel 80960 */
#define EM_PPC 20 /* PowerPC */
#define EM_PPC64 21 /* 64-bit PowerPC */
#define EM_S390 22 /* IBM S/390 */
#define EM_SPU 23 /* Sony/Toshiba/IBM SPU */
#define EM_res024 24 /* Reserved */
#define EM_res035 35 /* Reserved */
#define EM_V800 36 /* NEC V800 series */
#define EM_FR20 37 /* Fujitsu FR20 */
#define EM_RH32 38 /* TRW RH32 */
#define EM_MCORE 39 /* Motorola M*Core */ /* May also be taken by Fujitsu MMA */
#define EM_RCE 39 /* Old name for MCore */
#define EM_ARM 40 /* ARM */
#define EM_OLD_ALPHA 41 /* Digital Alpha */
#define EM_SH 42 /* Renesas (formerly Hitachi) / SuperH SH */
#define EM_SPARCV9 43 /* SPARC v9 64-bit */
#define EM_TRICORE 44 /* Siemens Tricore embedded processor */
#define EM_ARC 45 /* ARC Cores */
#define EM_H8_300 46 /* Renesas (formerly Hitachi) H8/300 */
#define EM_H8_300H 47 /* Renesas (formerly Hitachi) H8/300H */
#define EM_H8S 48 /* Renesas (formerly Hitachi) H8S */
#define EM_H8_500 49 /* Renesas (formerly Hitachi) H8/500 */
#define EM_IA_64 50 /* Intel IA-64 Processor */
#define EM_MIPS_X 51 /* Stanford MIPS-X */
#define EM_COLDFIRE 52 /* Motorola Coldfire */
#define EM_68HC12 53 /* Motorola M68HC12 */
#define EM_MMA 54 /* Fujitsu Multimedia Accelerator */
#define EM_PCP 55 /* Siemens PCP */
#define EM_NCPU 56 /* Sony nCPU embedded RISC processor */
#define EM_NDR1 57 /* Denso NDR1 microprocessor */
#define EM_STARCORE 58 /* Motorola Star*Core processor */
#define EM_ME16 59 /* Toyota ME16 processor */
#define EM_ST100 60 /* STMicroelectronics ST100 processor */
#define EM_TINYJ 61 /* Advanced Logic Corp. TinyJ embedded processor */
#define EM_X86_64 62 /* Advanced Micro Devices X86-64 processor */
#define EM_PDSP 63 /* Sony DSP Processor */
#define EM_PDP10 64 /* Digital Equipment Corp. PDP-10 */
#define EM_PDP11 65 /* Digital Equipment Corp. PDP-11 */
#define EM_FX66 66 /* Siemens FX66 microcontroller */
#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 bit microcontroller */
#define EM_ST7 68 /* STMicroelectronics ST7 8-bit microcontroller */
#define EM_68HC16 69 /* Motorola MC68HC16 Microcontroller */
#define EM_68HC11 70 /* Motorola MC68HC11 Microcontroller */
#define EM_68HC08 71 /* Motorola MC68HC08 Microcontroller */
#define EM_68HC05 72 /* Motorola MC68HC05 Microcontroller */
#define EM_SVX 73 /* Silicon Graphics SVx */
#define EM_ST19 74 /* STMicroelectronics ST19 8-bit cpu */
#define EM_VAX 75 /* Digital VAX */
#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded cpu */
#define EM_FIREPATH 78 /* Element 14 64-bit DSP processor */
#define EM_ZSP 79 /* LSI Logic's 16-bit DSP processor */
#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
#define EM_HUANY 81 /* Harvard's machine-independent format */
#define EM_PRISM 82 /* SiTera Prism */
#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
#define EM_FR30 84 /* Fujitsu FR30 */
#define EM_D10V 85 /* Mitsubishi D10V */
#define EM_D30V 86 /* Mitsubishi D30V */
#define EM_V850 87 /* Renesas V850 (formerly NEC V850) */
#define EM_M32R 88 /* Renesas M32R (formerly Mitsubishi M32R) */
#define EM_MN10300 89 /* Matsushita MN10300 */
#define EM_MN10200 90 /* Matsushita MN10200 */
#define EM_PJ 91 /* picoJava */
#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
#define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */
#define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor */
#define EM_NS32K 97 /* National Semiconductor 32000 series */
#define EM_TPC 98 /* Tenor Network TPC processor */
#define EM_SNP1K 99 /* Trebia SNP 1000 processor */
#define EM_ST200 100 /* STMicroelectronics ST200 microcontroller */
#define EM_IP2K 101 /* Ubicom IP2022 micro controller */
#define EM_MAX 102 /* MAX Processor */
#define EM_CR 103 /* National Semiconductor CompactRISC */
#define EM_F2MC16 104 /* Fujitsu F2MC16 */
#define EM_MSP430 105 /* TI msp430 micro controller */
#define EM_BLACKFIN 106 /* ADI Blackfin */
#define EM_SE_C33 107 /* S1C33 Family of Seiko Epson processors */
#define EM_SEP 108 /* Sharp embedded microprocessor */
#define EM_ARCA 109 /* Arca RISC Microprocessor */
#define EM_UNICORE 110 /* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */
#define EM_EXCESS 111 /* eXcess: 16/32/64-bit configurable embedded CPU */
#define EM_DXP 112 /* Icera Semiconductor Inc. Deep Execution Processor */
#define EM_ALTERA_NIOS2 113 /* Altera Nios II soft-core processor */
#define EM_CRX 114 /* National Semiconductor CRX */
#define EM_XGATE 115 /* Motorola XGATE embedded processor */
#define EM_C166 116 /* Infineon C16x/XC16x processor */
#define EM_M16C 117 /* Renesas M16C series microprocessors */
#define EM_DSPIC30F 118 /* Microchip Technology dsPIC30F Digital Signal Controller */
#define EM_CE 119 /* Freescale Communication Engine RISC core */
#define EM_M32C 120 /* Renesas M32C series microprocessors */
#define EM_res121 121 /* Reserved */
#define EM_res130 130 /* Reserved */
#define EM_TSK3000 131 /* Altium TSK3000 core */
#define EM_RS08 132 /* Freescale RS08 embedded processor */
#define EM_res133 133 /* Reserved */
#define EM_ECOG2 134 /* Cyan Technology eCOG2 microprocessor */
#define EM_SCORE 135 /* Sunplus Score */
#define EM_SCORE7 135 /* Sunplus S+core7 RISC processor */
#define EM_DSP24 136 /* New Japan Radio (NJR) 24-bit DSP Processor */
#define EM_VIDEOCORE3 137 /* Broadcom VideoCore III processor */
#define EM_LATTICEMICO32 138 /* RISC processor for Lattice FPGA architecture */
#define EM_SE_C17 139 /* Seiko Epson C17 family */
#define EM_TI_C6000 140 /* Texas Instruments TMS320C6000 DSP family */
#define EM_TI_C2000 141 /* Texas Instruments TMS320C2000 DSP family */
#define EM_TI_C5500 142 /* Texas Instruments TMS320C55x DSP family */
#define EM_res143 143 /* Reserved */
#define EM_res159 159 /* Reserved */
#define EM_MMDSP_PLUS 160 /* STMicroelectronics 64bit VLIW Data Signal Processor */
#define EM_CYPRESS_M8C 161 /* Cypress M8C microprocessor */
#define EM_R32C 162 /* Renesas R32C series microprocessors */
#define EM_TRIMEDIA 163 /* NXP Semiconductors TriMedia architecture family */
#define EM_QDSP6 164 /* QUALCOMM DSP6 Processor */
#define EM_8051 165 /* Intel 8051 and variants */
#define EM_STXP7X 166 /* STMicroelectronics STxP7x family */
#define EM_NDS32 167 /* Andes Technology compact code size embedded RISC processor family */
#define EM_ECOG1 168 /* Cyan Technology eCOG1X family */
#define EM_ECOG1X 168 /* Cyan Technology eCOG1X family */
#define EM_MAXQ30 169 /* Dallas Semiconductor MAXQ30 Core Micro-controllers */
#define EM_XIMO16 170 /* New Japan Radio (NJR) 16-bit DSP Processor */
#define EM_MANIK 171 /* M2000 Reconfigurable RISC Microprocessor */
#define EM_CRAYNV2 172 /* Cray Inc. NV2 vector architecture */
#define EM_RX 173 /* Renesas RX family */
#define EM_METAG 174 /* Imagination Technologies Meta processor architecture */
#define EM_MCST_ELBRUS 175 /* MCST Elbrus general purpose hardware architecture */
#define EM_ECOG16 176 /* Cyan Technology eCOG16 family */
#define EM_CR16 177 /* National Semiconductor CompactRISC 16-bit processor */
#define EM_ETPU 178 /* Freescale Extended Time Processing Unit */
#define EM_SLE9X 179 /* Infineon Technologies SLE9X core */
#define EM_L1OM 180 /* Intel L1OM */
#define EM_K1OM 181 /* Intel K1OM */
#define EM_INTEL182 182 /* Reserved by Intel */
#define EM_AARCH64 183 /* ARM 64-bit architecture */
#define EM_ARM184 184 /* Reserved by ARM */
#define EM_AVR32 185 /* Atmel Corporation 32-bit microprocessor family */
#define EM_STM8 186 /* STMicroeletronics STM8 8-bit microcontroller */
#define EM_TILE64 187 /* Tilera TILE64 multicore architecture family */
#define EM_TILEPRO 188 /* Tilera TILEPro multicore architecture family */
#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze 32-bit RISC soft processor core */
#define EM_CUDA 190 /* NVIDIA CUDA architecture */
#define EM_TILEGX 191 /* Tilera TILE-Gx multicore architecture family */
#define EM_RL78 197 /* Renesas RL78 family. */
#define EM_78K0R 199 /* Renesas 78K0R. */
#define EM_INTEL205 205 /* Reserved by Intel */
#define EM_INTEL209 209 /* Reserved by Intel */
原本想向上面一样准备好一个表格,结果发现是真的多,所以就放弃了……直接贴源码过来
上面的机器码定义应该是最新的协议收录机器码了。其中没有使用的区间被我直接删去了,但是两端的没有使用的数据都是留下来的。
当然,本人至今不知道TI的16位系列的DSP内核构架的文件为啥不将自己的芯片模型写入这个文件解析协议中……可能是TI公司没有考虑?(GNU组织的PY交易没有完成)不过其公司也有一套自己的工具链也倒是可以使用但是文档就比较难找……总之如果是TI ROM最小单元为16位的DSP芯片是没有办法使用这套文件协议的。需要特殊的修改进行识别。
PS:谢谢TI公司让我需要强行的了解ELF文件格式,谢谢。
0x32 Class
此为文件格式的定义,文件格式现有的版本为32和64位。
数据定义 | 数据值 | 数据含义 |
---|---|---|
未定的数据格式 | 0 | 未定的格式 |
32位版本格式 | 1 | 32位的目标格式 |
64位版本格式 | 2 | 64位的目标格式 |
0x33 Data
此为数据排列的方式,主要为大端与小端的排序。
数据定义 | 数据值 | 数据含义 |
---|---|---|
未定义的数据解析 | 0 | 未定义的数据解析 |
小段模式的数据解析 | 1 | 传统的小端模式 |
大端模式的数据解析 | 2 | 传统的大端模式 |
0x34 Version
此为版本相关的参数。感觉这个参数就是用来显示的,因为源代码中似乎只是在最后转换的时候进行了一丝处理
数据定义 | 数据值 | 数据含义 |
---|---|---|
未定版本 | 0 | 未定的版本数据 |
当前版本 | 1 | 正在定义的已知版本 |
0x40 致谢!
本文的一切数据基础很大程度上参考了https://refspecs.linuxbase.org/elf/elf.pdf内的数据结构与GNU-Until的源码,这些文档是本文写就的基础,如果英语能力较好的朋友可以直接查看此PDF文件并辅以本文进行观看,对此作者与历史上的所有我不知道名字的维护者表示崇高的敬意!
PS:本人经过阅读源代码发现,现有的源代码中的数据相较于手册简直查了不是一星半点,所以完全详细解析的还是需要借助本文进行查看
PPS:不知道为啥,感觉GNU-Until的代码就是像随便写的,一点条理都没有……头又秃了1%
更多
本文首发自 记:ELF文件解析初定义——文件头解析,更多文章可进入我的博客详查。