转载:DOS下exe头文件解析

原文地址:http://www.asmedu.net/bbs/pasteinfo.jsp?part=1&level=free&kind=1020&qkSg=2&qID=17819

/**************************************************************************************************************************** 
                                           DOS下EXE文件头分析 

                                                                                                Author:Thinkred  
                                                                                             Date:2008/05/29 
****************************************************************************************************************************/ 

最近在学习8086汇编的时候,研究了DOS下exe文件的文件头。具体的分析结果如下: 

标准的EXE文件头结构如下: 

EXEHEADER STRUC  
exSignature dw 5A4Dh ;            exe的文件标识 ---------------------magic number
exExraBytes dw ? ;                exe文件最后一个扇区的的字节数-----bytes on last page of file  
exPages dw ? ;                    exe的扇区总数----pages  in file  
exRelocItems dw ? ;               重定位表的表项个数---relocations  
exHeaderSize dw ? ;               文件头大小,以字节为单位--size of header in paragraphs  
exMinAlloc dw ? ;                 运行程序时,所需的最小内存分配空间--min extra paragraphs needed   
exMaxAlloc dw ? ;                 运行程序时,所需的最大内存分配空间--max extra paragraphs needed  
exInitSS dw ? ;                   程序被载入时,堆栈段SS的偏移地址--initail ss value  
exInitSP dw ? ;                   程序被载入时,SP的初值--initial (relative) sp value  
exChechSum dw ? ;                 补码校验值---checknum  
exInitIP dw ? ;                   程序被载入时,IP的初值--intial ip value  
exInitCS dw ? ;                   程序被载入时,代码段CS的偏移地址-initial cs value  
exRelocTable dw ? ;               重定位表起点在头部信息块中的偏移位置--file address of relocation   table
exOverlay dw ? ;                  覆盖号  --overlay num
EXEHEADER ENDS 

这里以masm5文件夹下的cref.exe来具体分析,这里我们需要用到UltraEdit和debug两个工具。用UltraEdit打开cref.exe前面30H的数据如下: 

00000000h:4D 5A D6 01 1F 00 03 00 20 00 CB 00 FF FF 08 04 
00000010H:00 08 88 90 86 11 00 00 1E 00 00 00 01 00 D2 01 
00000020H:2F 03 9D 11 00 00 11 15 00 00 00 00 00 00 00 00 

然后用debug载入cref.exe时,各个寄存器数据如下: 

C:\MASM5>debug cref.exe 
-r 
AX=0000  BX=0000  CX=3BD6  DX=0000  SP=0800  BP=0000  SI=0000  DI=0000 
DS=153C  ES=153C  SS=1954  CS=154C  IP=1186   NV UP EI PL NZ NA PO NC 
154C:1186 B430          MOV     AH,30 

1、偏移00-01H的数据是:4D 5A ,这两个字节是exe的文件标识,转换为ASCII码就是MZ,代表DOS的主要开发者Mark Zbikowski 

2、偏移02-03H的数据是:D6 01,  表示cref.exe最后一个扇区的字节数,可以用"文件大小 mod 512"来计算。cref.exe的文件大小是15830字节,15830 mod 512 = 470, 转换成16进制就是01D6,根据高高低低的原则存放 

3、偏移04-05H的数据是:1F 00, 表示cref.exe一共有31个扇区。一个扇区大小默认是512字节,cref.exe的文件大小是15830字节,15830 整除 512 = 30,剩下的470个字节占据一个扇区,所以一共是31个扇区,转换成16进制就是00 1F 

4、偏移06-07H的数据是:03 00, 表示cref.exe的重定位表有3个表项。每次将exe载入内存时,载入地址都不是固定的,因此需要对exe进行重定位操作。重定位表每一个表项为4个字节。根据偏移06-07H重定位表的表项个数和偏移18-19H重定位表在文件头的偏移,我们可以知cref.exe有3个表项,起始位置是偏移1E,内容分别是:D2 01 2F 03 9D 11 00 00 11 15 00 00 

5、偏移08-09H的数据是:20 00, 表示cref.exe的文件头有20H个字节 

6、偏移0A-0BH的数据是:CB 00, 表示cref.exe运行时所需的最小分配内存是00CBH字节 

7、偏移0C-0DH的数据是:FF FF, 表示cref.exe运行时所需的最大分配内存是FFFFH字节。一般情况下,除非被LINK命令行开关覆盖,连接程序将它设置为FFFFH 

8、偏移0E-OFH的数据是:08 04,表示cref.exe被载入后SS的相对偏移地址是:0408H 。这里的偏移是相对于DS后256个字节处的偏移。我们知道exe载入分配内存后,在该内存的头256字节建立一个PSP。debug中,SS=1954,DS=153C,所以SS - DS - 10h = 1954h - 153ch - 10h = 0408h 

9、偏移10-11H的数据是:00 08,表示cref.exe被载入后SP的初值是0800H。在debug中,我们可以看到SP=0800 

10、偏移12-13H的数据是:88 90,表示cref.exe的补码校验值是:9088H 

11、偏移14-15H的数据是:86 11,表示cref.exe被载入后IP的初值是:1186H。在debug中,我们可以看到IP=1186 

12、偏移16-17H的数据是:00 00,表示cref.exe被载入后CS的相对偏移地址是:0000H。这里的偏移是相对于DS后256个字节处的偏移。我们知道exe载入分配内存后,在该内存的头256字节建立一个PSP。debug时,CS=154C,DS=153C,所以CS - DS - 10h = 154ch - 153ch - 10h = 
0000h 

13、偏移18-19H的数据是:1E 00,表示cref.exe的重定位项表在文件头的的偏移位置是1EH,内容分别是:D2 01 2F 03 9D 11 00 00 11 15 00 00 

14、偏移1A-1BH的数据是: 00 00,这是一个覆盖号。对于一个程序,这个值为零 

15、偏移1C-1DH的数据是: 01 00,对于所有DOS下所有的exe文件,这个值都是0001H,但具体含义并不清楚 

16、偏移1E-29H的数据是:D2 01 2F 03 9D 11 00 00 11 15 00 00,放的是cref.exe的重定位项表的内容 

    至此,文件头的所有内容就分析完了,剩下数据从偏移2AH-1FFH都用00来填充,从偏移200H开始,就是放的是程序执行时的机器码。最后来分析下,DOS将exe载入的过程。在将exe文件载入后,DOS创建了新的PSP,因而,除EXE文件头外,将整个EXE文件可执行的机器码装入内存中位于PSP之上的位置,我们称此位置为装载地址。随后,把DS和ES寄存器设置成指向此PSP,通过EXE文件头的值来设置CS:IP和SS:SP寄存器。 最后,用EXE头中的重定位表修改内存映象中的段引用。

posted @ 2013-01-11 15:26  Black Man's Note  阅读(699)  评论(0编辑  收藏  举报