记:COFF文件下的解析说明

0x00 序言

本文是因为当前的COFF文件中对于当前的芯片的软件构建,COFF本身是在很久以前的文件了,所以现在在互联网上的资料极少,且当年的COFF文件主要是在替换a.out文件格式,也就是对其的可扩展性增加。而ELF也是对于其的增加,COFF就被夹在了中间,所以这份COFF文档会和我的ELF解析差不多。

而因为COFF已经是上个世纪的不需要太对兼容负责的程序格式了,所以自然也就是直接淘汰在现在的执行序列里面了,除了固定的一些应用场景,已经越来越少看到这类文件了。

而且现在的解析器也越来越少,所以很多软件都已经是定制性的。

因为遇到了TI 的CCS文件的操作,所以准备在这里叙述一下COFF文件的结构。

笔者现在能找到的就是Linux系列的文件介绍与TI的自定义的COFF文件格式。

需要说明的是,两者比起来,TI的文件更像是前者的简化自定义版,所以这里主要介绍Linux的文件介绍。

阅读本文之前,您需要掌握的技能有:

技能名称技能熟练度技能教程链接
C语言熟悉暂无

0x10 文件头说明

COFF与ELF相比,更像是一个阉割版的ELF文件,但是麻雀虽小五脏俱全。

一个标准的文件头包括了以下几个大部分:

  • 文件头硬编码
  • 文件头的信息说明
  • 字符串头
  • 未定义的段定义数据
  • 重定向的段数据信息
  • 标签与相关的字符串

0x11 头文件硬编码

一个严谨的文件格式肯定会定义第一个专属的文件识别编码。也就是真正意义上的文件头。

COFF的文件头规定了其文件的段个数、生成时间戳、各个区块的入口与文件的针对性的芯片与指令。

位置格式定义说明称呼
0-1unsigned short版本号以及一些文件的版本信息版本信息
2-3unsigned short当前段的个数段计数
4-7unsigned int时间戳,这个并不是必须的,但是规定下一般都会写入时间戳
8-11unsigned int标识符空间的指针标识符指针
12-15unsigned int标识符的个数标志个数
16-17unsigned short设置相关的参数的长度,可能是0,因为有些情况下不需要自定义参数
18-19unsigned short一些文档的格式标志,大多数时间都会同时置很多文件属性

上面这些就是一个典型的文件头的内容了

于是可以获得如下的自定义格式:

typedef struct
{
    unsigned short Version_id;
    unsigned short section_h_count;
    unsigned int time_about;
    unsigned int symbol_point;
    unsigned short optional;//需要注意的是,这里不用可以写空,但是一定要存在
    unsigned short flag;
}

版本信息的定义

这里需要知道的是,版本信息虽然不是一个必须要用到的参数,但是还是有定义的一个参数。下面就是TI对其的一些定义:

版本信息变量说明
IMAGE_FILE_MACHINE_UNKNOWN0x0Contents assumed to beapplicable to any machine type.
IMAGE_FILE_MACHINE_ALPHA0x184Alpha AXP™.
IMAGE_FILE_MACHINE_ARM0x1c0
IMAGE_FILE_MACHINE_ALPHA640x284Alpha AXP™ 64-bit.
IMAGE_FILE_MACHINE_I3860x14cIntel 386 or later, andcompatible processors
IMAGE_FILE_MACHINE_IA640x200Intel IA64™
IMAGE_FILE_MACHINE_M68K0x268Motorola 68000 series.
IMAGE_FILE_MACHINE_MIPS160x266
IMAGE_FILE_MACHINE_MIPSFPU0x366MIPS with FPU
IMAGE_FILE_MACHINE_MIPSFPU160x466MIPS16 with FPU
IMAGE_FILE_MACHINE_POWERPC0x1f0Power PC, little endian.
IMAGE_FILE_MACHINE_R30000x162
IMAGE_FILE_MACHINE_R40000x166MIPS® little endian
IMAGE_FILE_MACHINE_R100000x168
IMAGE_FILE_MACHINE_SH30x1a2Hitachi SH3
IMAGE_FILE_MACHINE_SH40x1a6Hitachi SH4
IMAGE_FILE_MACHINE_THUMB0x1c2

