Структура exe файла windows
Исследуем формат EXE-файла
Целью работы компилятора является получение EXE-файла. Поэтому, исследуем его структуру.
EXE-файлы появились ещё в DOS и потом они с небольшими изменениями перекочевали в Windows. Формат EXE-файла под Windows называется PE-файлом. Он организован в виде линейного потока данных.
Формат PE-файла
Заголовок MS-DOS |
Программа-заглушка |
Заголовок PE |
Доп. заголовок PE |
Массив DataDir |
Заголовки сегментов |
Тела сегментов |
Остальные области данных |
Заголовок MS-DOS не нов, он используется начиная с MS-DOS версии 2. Если вы пытаетесь запустить Windows-программу под DOS-ом, то программа-заглушка, которая размещена ниже, сообщит о невозможности этого сделать. Если бы заголовок MS-DOS и программа-заглушка не были бы включены в PE-файл, то скорее всего бы это бы привело к сбою.
Залоговок MS-DOS (размер 40H байт)
Адрес | Тип | Имя | Описание |
---|---|---|---|
00h | word | Magic | Магическая сигнатура DOS-файла — два символа «MZ», явно от MZ -club 🙂 |
02h | word | LastByteCount | Количество байт на последней странице файла |
04h | word | PageCount | Количество страниц в файле |
06h | word | RelocCount | Количество релокейшенов |
08h | word | HeaderSize | Размер заголовка в параграфах |
0Ah | word | MinAlloc | Мин. выделение памяти в параграфах |
0Ch | word | MaxAlloc | Макс. выделение памяти в параграфах |
0Eh | word | InitSS | Начальное (относительное) значение регистра SS |
10h | word | InitSP | Начальное значение регистра SP |
12h | word | CheckSum | Контрольная сумма |
14h | word | InitIP | Начальное значение регистра IP |
16h | word | InitCS | Начальное (относительное) значение регистра CS |
18h | word | RelocAddr | Адрес на релокейшены и программу-заглушку |
1Ah | word | OverlayCount | Количество оверлеев |
1Ch | word | Res1[4] | Зарезервировано |
24h | word | OEMIdentifier | Для OEMInfo |
26h | word | OEMInfo | Информация о программе |
28h | word | Res1[10] | Зарезервировано |
3Ch | dword | PEHeaderAddr | Адрес в файле заголовка PE |
Для Windows-программы заголовок MS-DOS не содержит релокейшины (пока даже и не знаю что это такое), то есть Relocations = 0, поэтому RelocAddr указывает сразу на программу-заглушку. Но нам важен заголовок PE, его адрес находиться в PEHeaderAddr.
Залоговок PE (размер 18H байт)
Адрес | Тип | Имя | Описание |
---|---|---|---|
00h | dword | Magic | Магическая сигнатура PE-файла 4550H или «PE», 0H, 0H |
04h | word | CPUType | Тип процессора |
06h | word | SectionCount | Количество сегментов |
08h | dword | DateTime | Дата/время создания/модификации линкером |
0Сh | dword | SymbolTableAddr | Адрес местонахождения таблицы символов |
10h | dword | SymbolTableSize | Размер таблицы символов |
14h | word | OptionalHeaderSize | Размер доп. заголовка PE |
16h | word | Flags | Предназначение программы |
Сразу за основным заголовком идёт дополнительный заголовок PE.
Доп. залоговок PE (размер 18H — 77H байт)
Адрес | Тип | Имя | Описание |
---|---|---|---|
18h | word | Magic | Всегда 10Bh |
1Ah | byte | MajorLinkVer | Версия линкера, создавшего данный файл |
1Bh | byte | MinorLinkVer | — |
1Ch | dword | CodeSize | Размер исполнительного кода |
20h | dword | InitDataSize | Размер инициализированных данных |
24h | dword | UnInitDataSize | Размер неинициализированных данных |
28h | dword | EntryPointAddr | Адрес, относительно ImageBase, по которому передаётся управление при запуске программы или адрес инициализации/завершения библиотеки |
2Ch | dword | CodeBase | Относительное смещение сегмента кода |
30 | dword | DataBase | Относительное смещение сегмента неинициализированных данных |
34h | dword | ImageBase | Предподчтительный адрес для загрузки исполнимого файла (по умолчанию 400000H) |
38h | dword | SectionAlign | Выравнивание программных секций (по умолчанию 1000H) |
3Ch | dword | FileAlign | Минимальная гранулярность сегментов, то есть размер сегментов должен быть кратен FileAlign, должен быть равен значению степени 2 между 200H и 10000H (по умолчанию 200H) |
40h | word | MajorOSVer | Старший номер версии OS, необходимый для запуска программы |
42h | word | MinorOSVer | Младший номер версии OS |
44h | word | MajorImageVer | Пользовательский старший номер версии, задается пользователем при линковке программы и им же и используется |
46h | word | MinorImageVer | Пользовательский младший номер версии, задается пользователем при линковке программы и им же и используется |
48h | word | MajorSubSysVer | Старший номер версии Win32 |
4Ah | word | MinorSubSysVer | Младший номер версии Win32 |
4Ch | dword | Res1 | — |
50h | dword | ImageSize | Виртуальный размер в байтах всего загружаемого образа, вместе с заголовками, кратен ObjectAlign |
54h | dword | HeaderSize | Общий размер всех заголовков: MS-DOS, PE, доп PE и всех сегментов |
58h | dword | CheckSum | Контрольная сумма (не используется и равна 0) |
5Ch | word | SubSystem | Подсистема, необходимая для запуска данного файла //(0 — неизвестная подсистема, 1 — не требует подсистему, 2 — Windows GUI, 3 — Windows консоль. ) |
5Eh | word | DllFlags | Специальные флаги при загрузке, начиная с NT 3.5 не используются |
60h | dword | StackReserveSize | Память, требуемая для стека приложения, память резервируется, но выделяется только StackCommitSize байтов, следующая страница является охранной. Когда приложение достигает этой страницы, то страница становится доступной, а следующая страница — охранной, и так до достижения нижней границы, после чего Windows убивает программу с сообщением о конце стека |
64h | dword | StackCommitSize | Объем памяти, отводимый в стеке немедленно после загрузки |
68h | dword | HeapReserveSize | Максимальный возможный размер локального хипа |
6Ch | dword | HeapComitSize | Отводимый при загрузке хип |
70h | dword | LoaderFlags | Данный параметр устарел |
74h | dword | DataDirSize | Указывает размер массива DataDir, расположенный ниже (по умолчанию 10h) |
Далее идёт массив DataDir, 8-байтные элементы которого состоят из двух 4-х байтных: адрес и размер.
Массив DataDir (размер 78H — F8H байт)
Адрес | Тип | Имя | Описание |
---|---|---|---|
78h | qword | ExportDir | Каталог экспортируемых объектов |
80h | qword | ImportDir | Каталог импортируемых объектов |
88h | qword | ResourceDir | Каталог ресурсов |
90h | qword | ExceptionDir | Каталог исключений |
98h | qword | SecurityDir | Каталог безопастности |
A0h | qword | BaseRelocDir | Каталог переадресаций |
A8h | qword | DebugDir | Отладочный каталог |
B0h | qword | CopyrightDir | Каталог описаний |
B8h | qword | CpuSpecDir | Каталог значений, специфичных для процессора |
C0h | qword | TLSDir | Каталог TLS (Thread local storage — локальная память потоков) |
C8h | qword | ConfigDir | Каталог конфигураций загрузки |
D0h | qword | ResDir11 | — |
D8h | qword | ResDir12 | — |
E0h | qword | ResDir13 | — |
E8h | qword | ResDir14 | — |
F0h | qword | ResDir15 | — |
Элемент массива DataDir (размер 8 байт)
Адрес | Тип | Имя | Описание |
---|---|---|---|
00h | dword | Addr | Адрес каталога |
04h | dword | Size | Размер каталога |
Далее идёт подряд несколько сегментов, количество указано в SectionCount.
Заголовок сегмента (размер 2Ch байт)
Адрес | Тип | Имя | Описание | |||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
00h | char[8] | SectName | Имя секции, если имя Практически любая программа под Windows работает с такими её DLL-ками: kernel32.dll, user32.dll, gdi32.dll и т.д.. Поэтому, EXE-шник должен уметь импортировать функции данных библиотек, то есть работать с каталогом импорта ImportDir. Каталог импорта сразу же начинается с таблицы импорта ImportDirTable, которая описывает остальную информацию об импорте. Такая таблица состоит из элементов ImportDirTableItem, указывающих, как минимум, на каждую импортируемую библиотеку. Последний элемент, указывающий на конец таблицы, заполнен нулями. Элемент таблицы каталога импортируемых объектов ImportDirTableItem (размер 14h байт)
Параметр LibName указывает на имя библиотеки, которое должно заканчиваться нулём. FuncNameList указывает на список адресов (0-ой адрес — конец списка), по которым находится сначала Hint — (укороченный идентификатор точки входа), а затем имя функции, заканчивающееся нулём. Параметр FuncAddrList указывает на точно такой же список адресов, находящийся (по моим наблюдениям) перед ImportDirTable. Формат EXE-файла здесь описан не полностью. Остальное будет описано позже. Однако, этого уже достаточно для создания компилятора. Для глубокого изучения EXE-шника, написана специальная программа «EXE-исследователь». Последнюю версию данной программы можно скачать на страничке Download Структура exe файла windowsСтруктура COM и EXE файлов Структура COM файла Наверное всем известны файлы с расширением COM. Главным COM файлом на ПК является вездесущий command.com (командный файл DOS) . Что же такое COM файл, как он работает и запускается ? В основном COM файлы пишут на языке Ассемблера, но это не обязательно. Нописать файл можно на любом языке, который можно потом компилировать. Пример небольшого COM файла выводящего на экран сообщение: .286 ; Устанавливаем тип процессора mov ah,4Ch ;Функцию DOS (прерывание 21h) 4Ch message db «My first COM programms»,13,10,»$» ;Придаем значение переменной message Использую определение прерывания можно сказать как действует эта программа. mov ah,09h В первой строке в регистр ah заносится значение 09, где h означает, что это число в шестнадцатеричной системе исчисления, во второй строке указывается прерывание, в данном случае это 21, (h тоже самое, что и в первой строке) т.е. прерывание DOS. Получив такую команду, процессор на время перестает выполнять текущие операции и передает управление находящейся в оперативной памяти программе, обработчику функции 09h. После выполнения всех этих операций процессор возвращается к выполнению ранее выполняемой операции. Ниже приведены два варианта кода COM — файла до «инфицирования» вирусом и после: .286 ;Задаем тип процессора jmp coob ; Тело программы начинается с метки coob mov ah,4Ch coob: ;Начало тела программы message db «Файл не инфицирован»,13,10,»$» ; Строка с текстом для вывода на экран mov ah,4Ch ;Выходим из программы ends code ; Конец сегмента кода программы .286 ;Задаем тип процессора jmp virus ; JMP изменены таками образом, чтобы вирус получил управление mov ah,4Ch virus: mov . jmp coob ends code ; Конец сегмента кода программы Ниже приведена структура инфицированного файла Хвост COM программы Тело вируса Оригинальное начало Структура EXE файла COM файлы пишут в основном на языке Ассемблера, но они постепенно устаревают и на смену им приходят огромные по своим размерам и сложные по своей структуре EXE файлы. Примерная структура EXE файла: Тело программы Конец программы Заголовок EXE файла — содержет данные необходимые для загрузки программы Первая и последняя часть программы являются обязательными для всех EXE файлов, а вторая часть вовсе не обязательна. Вы можете просто взять её и пропустить. Приводить виды «инфицированного» и «не инфицированного» EXE файла я не буду, т.к. в отличие от COM вирусов, у EXE вирусов есть множество способов заражения. Подробно о каждом из них я расскажу Вам в следующих выпусках рассылки, а сейчас только перечислю названия основных из них: OVERWRITE — вирусы, замещающие программный код COMPANION — вирусы-спутники PARASITIC — вирусы, внедряющиеся в программу метод переименования EXE файла внедрение способом переноса внедрение способом сдвига
Стандартный вирус Не только файлы имеют определенную структуру, но и вирусы для осуществления своей вредоносной деятельности должны соблюдать определенную структуру своего тела и действовать в определенном порядке. Интересно, а кто создал первый вирус ? С момента появления вычислительной техники программистов и электронщиков интересовала одна тема: самовопроизводяющиеся и самораспространяющиеся механизмы. Первым кто попробовал осуществить эту идею в 1951 году был Дж. фон Нейман. Но Нейман и не думал использовать эти материалы в каких либо разрушительных целях, но другие люди, воспользовавшись его материалами и знаниями в этой области начали создавать различных вредоносные программы — компьютерные вирусы. Но что же побудило этих людей пойти на это. Ученые считают, что людей побуждают создавать компьютерные вирусы некоторые факторы: — озорство и одновременное непонимание всех последствий распространения вируса Как и у биологических, у компьютерных вирусов есть определенные стадии «развития»: — латентный период — в течение которого вирус себя никак не проявляет (для того, чтобы «замести следы» источника его попадания на «инфицированный» ПК) Нелепо думать, что компьютерные вирусы могут содержаться везде. Особенно это проявляется на пользователях «чайниках» которые могут часами просиживать перед экраном и с упортством проверять файлы, которые никак не могут содержать вирусы. Ведь вирус — это программа, следовательно имеет смысл внедряться только в другие программы. В связи с этим компьютерные вирусы подразделяют еще на: ФАЙЛОВЫЕ Вирусы могут внедряться в следующие компоненты системы: — файлы с компонентами DOS С каждым днем этот список растет. Чаще всего вирусы внедряются в файлы COM, EXE и DOC ЗАГРУЗОЧНЫЕ загрузояные вирусы распространяются в BOOT секторах дисков и дискет — BR — на дискетах При загрузке этих дискет выполняется программа в BOOT секторе этого диска, а следовательно и сам вирус. Плюс этого типа вирусов в том, что если прочитать этот инфицированный диск, то на нем не окажется ни одного файла. ФАЙЛОВО-ЗАГРУЗОЧНЫЕ ВИРУСЫ Вирусы данного типа обладают большей инфицирующей способностью, так как они распространяются в BOOT секторах диска и в файлах на этом диске. СПОСОБЫ ЗАРАЖЕНИЯ СРЕДЫ ОБИТАНИЯ Вирусы могут «имплантироваться» в следующие места файлов: — конец файла |