# Assignment: PE file reader --- Лабораторная работа: Чтение PE файла # Подготовка - Прочитайте документацию по формату PE файла: https://learn.microsoft.com/en-us/windows/win32/debug/pe-format - Ознакомьтесь с документацией к Doxygen: https://www.doxygen.nl/manual/ # 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, которые используются при автоматическом тестировании. Используя директивы препорцессора можно выяснить вид компилятора и написать портабельный код: ```c #ifdef __clang__ printf("Hello world from clang!\n"); #elif defined __GNUC__ printf("Hello world from gcc!\n"); #elif defined _MSC_VER printf("Hello world from Visual C!\n"); #else printf("Hello world from somethig else!\n"); #endif ``` ## Смещения Обратите внимание на смещения в файле, некоторые из них абсолютные, а некоторые относительные. Можно вычислить и сохранить все абсолютные смещения для удобства работы с файлом: ```c /// 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](https://clang.llvm.org/docs/AddressSanitizer.html), набор проверок на некорректное использование адресов памяти. Примеры: use-after-free, double-free, выход за пределы стека, кучи или статического блока. - `LSan` — [LeakSanitizer](https://clang.llvm.org/docs/LeakSanitizer.html), проверки на утечки памяти. - `MSan` — [MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), проверяет, что любая используемая ячейка памяти проинициализирована на момент чтения из нее. - `UBSan` — [UndefinedBehaviourSanitizer](https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html), набор базовых проверок на неопределенное поведение. Примеры: переполнение численного типа, 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/ ### Инструкции по сборке и тестированию - [Работа с терминалом](docs/Terminal.md) - [CLion](docs/CLion.md) - [Visual Studio](docs/VisualStudio.md) - [Visual Studio Code](docs/VSCode.md)