首页
社区
课程
招聘
[求助]DOS下exe的各个段是如何确认段基址
发表于: 2010-5-10 23:47 5983

[求助]DOS下exe的各个段是如何确认段基址

2010-5-10 23:47
5983
我看到一个dos的EXE有40多个段,请问这些段的信息存在哪里,咋找啊

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 237
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
Intel x86 实模式下面,一个段只有64KB,内存寻址空间才1MB,没有很多段连大点的程序都放不下。段寄存器里放的就是段地址,没有查表这一说。
如果DS=5000H SI=FF02H 那么 DS:SI 的实际地址就是 (5000H << 4) + FF02H = 5FF02H。
2010-5-11 01:44
0
雪    币: 237
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
DOS的EXE格式google: MZ文件格式。
2010-5-11 01:48
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
有两个段IDA似乎没分析,段属性为UNK,里面的串找不到任何引用,这种情况有什么好办法找到引用吗
2010-5-11 09:13
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
google找不到啊
2010-5-11 13:26
0
雪    币: 237
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
EXE Format
Note: all multi-byte values are stored LSB first. One block is 512 bytes, one paragraph is 16 bytes. See also the entry in Ralf Brown's Interrupt List

Offset (hex)
Meaning
00-01        0x4d, 0x5a. This is the "magic number" of an EXE file. The first byte of the file is 0x4d and the second is 0x5a.
02-03        The number of bytes in the last block of the program that are actually used. If this value is zero, that means the entire last block is used (i.e. the effective value is 512).
04-05        Number of blocks in the file that are part of the EXE file. If [02-03] is non-zero, only that much of the last block is used.
06-07        Number of relocation entries stored after the header. May be zero.
08-09        Number of paragraphs in the header. The program's data begins just after the header, and this field can be used to calculate the appropriate file offset. The header includes the relocation entries. Note that some OSs and/or programs may fail if the header is not a multiple of 512 bytes.
0A-0B        Number of paragraphs of additional memory that the program will need. This is the equivalent of the BSS size in a Unix program. The program can't be loaded if there isn't at least this much memory available to it.
0C-0D        Maximum number of paragraphs of additional memory. Normally, the OS reserves all the remaining conventional memory for your program, but you can limit it with this field.
0E-0F        Relative value of the stack segment. This value is added to the segment the program was loaded at, and the result is used to initialize the SS register.
10-11        Initial value of the SP register.
12-13        Word checksum. If set properly, the 16-bit sum of all words in the file should be zero. Usually, this isn't filled in.
14-15        Initial value of the IP register.
16-17        Initial value of the CS register, relative to the segment the program was loaded at.
18-19        Offset of the first relocation item in the file.
1A-1B        Overlay number. Normally zero, meaning that it's the main program.
Here is a structure that can be used to represend the EXE header and relocation entries, assuming a 16-bit LSB machine:

struct EXE {
  unsigned short signature; /* == 0x5a4D */
  unsigned short bytes_in_last_block;
  unsigned short blocks_in_file;
  unsigned short num_relocs;
  unsigned short header_paragraphs;
  unsigned short min_extra_paragraphs;
  unsigned short max_extra_paragraphs;
  unsigned short ss;
  unsigned short sp;
  unsigned short checksum;
  unsigned short ip;
  unsigned short cs;
  unsigned short reloc_table_offset;
  unsigned short overlay_number;
};

struct EXE_RELOC {
  unsigned short offset;
  unsigned short segment;
};
The offset of the beginning of the EXE data is computed like this:

exe_data_start = exe.header_paragraphs * 16L;
The offset of the byte just after the EXE data (in DJGPP, the size of the stub and the start of the COFF image) is computed like this:

extra_data_start = exe.blocks_in_file * 512L;
if (exe.bytes_in_last_block)
  extra_data_start -= (512 - exe.bytes_in_last_block);
2010-5-11 21:21
0
雪    币: 237
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
IDA对16位程序是要差点。用刘涛涛的TR for DOS在那两个段下断点跑一下看是谁引用的吧。话说TR for DOS这个基于VM的debuger还是很强的。
2010-5-11 21:23
0
游客
登录 | 注册 方可回帖
返回
//