flag参数

这些主要是这个文件的执行定义

变量参数定义
IMAGE_FILE_RELOCS_STRIPPED0x0001重定义的信息剥离
IMAGE_FILE_EXECUTABLE_IMAGE0x0002本文件可以单独使用(没有外部依赖)
IMAGE_FILE_LINE_NUMS_STRIPPED0x0004长度数字已经剥离.
IMAGE_FILE_LOCAL_SYMS_STRIPPED0x0008符号区域已被剥离
IMAGE_FILE_AGGRESSIVE_WS_TRIM0x0010优先优化工作的位置
IMAGE_FILE_LARGE_ADDRESS_AWARE0x0020应用可以检索大于2GB的地址
IMAGE_FILE_16BIT_MACHINE0x004016位机专用,保留
IMAGE_FILE_BYTES_REVERSED_LO0x0080小端编码
IMAGE_FILE_32BIT_MACHINE0x010032位芯片限定.
IMAGE_FILE_DEBUG_STRIPPED0x0200调试文件已经删除.
IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP0x0400多用于定义的多媒体文件内存区块
IMAGE_FILE_SYSTEM0x1000系统文件限定.
IMAGE_FILE_DLL0x2000这里是个dll.
IMAGE_FILE_UP_SYSTEM_ONLY0x4000似乎是某个特殊机器使用的文件(UP机器)
IMAGE_FILE_BYTES_REVERSED_HI0x8000大端编码.

这里的文档就是暂时的LINUX早期的文件的定义,这个其实也是可以随便定义的,但是这里依照LINUX提供的文件,讲述这个比较好一些。

但是我看了TI文件后,它们的定义几乎没几个一样的(可能是TI为了节省一些文件空间)。

0x12自定义参数

这个参数是这个文件的属性参数之一,主要的作用是告诉解析器具体的软件结构

位置格式定义说明称呼
0-1unsigned short特定的文件定义diy
2-3unsigned short版本号version
4-7unsigned long可执行代码尺寸sizeof_exec
8-11unsigned long已被初始化的尺寸sizeof_init
12-15unsigned long未初始化的尺寸sizeof_uninit
16-19unsigned long当前的文件入口entry
20-23unsigned long可执行代码的入口exec_entry
24-27unsigned long已初始化的数据入口data_entry

上面的所有入口基本上都是当前的文件入口,也就是当前的文件的真实结构。

原本文档里面有很多的表格,关于PE文档的一些与关于库文件的一些这里没有细说,现有的嵌入式也不常用。所以这里也就仅仅介绍最简单的部分。

0x20段结构

段结构是一个基本的代码结构,这只是个对于数据的定义。是一个简单的列表结构,包罗了长度,名称,地址与偏移什么的。下表就是一个典型的段结构

位置长度名称介绍
08段名称字符串
84虚拟长度软件真实空间的长度
124虚拟地址软件真实空间的地址
164真实的代码尺寸这个是段的尺寸,这个是8位为一个基准
204指针的真实地址文件中的指针的真实地址。
244重定义的地址如果是重定向的地址就会填进去,但是如果不是的话固定为0
284行数指针行数的地址
322重定义的编码重定义的编码。比如是1.2.3.4什么的
342行数的编码行数的个数。和上面的那个差不多
362标志位当前段的标志位

至于最后的一位,也是比较重要的定义项:

