Assignment: PE file reader
Лабораторная работа: Чтение PE файла
Подготовка
- Прочитайте документацию по формату PE файла: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format
PE файл
PE файлы используются в ОС Windows для хранения объектных и исполняемых файлов.
Для "совместимости" со старыми операционными системами PE файл начинается с корректной программы для MS-DOS, которая выводит сообщение "This program cannot be run in DOS mode." Поэтому заголовок и данные в PE файле смещены от начала файла и эффективное смещение записано со смещением 0x3c
от начала файла.
По данному смещению записано magic value `PE\0\0', за которым следует заголовок и данные.
Для чтения заголовков удобно использовать упакованные структуры.
Упаковка данных
Для упаковки стркутур следует ипользовать #pragma packed(...)
для компилятора Visual C и __attribute__((packed))
для компиляторов gcc и clang, которые используются при автоматическом тестировании. Используя директивы препорцессора можно выяснить вид компилятора и написать портабельный код:
#ifdef __GNUC__
printf("Hello world from gcc!\n");
#elif defined __clang__
printf("Hello world from clang!\n");
#elif defined _MSC_VER
printf("Hello world from Visual C!\n");
#else
printf("Hello world from somethig else!\n");
#endif
Смещения
Обратите внимание на смещения в файле, некоторые из них абсолютные, а некоторые относительные. Можно вычислить и сохранить все абсолютные смещения для удобства работы с файлом:
/// Structure containing PE file data
struct PEFile
{
/// @name Offsets within file
///@{
/// Offset to a file magic
uint32_t magic_offset;
/// Offset to a main PE header
uint32_t header_offset;
/// Offset to an optional header
uint32_t optional_header_offset;
/// Offset to a section table
uint32_t section_header_offset;
///@}
/// @name File headers
///@{
/// File magic
uint32_t magic;
/// Main header
struct PEHeader header;
/// Optional header
struct OptionalHeader optional_header;
/// Array of section headers with the size of header.number_of_sections
struct SectionHeader *section_headers;
///@}
...
};
Задание
- Необходимо реализовать чтение PE файла и вывод одной его секции в файл. Формат использования такой:
./section-extracter <source-pe-file> <section-name> <output-bin-image>
- Код размещается в директории
solution/src
, заголовочные файлы ищутся вsolution/include
. - Код должен быть портабельный и корректно работать с компиляторами gcc, clang, visual C.
- Код должен быть документирован для автоматической генерации документации в формате
doxygen
.
Система сборки и тестирования
Для сборки кода вам предоставлена система сборки на языке CMake, самим писать систему сборки не требуется.
-
В зависимости от платформы и компилятора, система сборки поддерживает несколько конфигураций с динамическими анализаторами (санитайзерами). Санитайзеры могут дать подробную информацию о возможных и реальных ошибках в программе вместо классического сообщения о segmentation fault. Выбрать подходящую конфигурацию вы можете с помощью переменной
CMAKE_BUILD_TYPE
:-
ASan
— AddressSanitizer, набор проверок на некорректное использование адресов памяти. Примеры: use-after-free, double-free, выход за пределы стека, кучи или статического блока. -
LSan
— LeakSanitizer, проверки на утечки памяти. -
MSan
— MemorySanitizer, проверяет, что любая используемая ячейка памяти проинициализирована на момент чтения из нее. -
UBSan
— UndefinedBehaviourSanitizer, набор базовых проверок на неопределенное поведение. Примеры: переполнение численного типа, null-pointer dereference.
-
-
Если в вашей системе имеется статический анализатор
clang-tidy
, он будет запущен во время компиляции программы. Список проверок описан в файлеclang-tidy-checks.txt
. Вы можете добавить свои проверки в конец этого файла. -
Директория
tester
содержит код и изображения для тестирования вашей программы. Для запуска тестов используется CTest. -
Поддержана интеграция системы сборки со средами разработки CLion, Visual Studio и Visual Studio Code.
Чтобы система сборки работала на вашей системе, вам необходимо:
Linux и MacOS
- Компилятор (
gcc
/clang
) иcmake
(проверьте, чтоcmake
версии 3.12 или выше) - Если вы хотите использовать санитайзеры с GCC, установите
libasan
,liblsan
иlibubsan
с помощью пакетного менеджера (названия могут отличаться). - Если вы хотите использовать санитайзеры с Clang, на некоторых системах вам может понадобиться пакет
compiler-rt
. - Если вы хотите пользоваться
clang-tidy
, установитеclang-tools-extra
.
Windows
- Какая-либо среда разработки (CLion, Visual Studio, Visual Studio Code)
- Если вы хотите пользоваться
clang-tidy
, скачайте LLVM: https://github.com/llvm/llvm-project/releases (найдите установщик win64 под одной из версий) - Для VS Code требуется отдельно поставить Visual Studio (с сайта Microsoft) и CMake: https://cmake.org/download/