一个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
----本文完毕----
- 标 题:一个coff文件格式的观察
- 作 者:ljhhh
- 时 间:2008-10-06 09:44
- 链 接:http://bbs.pediy.com/showthread.php?t=74060