FlagValue介绍
IMAGE_SCN_TYPE_REG0x00000000现已不用
IMAGE_SCN_TYPE_DSECT0x00000001现已不用
IMAGE_SCN_TYPE_NOLOAD0x00000002现已不用
IMAGE_SCN_TYPE_GROUP0x00000004现已不用
IMAGE_SCN_TYPE_NO_PAD0x00000008被更好的使用方式替代
IMAGE_SCN_TYPE_COPY0x00000010现已不用
IMAGE_SCN_CNT_CODE0x00000020执行代码段
IMAGE_SCN_CNT_INITIALIZED_DATA0x00000040初始化的数据段
IMAGE_SCN_CNT_UNINITIALIZED_DATA0x00000080未初始化的数据段
IMAGE_SCN_LNK_OTHER0x00000100现已不用
IMAGE_SCN_LNK_INFO0x00000200一些不怎么重要的信息段
IMAGE_SCN_TYPE_OVER0x00000400现已不用
IMAGE_SCN_LNK_REMOVE0x00000800link段删除的标志
IMAGE_SCN_LNK_COMDAT0x00001000共同的数据段的特殊标志
IMAGE_SCN_MEM_FARDATA0x00008000现已不用
IMAGE_SCN_MEM_PURGEABLE0x00020000现已不用
IMAGE_SCN_MEM_16BIT0x00020000现已不用
IMAGE_SCN_MEM_LOCKED0x00040000现已不用
IMAGE_SCN_MEM_PRELOAD0x00080000现已不用
IMAGE_SCN_ALIGN_1BYTES0x00100000以1个八位字节排列的定义
IMAGE_SCN_ALIGN_2BYTES0x00200000以2个八位字节排列的定义
IMAGE_SCN_ALIGN_4BYTES0x00300000以4个八位字节排列的定义
IMAGE_SCN_ALIGN_8BYTES0x00400000以8个八位字节排列的定义
IMAGE_SCN_ALIGN_16BYTES0x00500000以16个八位字节排列的定义
IMAGE_SCN_ALIGN_32BYTES0x00600000以32个八位字节排列的定义
IMAGE_SCN_ALIGN_64BYTES0x00700000以64个八位字节排列的定义
IMAGE_SCN_ALIGN_128BYTES0x00800000以128个八位字节排列的定义
IMAGE_SCN_ALIGN_256BYTES0x00900000以256个八位字节排列的定义
IMAGE_SCN_ALIGN_512BYTES0x00A00000以512个八位字节排列的定义
IMAGE_SCN_ALIGN_1024BYTES0x00B00000以1024个八位字节排列的定义
IMAGE_SCN_ALIGN_2048BYTES0x00C00000以2048个八位字节排列的定义
IMAGE_SCN_ALIGN_4096BYTES0x00D00000以4096个八位字节排列的定义
IMAGE_SCN_ALIGN_8192BYTES0x00E00000以8192个八位字节排列的定义
IMAGE_SCN_LNK_NRELOC_OVFL0x01000000需要外部的重定义的数据,也就是说这个地址的重定义大小已经超过寻址的空间。
IMAGE_SCN_MEM_DISCARDABLE0x02000000这个段是可以被丢弃的
IMAGE_SCN_MEM_NOT_CACHED0x04000000段没办法被缓存
IMAGE_SCN_MEM_NOT_PAGED0x08000000这个段没有页的存在
IMAGE_SCN_MEM_SHARED0x10000000这个段可以被内存共享
IMAGE_SCN_MEM_EXECUTE0x20000000这个段可以被执行
IMAGE_SCN_MEM_READ0x40000000这个段可以被读取
IMAGE_SCN_MEM_WRITE0x80000000这个段可以被写入

这个是单个段的具体属性,类似于文件的只读、执行、只写等操作。

0x30 结尾

这个就是定义Windows的相关文件的结构,COFF因为过于久远,几乎已经可以追溯到可执行文件的初始结构统一上了。而现在的PE文件其实几乎和这个文件没有一点相同了(除了一些基础的文件结构)。

但是还是对于很多的现代文件的构成是一个参考。

具体的现代文件结构里程碑大概是从压缩文件与网页超文本结构出现有关。这个可能需要等到后面再说啦。

更多

本文首发自 记:COFF文件下的解析说明,更多文章可进入我的博客详查。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreenDreamer

如果帮到了你,还望请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值