Dos-mz 可执行(特指exe)文件分为2部分:头部+代码部分;
其中:
头部:文件头+重定位表;
代码部分:程序的所有2进制数据;
文件头:
0000h 2 char id="MZ";//幻数 ;
0002h 1 word lastsize; //最后一个块使用的字节数;
0004h 1 word nblocks; //512字节块的个数;
0006h 1 word nreloc; //重定位项个数 ;
0008h 1 word hdrsize; //以16字节段为单位的文件头部尺寸;
哪个星球水最多000ah 1 word minalloc; //需额外分配的最小内存量;
000ch 1 word maxalloc; //需额外分配的最大内存量;
dnf接收频道信息失败000eh 1 word initial ss relative to start of executable ;
0010h 1 word initial sp ;
0012h 1 word checksum; //文件校验和;
0014h 1 dword cs:ip relative to start of executable (entry point);(第一字节ip第二字节cs) ;
0018h 1 word relocpos; //重定位修正表位置; 40h for new-(ne,le,lx,w3,pe etc.) executable ;
001ah 1 word noverlay; //重叠的个数,程序为0 ;
说明:
1、sizeof(char)=1;sizeof(word)=2; sizeof(dword)=4;
2、sizeof(头部+代码部分)=512*(nblocks-1)+lastsize;
一般文件大小也等于这个大小,但有的编译器会在代码部分后加上额外的信息使文件变大,额外信息不影响程序的运行可直接删除;
3、一般 sizeof(文件头)=512;
好的三本院校 4、重定位表位置是在文件中的偏移;
一般汇编器从 1eH 处开始为重定位表项;
1bH1cH1dH 处我还不知道是什么信息;
其他编译器从1cH(1bH处不知)处加自己的信息,从定位表位置要相应改变;
重定位表:
重定位表有nreloc个重定位表项组成;
每个重定位表项格式如下:
段基址:段内偏移量
1 word 段内偏移量
1 word 段基址
1 word 段基址
冒险岛什么职业好共占4 字节;
(
注意winxp是 位高权重 的储存方式;
如数1234H在内存中占字节00H01H;
则:
【00H】:34H;【01H】:12H;即照3412H格式储存;
)
说明:
1、 对每一个修正地址(重定位表项),将其中的基地址与程序代码加载的基地址相加,然后将这个重定位后的修正地址作为指针,将程序代码的实际基地址与这个指针指向的程序代码中的地址相加。
2、 基地址指的是可执行代码段的基地址;
代码部分:
(按汇编顺序布局,汇编后数据段大小为16的整倍数,cs:0 指向执行代码);
程序加载过程:
1、读入文件头部,验证幻数是否有效。
2、一块大小合适的内存区域。minalloc和maxalloc域说明了在被加载程序末尾后需额外分配的内存块的最大和最小尺寸(链接器总是缺省的将最小尺寸设置为程序中类似BSS的未初始化数据的大小,将最大尺寸设置为0xFFFF)。
3、创建一个程序段前缀(Program Segment Prefix),即位于程序开头的控制区域。
4、在PSP之后读入程序的代码。nblocks和lastsize域定义了代码的长度。
5、从relocpos处开始读取nreloc个修正地址项。对每一个修正地址,将其中的基地址与程序代码加载的基地址相加,然后将这个重定位后的修正地址作为指针,将程序代码的实际基地址与这个指针指向的程序代码中的地址相加。
6、将栈指针设置为重定位后的sp,然后跳转到重定位后的ip处开始执行程序。 除了与分段寻址相关的怪异特性外,这是程序加载时的典型初始化过程。在少数情况下,程序的不同片段可以用不同的方式重定位。在286保护模式下(EXE文件不支持),虽然可执行文件中的代码和数据段被加载到系统中各自独立的段,但是由于体系结构的原因段基址是不连续的。每一个保护模式的可执行程序在靠近文件开头的位置有一个表列出来程序需要的所有段。系统会创建一个表将可执行程序中的每个段与系统中实际的段址对应起来。在进行地址调整时,系统会在这个表中查逻辑段址,并将其替换为实际的段址,相比于重定位这更类似一个符号绑定的过程。
附录1:
Winxp tc2.01 环境下编译的exe文件在文件头部和代码部分后有一些额外信息可去除;
其中的main()函数被编译在主代码段:01faH 处;程序在011aH处调用用户接口程序;
用户接口程序不一定是main()函数;也可能是定义在main()后边的函数;
数据好像是跟在可执行代码后面;
根据入口地址和main函数很容易照源程序代码部分并分析之;
1、 tc2.01 编译器;//WY_TCPP30H_;
2、 几个考察文件:*.c 源文件 *。Exe 原可执行文件 new*。Exe 删除额外信息后的可执行文件;//*
附录2:
文件夹:View_mz_head;
包含一个dos-mz文件查看器;(vc6.0 下编译);淘宝ems是什么意思
附录3:
文件夹:masn;
1、 一些masn源码;
2、 Masn5 编译器;
参考文献:
1、 百度:DOS MZ格式EXE文件介绍 - SearchLife的专栏 - CSDN博客.htm;
2、 百度:MS-DOS EXE文件 - 如斯专栏 - CSDN博客.htm;
3、 Vc6.0 winnt.h 文件 dos-header 部分;
英雄联盟深海泰坦出装
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论