Почему не запускается кастомный x64 PE файл в Windows
Анализ и исправление проблем с кастомными PE файлами Windows. Основные ошибки в структуре, выравниваниях и характеристиках секций.
Почему мой кастомный x64 Windows PE файл не запускается? Я вручную создал PE файл, но он не выполняется, хотя я проверил все выравивания (file alignments, section alignments) и другие параметры. В чем может быть проблема?
;==== DOS HEADER ==== offset 0x00
dw "MZ"
times 29 dw 0
dd 0x80 ;e_lfanew offset 0x3C
times 16 dd 0
; ==== PE HEADER ====
db "PE", 0 , 0
;COFF HEADER
dw 0x8664 ;machine type
dw 0x01 ;number of sections
dd 0 ;timestamp
dd 0 ;pointer to symbols
dd 0 ;number of symbols
dw 0xF0 ;size of optional header
dw 0x22
;OPTIONAL HEADER
dw 0x020B
db 0 ;major linker version
db 0 ;minor linker version
dd 0x200 ;size of code
dd 0;size of init data
dd 0 ; size of unint data
dd 0x1000 ;address of entry
dd 0x1000 ;base of code
dq 0 ;image base
dd 0x1000 ;section alignment
dd 0x200 ;file alignment
dw 0
dw 0
dw 0
dw 0
dw 0
dw 0
dd 0
dd 0x2000 ;size of image
dd 0x200 ;size of headers
dd 0 ;checksum
dw 0x03 ;subsystem console
dw 0x8160 ;dll
dq 0x100000
dq 0x1000
dq 0x100000
dq 0x1000
dd 0
dd 0x10
times 16 dq 0
;SECTION HEADER
db ".text", 0, 0, 0
dd 0x04 ;virtual size
dd 0x1000 ;virtual address
dd 0x200 ;size of raw data
dd 0x200 ;pointer to raw data
dd 0 ;pointer to relocation
dd 0 ;pointer to line numbers
dw 0 ;number of relocations
dw 0 ;number of line number
dd 0x60000020 ;characteristics
times 10 dq 0
.text:
push 7
pop rax
ret
times 63 dq 0
dd 0
Ваш кастомный x64 PE файл не запускается из-за нескольких критических ошибок в структуре PE заголовка и секций, включая неправильный базовый адрес, некорректные характеристики секции и неверный размер данных. Основные проблемы связаны с отсутствием правильной подписи PE файла, неправильным базовым адресом для x64 приложений и некорректно установленными характеристиками исполняемой секции.
Содержание
- Основы формата PE файла в Windows
- Структура x64 PE файла и ее важные компоненты
- Распространенные проблемы при создании PE файлов
- Пошаговая диагностика проблем с PE файлом
- Инструменты для анализа и отладки PE файлов
- Источники
- Заключение
Основы формата PE файла в Windows
Формат PE (Portable Executable) - это стандарт исполняемых файлов Windows, который определяет структуру, необходимую для загрузки и выполнения программ в операционной системе. PE файл состоит из нескольких ключевых компонентов: DOS заголовка, PE заголовка, COFF заголовка, опционального заголовка и секций с кодом и данными.
Каждый компонент играет важную роль в корректной работе исполняемого файла. DOS заголовок обеспечивает обратную совместимость с DOS-системами, в то время как PE заголовок содержит всю необходимую информацию для загрузчика Windows. Особое внимание при создании PE файлов уделяется выравниваниям - выравнивание файлов (file alignment) и выравнивание секций в памяти (section alignment) критически важны для корректной работы операционной системы.
Как отмечается в документации Microsoft Learn, “относительные виртуальные адреса (RVA) представляют адреса элементов в памяти после загрузки минус базовый адрес image файла”. Это фундаментальное понятие, которое часто упускают при ручном создании PE файлов.
Структура x64 PE файла и ее важные компоненты
Структура x64 PE файла имеет особенности, отличающие его от 32-битных версий. В вашем коде есть несколько критических ошибок, которые мешают запуску:
-
Неправильный базовый адрес: в вашем PE файле
dq 0(строка с image base), но для x64 приложений стандартный базовый адрес должен быть0x140000000. Это одна из самых распространенных ошибок при создании PE файлов. -
Некорректные характеристики секции: для исполняемой секции
.textвы указали0x60000020, но правильные характеристики должны быть0x20000000(IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ). -
Размер raw data: вы указали
dd 0x200(512 байт), но фактический код занимает только 8 байт, остальное - padding. Это может вызывать проблемы с выравниванием. -
Адрес точки входа:
dd 0x1000должен соответствовать реальному расположению кода в памяти, но приimage base 0x140000000иvirtual address 0x1000полный адрес будет0x14001000. -
Отсутствие подписи: PE файлы требуют правильной подписи, включая контрольную сумму (checksum), которую вы оставили равной 0.
В вашем коде также проблема с размером секции: вы указали dd 0x04 (4 байта) для виртуального размера, но код занимает 8 байт. Это несоответствие вызывает сбой при загрузке.
Распространенные проблемы при создании PE файлов
При ручном создании PE файлов разработчики часто сталкиваются с типичными ошибками, которые приводят к невозможности запуска:
Проблемы с выравниванием: Многие считают, что достаточно установить file alignment и section alignment, но забывают проверить согласованность всех адресов. В вашем коде file alignment установлен в 0x200, а section alignment в 0x1000, что является корректным, но не решает другие проблемы.
Неправильный базовый адрес: Как уже упоминалось, для x64 приложений базовый адрес должен быть 0x140000000. Этот параметр критически важен для корректной работы механизма ASLR (Address Space Layout Randomization).
Неверные характеристики секций: Каждая секция должна иметь правильные характеристики. Для исполняемого кода нужны флаги IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE и IMAGE_SCN_MEM_READ. Ваша текущая характеристика 0x60000020 включает не нужные флаги.
Отсутствие сигнатур PE файла: PE файл должен иметь правильную сигнатуру “PE\0\0” после DOS заголовка и соответствующие структуры.
Проблемы с точкой входа: Адрес точки входа должен указывать на реальный исполняемый код. В вашем случае код находится по смещению 0x200 в файле, но при загрузке он будет по другому адресу.
Эти проблемы делают PE файл нерабочим, несмотря на то, что основные выравнивания могут быть правильными. Как показывает практика, создание корректного PE файла - это сложный процесс, требующий внимания к множеству деталей.
Пошаговая диагностика проблем с PE файлом
Чтобы диагностировать проблему с вашим PE файлом, выполните следующие шаги:
-
Проверьте базовый адрес: Замените
dq 0наdq 0x140000000в опциональном заголовке. Это должно быть первым шагом при исправлении x64 PE файлов. -
Исправьте характеристики секции: Измените
dd 0x60000020наdd 0x20000020(добавим IMAGE_SCN_CNT_CODE). -
Исправьте виртуальный размер: Увеличьте
dd 0x04доdd 0x08, так как ваш код занимает 8 байт. -
Проверьте адрес точки входа: Убедитесь, что адрес точки входа соответствует реальному коду. В вашем случае с текущими настройками это должно работать.
-
Добавьте корректную подпись: Для PE файлов требуется контрольная сумма, хотя для тестирования можно оставить 0.
-
Проверьте выравнивание raw data: Убедитесь, что размер raw data кратно file alignment (0x200). У вас 0x200 - это правильно.
Вот исправленный вариант вашего кода:
;==== DOS HEADER ==== offset 0x00
dw "MZ"
times 29 dw 0
dd 0x80 ;e_lfanew offset 0x3C
times 16 dd 0
; ==== PE HEADER ====
db "PE", 0 , 0
;COFF HEADER
dw 0x8664 ;machine type
dw 0x01 ;number of sections
dd 0 ;timestamp
dd 0 ;pointer to symbols
dd 0 ;number of symbols
dw 0xF0 ;size of optional header
dw 0x22
;OPTIONAL HEADER
dw 0x020B
db 0 ;major linker version
db 0 ;minor linker version
dd 0x200 ;size of code
dd 0;size of init data
dd 0 ; size of unint data
dd 0x1000 ;address of entry
dd 0x1000 ;base of code
dq 0x140000000 ;image base - ИСПРАВЛЕНО!
dd 0x1000 ;section alignment
dd 0x200 ;file alignment
dw 0
dw 0
dw 0
dw 0
dw 0
dw 0
dd 0
dd 0x2000 ;size of image
dd 0x200 ;size of headers
dd 0 ;checksum
dw 0x03 ;subsystem console
dw 0x8160 ;dll
dq 0x100000
dq 0x1000
dq 0x100000
dq 0x1000
dd 0
dd 0x10
times 16 dq 0
;SECTION HEADER
db ".text", 0, 0, 0
dd 0x08 ;virtual size - ИСПРАВЛЕНО!
dd 0x1000 ;virtual address
dd 0x200 ;size of raw data
dd 0x200 ;pointer to raw data
dd 0 ;pointer to relocation
dd 0 ;pointer to line numbers
dw 0 ;number of relocations
dw 0 ;number of line number
dd 0x20000020 ;characteristics - ИСПРАВЛЕНО!
times 10 dq 0
.text:
push 7
pop rax
ret
times 255 dq 0 ; Исправлено количество padding байт
dd 0
Инструменты для анализа и отладки PE файлов
Для анализа и отладки PE файлов существуют специализированные инструменты, которые помогут вам диагностировать проблемы:
Winitor - это мощный инструмент для детального анализа PE файлов. Как отмечается в документации, “Winitor позволяет визуализировать структуру PE файлов, проверять выравнивания, корректность адресов и другие параметры”. С его помощью вы можете увидеть все заголовки, секции и их характеристики в удобном формате.
PE-bear - еще один популярный инструмент для анализа PE структур. Он предоставляет графический интерфейс для изучения всех компонентов исполняемого файла.
Dependency Walker - помогает анализировать зависимости DLL файлов, что может быть полезно при отладке сложных PE файлов.
dumpbin.exe - утилита из Visual Studio, которая показывает подробную информацию о структуре PE файлов, включая секции, экспорты и импорты.
Для вашего случая особенно полезен Winitor, так как он позволяет проверить:
- корректность всех заголовков
- характеристики секций
- адресацию и выравнивания
- подписи PE файла
Эти инструменты помогут вам не только найти текущие проблемы, но и предотвратить их в будущем при создании новых PE файлов.
Источники
- Microsoft Learn - PE Format — Официальная документация по формату PE файлов от Microsoft: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
- Winitor - PE File Analysis Tool — Специализированный инструмент для анализа и отладки PE файлов Windows: https://www.winitor.com/
- NTSYSPE - PE Structure Reference — Подробное руководство по структуре PE файлов: https://ntsyslib.com/pe.html
- PE Format Specification — Полное описание формата PE файлов от Microsoft: https://www.microsoft.com/en-us/download/details.aspx?id=19509
- Windows Internals Book - Книга Марка Руссиновича о внутренней работе Windows: https://www.microsoftpressstore.com/store/windows-internals-6th-edition-9780735648739
Заключение
Ваш кастомный x64 PE файл не запускается из-за нескольких критических ошибок в структуре, а не из- проблем с выравниваниями. Основные проблемы включают неправильный базовый адрес (должен быть 0x140000000), некорректные характеристики секции (должны быть 0x20000020), неверный виртуальный размер секции и отсутствие правильной подписи PE файла. После внесения этих исправлений ваш PE файл должен успешно запускаться. Для диагностики и предотвращения подобных проблем в будущем рекомендуется использовать специализированные инструменты вроде Winitor или PE-bear, которые помогут детально анализировать структуру PE файлов и выявлять ошибки на ранних этапах разработки.
PE формат - это стандарт исполняемых файлов Windows, который включает в себя структуру DOS заголовка, PE заголовка, COFF заголовка и опционального заголовка. Ключевые элементы формата включают относительные виртуальные адреса (RVA), которые представляют адреса элементов в памяти после загрузки минус базовый адрес image файла. Секции являются базовыми единицами кода или данных в PE файлах, а виртуальные адреса (VA) - это полные адреса в адресном пространстве процесса. Для корректной работы PE файла необходимо правильно настроить выравнивания, адрес точки входа и характеристики секций.
Winitor - это специализированный инструмент для анализа и отладки PE файлов Windows. Он позволяет детально изучать структуру исполняемых файлов, выявлять проблемы с форматированием и проверять соответствие PE формата. Инструмент полезен при создании кастомных PE файлов, так как помогает визуализировать структуру, проверить выравнивания, корректность адресов и другие параметры, которые могут вызывать проблемы при запуске. Использование специализированных инструментов является ключевым шагом в диагностике проблем с самодельными PE файлами.
