- •Введение
- •Тема 1. Двухпросмотровый ассемблер
- •Тема 2. Com-сервер для обработки и хранения результатов тестирования.
- •Тема 3. Дисковая утилита для просмотра fat.
- •Тема 4. Сервер автоматизации ole.
- •Тема 5. Дефрагментатор файловой системы.
- •Элемент каталога для короткого имени
- •Тема 6. Монитор системных ресурсов для Windows 98/2000.
- •Тема 7. Менеджер процессов и потоков для Windows 98/2000.
- •Тема 8. Файловый менеджер для Windows 98/2000/nt.
- •Тема 9. Формат исполняемого pe-файле в Windows 98/nt.
- •Тема 10. Запуск в определенное время различных программ.
- •Тема 11. Утилита, сохраняющая в файле информацию из системного реестра о программах, установленных на компьтере.
- •Тема 12. Утилита для очистки системного реестра Windows.
- •Тема 13. Утилита, отслеживающая изменения в файловой системе Windows в заданных каталогах.
- •Тема 14. Просмотрщик таблицы разделов и fat.
- •Тема 15. Утилита MaxSplitter
- •Тема 16. Утилита удаленного администрирования.
- •Тема 17. Простая почтовая программа на основе протокола smtp.
- •Тема 18. Ftp - клиент.
- •Тема 19. Ftp - сервер.
- •Тема 20. Системные сервисы Windows nt/2000.
- •Литература
- •Приложение 1. Tcp/ip Программирование с использованием WinSock
- •Создание и использование сокетов
- •Закрытие сокета
- •Функция shutdown()
- •Методы прекращения работы гнезда
- •Функция bind()
- •Приложение может послать запрос на соединение с помощью функции
- •Отправка и прием данных через сокеты потоков
- •Ожидание и обработка событий
- •Использование функции wsaAsyncSelect()
- •Приложение 2. Команды ftp
- •Приложение 3. Команды smtp
- •Приложение 4. Заголовки почты smtp
Тема 9. Формат исполняемого pe-файле в Windows 98/nt.
Техническое задание.
Разработать программу, выводящую информацию об исполняемом PE-файле.
Методические указания.
Переносимый формат исполнимых файлов, - Portable Executable (PE) file format, - произведен от спецификации COFF ( общий формат объектных файлов - Common Object File Format ), который распространен на многих операционных системах семейства UNIX. В то же время, для сохранения совместимости с предыдущими версиями MS-DOS и Windows, PE формат также сохранил старый знакомый MZ заголовок DOSа.
Структура PE-файла
00h |
DOS 2 Header Заголовок ЕХЕ-файла DOS |
1Ch |
4 байта, выравнивающие форматированную область заголовка с 1Ch до 20h, это позволяет заголовку файла иметь красивый размер в 2 параграфа... |
20h |
OEM Identifier & OEM Info Другими словами, информация о программе, практически никогда не присутствует, однако место должно быть зарезервировано. |
3Ch |
Offset to PE Header Смещение реального PE заголовка в файле, DWORD |
min 40h |
Расположение программы-заглушки. На это поле указывает ReloOfs заголовка DOS 2 Header, соответственно его значение должно быть >=40h иначе такой файл как кандидат в PE рассматриваться вообще не будет |
min 40h + XXh |
Тело DOS программы, иначе говоря, STUB'a. Чаще всего говорит о невозможности запуска, но может содержать в себе очень разрушительные вещи, как то поиск в PATH и запуск файла WIN.COM с указанием имени данного файла и т.д. |
XXh |
PE Header Здесь находится заголовок PE файла и, другими словами, начинается сама 32-битная программа, он должен быть выровнен на 8-байтовую границу |
XXh |
Object Table таблица описаний секций файла, подробнее далее. |
XXh |
Image Pages (import info, export info, fixup info, resource info, debug info, etc...) Остальная часть запускаемого файла... |
Для проверки на возможность файла быть в формате PE необходимо, чтобы он был во первых EXE (байты по смещению 0h равны 5A4Dh), во вторых, слово по смещению 18h должно быть >=40h, тогда и только тогда DWORD поле по смещению 3Ch имеет смысл. Загрузчик, загружая EXE-файлы DOS с заголовком 'ZM' - 4D5Ah, не считает их 32-битовыми программами. При запуске из DOS-окна выполняется DOS часть программы, а при запуске с помощью CreateProcessA (консольная утилита START.EXE вызывает данный сервис) выдается сообщение о невозможности запуска программы, т.к. это не 32-битовое приложение.
Заголовок MS-DOS занимает первые 64 байта PE файла. Структура, определяющая его содержимое, описана ниже:
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE заголовок
USHORT e_magic; // магическое число
USHORT e_cblp; // количество байт на последней странице файла
USHORT e_cp; // количество страниц в файле
USHORT e_crlc; // Relocations
USHORT e_cparhdr; // размер заголовка в параграфах
USHORT e_minalloc; // Minimum extra paragraphs needed
USHORT e_maxalloc; // Maximum extra paragraphs needed
USHORT e_ss; // начальное ( относительное ) значение регистра SS
USHORT e_sp; // начальное значение регистра SP
USHORT e_csum; // контрольная сумма
USHORT e_ip; // начальное значение регистра IP
USHORT e_cs; // начальное ( относительное ) значение регистра CS
USHORT e_lfarlc; // адрес в файле на таблицу переадресации
USHORT e_ovno; // количество оверлеев
USHORT e_res[4]; // Зарезервировано
USHORT e_oemid; // OEM identifier (for e_oeminfo)
USHORT e_oeminfo; // OEM information; e_oemid specific
USHORT e_res2[10]; // Зарезервировано
LONG e_lfanew; // адрес в файле нового .exe заголовка
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
Первое поле, e_magic, этот так называемое магическое число. Это поле используется для идентификации типа файла, совместимого с MS-DOS. Все MS-DOS совместимые исполнимые файлы имеют сигнатуру 0x54AD, представляющую в ASCII-символах строку MZ (или ZM). По этой причине на заголовок MS-DOS часто ссылаются также как на MZ-заголовок. Большинство других полей имеет значение для операционной системы MS-DOS, для Windows же есть только одно важное поле в этой структуре. Это последнее поле, e_lfanew, 4х байтовое смещение в файле, указывающее расположение заголовока PE файла. Мы должны использовать это смещение, чтобы найти заголовок PE файла. Для PE файлов, заголовок PE файла расположен сразу же за заголовком MS-DOS и только тело программы Реального режима (STUB) расположена между ними.
Рассмотрим структуру PE Header.
Base |
Size or Type |
Name Of field |
Brief description |
00h |
DWord |
Signature Bytes |
Сигнатурка того, что этот файл собственно говоря является PE - должна быть 4550h, иначе - 'PE',0h,0h; два последних байта под что-то-там Микрософт зарезервировала (и проверяет их равенству на 0!). |
04h |
Word |
CPU Type |
это поле указывает на предпочтительный тип процессора, на котором желательно запускать данную программу, вы редко увидите что-либо отличное от 14Ch -> i386 |
06h |
Word |
Num of Objects |
это поле указывает на число реальных входов в Object Table |
08h |
DWord |
Time/Date Stamp |
используется для хранения даты и времени создания/модификации линкером |
0Ch |
DWord |
Pointer to COFF table |
дополнительный указатель определяющий местонахождение отладочной COFF таблицы в файлах |
10h |
DWord |
COFF table size |
кол-во символов в COFF таблице |
14h |
Word |
NT Header Size |
размер заголовка PE файла начиная с поля Magic, таким образом, общий размер заголовка PE файла составляет NT Header Size + 18h |
16h |
Word |
Flags |
указывает на предназначение программы, конкретное значение флагов см.ниже |
18h |
Word |
Magic |
поле указывает на основное предназначение программы |
1Ah |
Byte |
Link Major |
старший номер версии использовавшегося при создании линкера |
1Bh |
Byte |
Link Minor |
младший номер версии использовавшегося при создании линкера (эти 2 поля загрузчик пока игнорирует) |
1Ch |
DWord |
Size of Code |
размер именно программного кода в файле, KERNEL использует это значение для фактического отведения памяти под загружаемую программу, установка этого значения слишком маленьким приведет к выдаче сообщения о нехватке памяти |
20h |
DWord |
Size of Init Data |
размер секции инициализированных данных, очевидно не используется в Windows 95, но используется в NT, назначение аналогично приведенному выше |
24h |
DWord |
Size of UnInit Data |
размер секции неинициализированных данных, |
28h |
DWord |
Entry point RVA |
адрес, относительно Image Base по которому передается управление при запуске программы или адрес инициализации/завершения библиотеки |
2Ch |
DWord |
Base of Code |
RVA секции, которая содержит программный код |
30h |
DWord |
Base of Data |
RVA секции содержащей данные, в реальных экзешниках указывает и на .data и на .bss |
34h |
DWord |
Image Base |
виртуальный начальный адрес загрузки программы (ее первого байта). Должен быть на границе 64 Кб (связано с системой памяти Windows 95) |
38h |
DWord |
Object align |
выравнивание программных секций, должен быть степенью 2 между 512 и 256М включительно, так же связано с системой памяти. При использовании других значений программа не загрузится. |
3Ch |
DWord |
File align |
фактор используемый для выравнивания секций в программном файле. В байтовом значении указывает на границу на которую секции дополняются 0 при размещении в файле. Большое значение приводит к нерациональному использованию дискового пространства, маленькое увеличивает компактность, но и снижает скорость загрузки. Должен быть степенью 2 в диапазоне от 512 до 64К включительно. Прочие значения вызовут ошибку загрузки файла. |
40h |
Word |
OS Major |
старший номер версии ОС необходимой для запуска программы. (нулевое значение не позволяет запустить программу, остальные игнорируются проверялось на OSR2) |
42h |
Word |
OS Minor |
младший номер версии ОС |
44h |
Word |
USER Major |
пользовательский номер версии, задается пользователем при линковке программы и им же и используется |
46h |
Word |
USER Minor |
аналогично, младший номер |
48h |
Word |
SubSys Major |
старший номер версии подсистемы |
4Ah |
Word |
SubSys Minor |
аналогично, младший номер |
4Ch |
DWord |
Reserved |
Зарезервировано |
50h |
DWord |
Image Size |
виртуальный размер в байтах всего загружаемого образа, вместе с заголовками, кратен Object align |
54h |
DWord |
Header Size |
общий размер всех заголовков: DOS Stub + PE Header + Object Table |
58h |
DWord |
File CheckSum |
контрольная сумма всего файла, как и в DOS, ее никто не контролирует, а линкер ее ставит в 0 |
5Ch |
Word |
SubSystem |
операционная подсистема необходимая для запуска данного файла (GUI, консоль...) |
5Eh |
Word |
DLL flags |
указывает на специальные потребности при загрузке, начиная с NT 3.5 устарел и не используется |
60h |
DWord |
Stack Reserve Size |
память требуемая для стека приложения, память резервируется, но выделяется только Stack Commit Size байтов, следующая страница является охранной. |
64h |
DWord |
Stack Commit Size |
объем памяти, отводимой в стеке немедленно после загрузки |
68h |
DWord |
Heap Reserve Size |
максимальный возможный размер локальной кучи |
6Ch |
DWord |
Heap Comit Size |
отводимая при загрузке куча |
70h |
DWord |
Loader Flags |
? начиная с NT 3.5 объявлено неиспользуемым, назначение неясно, но в целом связано с поддержкой отладки |
74h |
DWord |
Num of RVA and Sizes |
указывает размер массива VA/Size который следует ниже, зарезервировано под будущие расширения формата. В данный момент его значение всегда равно 10h |
78h |
DWord |
Export Table RVA |
RVA адрес таблицы экспорта |
7Ch |
DWord |
Export Data Size |
размер таблицы экспорта |
80h |
DWord |
Import Table RVA |
RVA адрес таблицы импорта |
84h |
DWord |
Import Data Size |
размер таблицы импорта |
88h |
DWord |
Resource Table RVA |
RVA адрес таблицы ресурсов |
8Ch |
DWord |
Resource Data Size |
размер таблицы ресурсов |
90h |
DWord |
Exception Table RVA |
RVA адрес таблицы исключений |
94h |
DWord |
Exception Data Size |
размер таблицы исключений |
98h |
DWord |
Security Table RVA |
? адрес таблицы безопасности |
9Ch |
DWord |
Security Data Size |
? размер таблицы безопасности |
A0h |
DWord |
Fix Up's Table RVA |
RVA адрес таблицы настроек |
A4h |
DWord |
Fix Up's Data Size |
размер таблицы настроек |
A8h |
DWord |
Debug Table RVA |
RVA адрес таблицы отладочной информации |
ACh |
DWord |
Debug Data Size |
размер таблицы отладочной информации |
B0h |
DWord |
Image Description RVA |
RVA адрес строки описани модуля |
B4h |
DWord |
Description Data Size |
размер строки описания модуля |
B8h |
DWord |
Machine Specific RVA |
? адрес таблицы значений специфичных для микропроцессора |
BCh |
DWord |
Machnine Data Size |
? размер таблицы значений специфичных для микропроцессора |
C0h |
DWord |
TLS RVA |
указатель на локальную область данных цепочек |
C4h |
DWord |
TLS Data Size |
размер области данных цепочек |
C8h |
DWord |
Load Config RVA |
? |
CCh |
DWord |
Load Config Data Size |
? |
D0h |
08h |
Reserved |
? |
D8h |
DWord |
IAT RVA |
? |
DCh |
DWord |
IAT Data Size |
? размер описанного поля |
E0h |
08h |
Reserved |
? |
E8h |
08h |
Reserved |
? |
F0h |
08h |
Reserved |
? |
Total Structure size |
F8h |
Общий размер заголовка |
CPU Type имеет следующие значения:
014Ch - i386
014Dh - i486
014Eh - i586
0162h - MIPS Mark I (R2000, R3000)
0163h - MIPS Mark II (R6000)
0166h - MIPS Mark III (R4000)
Flags имеет следующие битовые значения:
0000h - это программа
0001h - файл не содержит перемещений и таблицы перемещаемых элементов
0002h - образ в файле можно запускать Если этот бит не установлен, то это обычно указывает на ошибку обнаруженную на этапе линковки
0200h - загружать фиксированно Указывает на то, что программу можно грузить только по адресу, записанному в Image Base, если это невозможно, то такой файл лучше вообще не запускать.
2000h - это библиотека
Magic имеет следующие значения:
0107h - программа должна выполняться в ПЗУ (?)
010Bh - нормальная программа для ОЗУ
(на самом деле можно ставить любое значение, программа грузится нормально)
SubSystem имеет следующие значения:
0001h - Native
0002h - Windows GUI, т.е. окошечная
0003h - Windows Character (консольное приложение)
0005h - OS/2 Character
0007h - Posix Character
DLL Flags имеет следующие битовые значения:
0001h - инициализация библиотеки на процесс
0002h - завершение библиотеки на процесс
0004h - инициализация библиотеки на поток
0008h - завершение библиотеки на поток
Все прочие биты зарезервированы и желательно их установить в 0 значение.