确定MZ exe结束的位置,并启动LE / LX / PE

时间:2011-12-28 00:01:49

标签: c exe

我想知道什么是确定EXE文件的MZ部分结束位置以及附加的扩展可执行文件的最佳方式(可以是PE / LE / LX / NE / COFF等......)。

我找到了这个网站:http://www.delorie.com/djgpp/doc/exe/试图解释它,但我从未得到预期的结果。我总是以超出实际PE或LX起始偏移的偏移方式结束。

// LXInfo.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

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;
};


int _tmain(int argc, _TCHAR* argv[])
{
    struct EXE header1;
    char sFile[]="c:\\register.dll";
    unsigned int extra_data_start;
    char test;
    FILE *fp;
    fp = fopen(sFile, "rb");
    fread(&header1,sizeof(struct EXE),1,fp);

    //read the header
    printf("EXE Signature: %x \n", header1.signature);
    printf("Bytes in last block: %08x \n", header1.bytes_in_last_block);
    printf("Blocks in file: %08x \n", header1.blocks_in_file);
    printf("Number of relocations: %08x \n", header1.num_relocs);
    printf("Header paragraphs: %08x \n", header1.header_paragraphs);
    printf("Min. extra paragraphs: %08x \n", header1.min_extra_paragraphs);
    printf("Max. extra paragraphs: %08x \n", header1.max_extra_paragraphs);
    printf("Initial SS value: %08x \n", header1.ss);
    printf("Initial SP value: %08x \n", header1.sp);
    printf("Checksum value: %08x \n", header1.checksum);
    printf("Initial CS value: %08x \n", header1.cs);
    printf("Initial IP value: %08x \n", header1.ip);
    printf("Relocation table offset: %08x \n", header1.reloc_table_offset);
    printf("Overlay number: %x \n", header1.overlay_number);
    printf("\n");
    printf("Start of EXE data: %08x \n", header1.header_paragraphs * 16L);

    //calculate end of MZ EXE, according to Delorie
    extra_data_start = header1.blocks_in_file * 512L;
    if (header1.bytes_in_last_block)
        extra_data_start -= (512 - header1.bytes_in_last_block);

    printf("End of EXE data: %08x \n", extra_data_start);

    // let's read the first two bytes after the MZ EXE data. This should give us a P and E on windows, or L and X on OS/2...
    fseek(fp,extra_data_start,SEEK_SET);
    fread(&test,1,1,fp);
    printf("test char: %c \n", test);
    fread(&test,1,1,fp);
    printf("test char: %c \n", test);

    fclose(fp);
    getch();
    return 0;
}

1 个答案:

答案 0 :(得分:3)

阅读以下文章:An In-Depth Look into the Win32 Portable Executable File Format 您还应该阅读The Portable Executable File Format

例如,要获得IMAGE_NT_HEADERS的偏移量,您可以这样做:

IMAGE_DOS_HEADER* pdos = (IMAGE_DOS_HEADER*)peBuffer; 
IMAGE_NT_HEADERS* pnt = (IMAGE_NT_HEADERS*)((DWORD)pdos + pdos->e_lfanew);