一个coff文件格式的观察
-- 2008-10-4 ljhhh0123
我采用自底向上的方法来学习coff文件格式,并体会汇编器的行为,
这是一个好方法.用vc6.0sp6编译的lcc将hello1.c
编译成汇编语言,再用masm32v8的汇编器得到的.obj文件,倾印下来,
本文的二进制字节序为little-endlian.
基本工具: 记事本+WinHex+ida+各种pe&coff学习资料
基本方法是: 选用winhex打开.obj文件,将内容以二进制方式复制到
记事本,然后就是边看资料,边从winhex上找到位置,边在记事本里断行和加
注释,另外还动用了masm32v8自带的工具dumpbin.exe和ida来找到各部分之
间的分界点.最后的结果如下.
-----可选文件头----
4C01 CPU识别码
0200 段数
43C5E548 日期戳
A6000000 符号表指针
0E000000 符号个数
0000 可选头大小
0000 标志
----段表--2项--
2E74657874000000 .text/0/0/0/0
00000000 第一个段的位置
00000000 在obj中总为0
2E000000 段大小
64000000 段的起始位置,相对于obj文件
92000000 重定位信息的位置
00000000 行号表的位置
0200 重定位项目数
0000 行号个数
20005060 段标志字 IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
| IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_CNT_CODE
2E64617461000000 .data/0/0/0
2E000000 第二个段的位置(第一个段起址加上第一个段的大小)
00000000
00000000
00000000
00000000
00000000
0000
0000
400050C0 IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE
| IMAGE_SCN_ALIGN_16BYTES |
E_SCN_CNT_INITIALIZED_DATA
----具体的段.text 长度0x2E----
535657558BEC8D3D0000000057E80000
000083C404B8000000008BE55D5F5E5B
C348656C6C6F20576F726C642100
----重定位表----2项----
08000000 段内偏移
0C000000 在符号表内的索引
0600 属性 重定位目标的32位虚拟地址
0E000000
0B000000 在符号表内的索引
1400 属性 重定位目标的32位相对偏移
----符号表--0xe项--
2E66696C65000000".file/0/0/0"
00000000
FEFF 只是个调试符号
0000
67 源文件符号记录。后面跟着给出文件名的辅助符号表记录。
03 附加记录数,就是下面三项数据不作具体的符号用.
433A5C444F43554D
457E315C6C6A685C4C4F
43414C537E315C54
656D705C6C6363313435
32312E61736D0000
00000000000000000000
40636F6D702E6964 "@comp.id"
FC201200
FFFF 这个符号值是个常量.
0000
03 存储类型为static
00
2E74657874000000 ".text/0/0/0"
00000000
0100 属于第一个段
0000
03
01 附加记录1项
2E00000002000000
00000000000000000000
2E64617461000000 ".data/0/0/0"
00000000
0200 段号,即第二个段
0000
03
01 附加记录1个
0000000000000000
00000000000000000000
00000000
04000000 以字符串表为开始,偏移四的位置取出.
00000000
0000
2000 函数类型
02 external
00
5F5F66746F6C0000 "__ftol/0/0"
00000000
0000
2000 函数类型
02 external
00
5F70757473000000 "_puts/0/0/0"
00000000
0000
2000
02 external
00
4C33000000000000 "L3"
21000000
0100 符号所在段的索引
0000
03 static
00
5F6D61696E000000 "_main/0/0/0"
00000000
0100 段号
2000 函数类型
02 external
00
----字符串表----
0E000000 总长度=本长度占的4字节+以0结尾的字符串的长度(包括0)
5F5F666C747573656400 "__fltused/0"
--------
附录A为开发环境所带的数据结构定义,
附录B为masm32v8下所执行的"dumpbin.exe /all hello1.obj"列印.
附录C为hello1.c文件和lcc生成的汇编语言文件倾印.
注:将些文章内的二进制数据复制到winhex内即可还原成hello1.obj文件.大小为0x1b0.
附录A:
typedef struct _IMAGE_FILE_HEADER {
WORD Machine;
WORD NumberOfSections;
DWORD TimeDateStamp;
DWORD PointerToSymbolTable;
DWORD NumberOfSymbols;
WORD SizeOfOptionalHeader;
WORD Characteristics;
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_SECTION_HEADER {
BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
union {
DWORD PhysicalAddress;
DWORD VirtualSize;
} Misc;
DWORD VirtualAddress;
DWORD SizeOfRawData;
DWORD PointerToRawData;
DWORD PointerToRelocations;
DWORD PointerToLinenumbers;
WORD NumberOfRelocations;
WORD NumberOfLinenumbers;
DWORD Characteristics;
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
typedef struct _IMAGE_RELOCATION {
union {
DWORD VirtualAddress;
DWORD RelocCount;
};
DWORD SymbolTableIndex;
WORD Type;
} IMAGE_RELOCATION;
typedef struct _IMAGE_SYMBOL {
union {
BYTE ShortName[8];
struct {
DWORD Short; // if 0, use LongName
DWORD Long; // offset into string table
} Name;
PBYTE LongName[2];
} N;
DWORD Value;
SHORT SectionNumber;
WORD Type;
BYTE StorageClass;
BYTE NumberOfAuxSymbols;
} IMAGE_SYMBOL;
附录B:
Microsoft (R) COFF Binary File Dumper Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
Dump of file hello1.obj
File Type: COFF OBJECT
FILE HEADER VALUES
14C machine (i386)
2 number of sections
48E5C543 time date stamp Fri Oct 03 15:09:55 2008
A6 file pointer to symbol table
E number of symbols
0 size of optional header
0 characteristics
SECTION HEADER #1
.text name
0 physical address
0 virtual address
2E size of raw data
64 file pointer to raw data
92 file pointer to relocation table
0 file pointer to line numbers
2 number of relocations
0 number of line numbers
60500020 flags
Code
16 byte align
Execute Read
RAW DATA #1
00000000: 53 56 57 55 8B EC 8D 3D 00 00 00 00 57 E8 00 00 SVWU...=....W...
00000010: 00 00 83 C4 04 B8 00 00 00 00 8B E5 5D 5F 5E 5B ............]_^[
00000020: C3 48 65 6C 6C 6F 20 57 6F 72 6C 64 21 00 .Hello World!.
RELOCATIONS #1
Symbol Symbol
Offset Type Applied To Index Name
-------- ---------------- ----------------- -------- ------
00000008 DIR32 00000000 C L3
0000000E REL32 00000000 B _puts
SECTION HEADER #2
.data name
2E physical address
0 virtual address
0 size of raw data
0 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0500040 flags
Initialized Data
16 byte align
Read Write
COFF SYMBOL TABLE
000 00000000 DEBUG notype Filename | .file
C:/DOCUME~1/ljh/LOCALS~1/Temp/lcc14521.asm
004 001220FC ABS notype Static | @comp.id
005 00000000 SECT1 notype Static | .text
Section length 2E, #relocs 2, #linenums 0, checksum 0
007 00000000 SECT2 notype Static | .data
Section length 0, #relocs 0, #linenums 0, checksum 0
009 00000000 UNDEF notype () External | __fltused
00A 00000000 UNDEF notype () External | __ftol
00B 00000000 UNDEF notype () External | _puts
00C 00000021 SECT1 notype Static | L3
00D 00000000 SECT1 notype () External | _main
String Table Size = 0xE bytes
Summary
0 .data
2e .text
附录C: hello1.c and hello1.asm
#include "stdio.h" /*借用djgpp的include目录.*/
main()
{puts("Hello World!");
}
.486
.model flat
extrn __fltused:near
extrn __ftol:near
public _main
_TEXT segment
_main:
push ebx
push esi
push edi
push ebp
mov ebp,esp
lea edi,(L3)
push edi
call _puts
add esp,4
mov eax,0
L2:
mov esp,ebp
pop ebp
pop edi
pop esi
pop ebx
ret
_TEXT ends
extrn _puts:near
_TEXT segment
_TEXT ends
_TEXT segment
align 1
L3 label byte
db 72
db 101
db 108
db 108
db 111
db 32
db 87
db 111
db 114
db 108
db 100
db 33
db 0
_TEXT ends
end
----本文完毕----