Таблица 1



Таблица 1

(0) 2 signature два байта 'MZ' (4Dh, 5Ah), индентифицирующие файл в формате EXE
(+2) 2part_pag длина последней страницы программы в байтах (страница содержит 512 байт)
(+4) 2file_size размер программы в страницах по 512 байт
(+6) 2rel_item число элементов в таблице расположения сегментов
(+8) 2hdr_size размер заголовка файла в параграфах (длина параграфа - 16 байт)
(+10) 2min_mem минимальное количество памяти в параграфах, которое нужно зарезервировать в памяти за концом загруженной программы
(+12) 2max_mem максимальное количество памяти в параграфах, которое нужно зарезервировать в памяти за концом загруженной программы
(+14) 2ss_reg величина смещения от начала программы, которая используется для загрузки сегментного регистра стека SS
(+16) 2sp_reg величина смещения от начала программы, которая используется для загрузки регистра SP
(+18) 2chk_summ контрольная сумма всех слов в файле
(+20) 2ip_reg значение для регистра IP, которое будет использовано при начальном запуске программы
(+22) 2cs_reg смещение от начала программы для установки сегментного регистра кода CS
(+24) 2relt_off смещение от начала файла таблицы расположения сегментов программы
(+26) 2overlay номер оверлея, равен 0 для основного модуля

Таблица расположения сегментов программы начинается сразу после форматированной области и состоит из четырехбайтовых значений в формате "смещение:сегмент".

Область файла после таблицы расположения сегментов выравнивается на границу параграфа с помощью байта-заполнителя, и дальше начинается сама программа.

В файле sysp.h есть описание заголовка файла и таблицы расположения сегментов, которые вы можете использовать при обработке заголовка EXE-файла: typedef struct _EXE_HDR_ { unsigned signature; unsigned part_pag; unsigned file_size; unsigned rel_item; unsigned hdr_size; unsigned min_mem; unsigned max_mem; unsigned ss_reg; unsigned sp_reg; unsigned chk_summ; unsigned ip_reg; unsigned cs_reg; unsigned relt_off; unsigned overlay; } EXE_HDR; typedef struct _RELOC_TAB_ { unsigned offset; unsigned segment; } RELOC_TAB;

В качестве примера приведем программу, которая считывает форматированную часть заголовка EXE-файла, проверяет наличие в его первых двух байтах признака EXE-формата ('MZ'). Если признак имеется, программа выводит на экран расшифрованное содержимое заголовка и таблицу перемещений, если такая таблица присутствует. В качестве параметра программе надо при запуске передать имя исследуемого EXE-файла. #include <stdio.h> #include <stdlib.h> #include "sysp.h" void main(int, char *[]); void main(int argc, char *argv[]) { printf("Распечатка заголовка EXE-файла\n" "Copyright (C)Frolov A., 1990\n\n"); if( argc != 2 ) { printf( " Задайте путь EXE-файла в качестве" "параметра\n" ); exit(0); } if( gethdr( argv[1]) != 0) { printf( "Ошибка в формате файла или нет такого" "файла\n" ); exit(0); } exit(0); } int gethdr( char *path) { EXE_HDR header; RELOC_TAB *reloc; FILE *inpfile; int i; if((inpfile = fopen(path,"rb")) == 0) return(-1); if(get_exeh(&header,&reloc,inpfile) != 0) { fclose(inpfile); return(-1); } printf("Магическое число: %04X\n" "Длина последней страницы файла: %d\n" "Количество страниц в файле: %d\n" "Кол. элементов табл. перемещений: %d\n" "Размер заголовка в параграфах: %d\n" "Минимальная память для программы: %04X\n" "Максимальная память для программы: %04X\n" "Значение адреса стека SS:SP: 04X:%04X\n" "Контрольная сумма: %04X\n" "Значения для регистров CS:IP: %04X:%04X\n" "Смещение табл. перемещений: %02X\n" "Номер оверлея: %d\n", header.signature, header.part_pag, header.file_size, header.rel_item, header.hdr_size, header.min_mem, header.max_mem, header.ss_reg, header.sp_reg, header.chk_summ, header.cs_reg, header.ip_reg, header.relt_off, header.overlay); if(reloc != 0) { printf("\nСодержимое таблицы перемещений:\n\n"); for(i=0;i < header.rel_item; i++) { printf("%04X:%04X\n", (reloc+i)->segment, (reloc+i)->offset); } free(reloc); } fclose(inpfile); return(0); }

Приведенная выше программа для чтения заголовка EXE-файла пользуется функцией get-exeh: /** *.Name get_exeh * *.Title Прочитать заголовок EXE-файла * *.Descr Функция читает заголовок EXE-файла в * структуру типа EXE_HDR, заказывает память * для таблицы размещений сегментов и считывает * таблицу в эту область. Адрес заказанной области * помещается по адресу, передаваемому в rtb. * Если таблица размещений отсутствует, память для * нее не заказывается. * *.Params int get_exeh(EXE_HDR *exeh,RELOC_TAB **rtb, * FILE *exe_file) * * exeh - указатель на структуру, которая * должна быть заполнена информацией * из заголовка EXE-файла * * rtb - указатель на указатель на таблицу * размещений сегментов программы * * exe_file - указатель на открытый EXE-файл * (до вызова функции нельзя обращаться * к этому файлу, т.к. считается, что * указатель текущего смещения * установлен на начало файла) * *.Return 0 при успешном считывании заголовка; * -1 в случае неправильного формата заголовка **/ #include <stdlib.h> #include <stdio.h> #include "sysp.h" int get_exeh(EXE_HDR *exeh,RELOC_TAB **rtb,FILE *exe_file) { int i,j,k; // считываем форматированную часть заголовка for(i=0; i < sizeof(EXE_HDR); i++) { *(((char*)exeh) + i) = fgetc(exe_file); if(feof(exe_file)) break; } // это EXE-файл? if(exeh->signature != 0x5a4d) return(-1); if((i=exeh->rel_item) != 0) { // если есть таблица перемещений, заказываем для нее память *rtb = (RELOC_TAB*)malloc(i*sizeof(RELOC_TAB)+16); // считываем таблицу перемещений for(k=0; k<i; k++) { for(j=0;j < sizeof(RELOC_TAB);j++) { *((char*)(*rtb)+j+k*sizeof(RELOC_TAB))= fgetc(exe_file); if(feof(exe_file)) break; } } } else *rtb = (RELOC_TAB *)0; return(0);}



- Начало - - Назад - - Вперед -