Останнє оновлення: 16 вересня 2026

PPTX Reverse Engineering: Understanding PowerPoint Files Internally

Реверс-інженерія файлів PPTX: посібник розробника

Сучасні презентаційні набори живлять усе — від інвесторських презентацій до внутрішніх квартальних метрик. Але якщо вам доводилося програмно витягувати текст, замінювати шаблони під час виконання, створювати автоматичні генератори слайдів або очищати конфіденційні презентації, ви, ймовірно, швидко зрозуміли: стандартні бібліотеки високого рівня для презентацій можуть виглядати як непередбачувана чорна скринька.

Коли бібліотеки, такі як python-pptx, Apache POI або OpenXML SDK, досягають своїх меж — або вводять недокументовані помилки розмітки — єдиний вихід — це глибоке занурення. Вам потрібно зрозуміти, що таке презентація PowerPoint на рівні байтів і схеми.

У цьому глибокому зануренні ми піднімемо завісу над форматом .pptx, розпакуємо його внутрішню структуру, простежимо граф зв’язків, розберемо ієрархії малюнків і розглянемо практичні стратегії зворотного інжинірингу, аналізу та маніпулювання презентаціями за допомогою чистого коду.

1. Що насправді таке файл .pptx?

По суті, файл .pptx не є пропрієтарним монолітним бінарним файлом, як старий формат .ppt 1990‑х років. З того часу, як Microsoft представила Office Open XML (ECMA-376 і ISO/IEC 29500), сучасні документи Office є архівами Open Packaging Conventions (OPC).

Простими словами: файл .pptx — це просто zip‑архів, що містить XML‑документи та медіа‑ресурси, організовані у детермінованому дереві каталогів.

Ви можете довести це за секунди, використовуючи стандартні інструменти терміналу:

# Rename the extension and unpack it
cp presentation.pptx presentation.zip
unzip presentation.zip -d presentation_unpacked/
cd presentation_unpacked/
tree -L 2

Отримане дерево каталогів виглядає надзвичайно послідовно:

.
├── [Content_Types].xml
├── _rels/
│   └── .rels
├── docProps/
│   ├── app.xml
│   └── core.xml
└── ppt/
    ├── presentation.xml
    ├── _rels/
    ├── slides/
    ├── slideLayouts/
    ├── slideMasters/
    ├── theme/
    └── media/

Кожен окремий візуальний ресурс, перехід, успадкування шаблону слайдів, координати текстового поля та векторна графіка закодовані в цій ієрархії файлів.

2. Будова пакету: ключові підсистеми

Щоб ефективно розбирати презентації, ви повинні розуміти функції кожного компоненту верхнього рівня.

[Content_Types].xml

Це маніфест входу для читача OPC. Він зіставляє розширення файлів та явні внутрішні назви частин зі стандартизованими типами MIME/контенту. Якщо ви створите новий слайд або додасте зображення і не задекларуєте його у [Content_Types].xml, PowerPoint оголосить презентацію пошкодженою і запропонує відновлення.

Приклад фрагмента:

<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
  <Default Extension="xml" ContentType="application/xml"/>
  <Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
  <Default Extension="png" ContentType="image/png"/>
  <Override PartName="/ppt/presentation.xml" 
            ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/>
</Types>

Граф зв’язків _rels/

Одним із найважливіших концептів у OpenXML є непряме посилання через відношення. Частини рідко вказують безпосередньо на сирі шляхи файлів. Замість цього файл (наприклад, slide1.xml) має пов’язаний файл відношень, розташований у сусідській папці _rels (наприклад, _rels/slide1.xml.rels).

Відношення визначають:

  • Гіперпосилання (r:id="rId2", TargetMode=“External”)
  • Зображення та аудіодоріжки, збережені в ppt/media/
  • Вказівники успадкування макету (slideLayout1.xml)
  • Слайди нотаток, коментарі та вбудовані шрифти

docProps/ (Метадані)

  • core.xml: метадані Dublin Core — автор, назва, дата створення, мітка часу модифікації.
  • app.xml: специфічна для застосунку статистика — версія PowerPoint, загальна кількість слайдів, кількість прихованих слайдів, кількість слів, назви шаблонів презентації.

ppt/ (Двигун презентації)

Тут розташована фактична презентація:

  • presentation.xml: Основний каркас. Він реєструє ідентифікатори слайдів, розміри слайдів, посилання на майстер нотаток та налаштування шрифту за замовчуванням.
  • slides/: Окремі слайди (slide1.xml, slide2.xml тощо).
  • slideLayouts/: Основні структурні шаблони (Титульний слайд, Два стовпці, Заголовок розділу).
  • slideMasters/: Глобальні стилі, палітри за замовчуванням, заповнення фону та успадкування заповнювачів.
  • theme/: Колірні палітри (акцент 1‑6, темні/світлі варіанти) та схеми шрифтів (основні/додаткові шрифти).
  • media/: Оригінальні зображення (PNG, JPEG, SVG), аудіо та відеофайли.

3. Розбір слайду: діалекти PresentationML (p:) та DrawingML (a:)

Коли ви відкриваєте ppt/slides/slide1.xml, ви стикаєтеся з двома основними XML‑просторами імен:

  1. PresentationML (p:): Керує структурними елементами презентації (слайди, дерева форм, групи полотна).
  2. DrawingML (a:): Керує типографікою, геометрією, 2D‑координатами, градієнтними заповненнями та векторним рендерингом.

Ось спрощений приклад того, як виглядає стандартна текстова форма:

<p:sp>
  <!-- 1. Non-visual shape properties (Identifiers, names) -->
  <p:nvSpPr>
    <p:cNvPr id="4" name="Title Box 1"/>
    <p:cNvSpPr>
      <a:spLocks noGrp="1"/>
    </p:cNvSpPr>
    <p:nvPr>
      <p:ph type="title"/>
    </p:nvPr>
  </p:nvSpPr>

  <!-- 2. Visual shape properties (Position, size, geometry) -->
  <p:spPr>
    <a:xfrm>
      <a:off x="1524000" y="1143000"/>
      <a:ext cx="9144000" cy="1828800"/>
    </a:xfrm>
    <a:prstGeom prst="rect">
      <a:avLst/>
    </a:prstGeom>
    <a:solidFill>
      <a:schemeClr val="accent1"/>
    </a:solidFill>
  </p:spPr>

  <!-- 3. Text Body (Paragraphs, runs, styling) -->
  <p:txBody>
    <a:bodyPr rtlCol="0" anchor="ctr"/>
    <a:lstStyle/>
    <a:p>
      <a:r>
        <a:rPr lang="en-US" sz="3200" b="1"/>
        <a:t>Mission Critical Architecture</a:t>
      </a:r>
    </a:p>
  </p:txBody>
</p:sp>

Важливі одиниці вимірювання: EMU та соті пункту

Зверніть увагу на числа координат у <a:xfrm>:

  • x=\"1524000\"
  • cx=\"9144000\"

Це англійські метричні одиниці (EMU).

  • $1 \text{ inch} = 914,400 \text{ EMUs}$
  • $1 \text{ cm} = 360,000 \text{ EMUs}$
  • $1 \text{ pt} = 12,700 \text{ EMUs}$

EMUs дозволяють цілим числам представляти точні дроби як дюймів, так і міліметрів без помилок округлення з плаваючою комою на різних апаратних архітектурах.

Зверніть також увагу на розмір шрифту:

  • sz="3200" означає 32.00 pt. Розміри шрифтів у DrawingML вимірюються в сотих частинах пункту.

4. Ланцюжок успадкування: чому форми успадковують невидимі стилі

Одним із найпоширеніших підводних каменів при реверс-інженерії файлів PPTX є припущення, що візуальне оформлення форми повністю задекларовано у її власному slideX.xml.

На практиці OpenXML спирається на сувору 4-рівневу каскадну модель успадкування:

[Theme: ppt/theme/theme1.xml]
[Slide Master: ppt/slideMasters/slideMaster1.xml]
[Slide Layout: ppt/slideLayouts/slideLayout1.xml]
[Slide: ppt/slides/slide1.xml]

Якщо текстове поле у slide1.xml містить:

<a:p>
  <a:r>
    <a:t>Revenue Projections</a:t>
  </a:r>
</a:p>

У цьому фрагменті (<a:r>) не вказано жодного шрифту, жодного явного кольору та жодного розміру. Щоб зрозуміти, як PowerPoint відображає цей текст, ваш парсер повинен:

  1. Визначити тип заповнювача (<p:ph type=\"title\"/>).
  2. Прочитати макет, зазначений у slide1.xml.rels.
  3. Перевірити, чи slideLayout1.xml містить перевизначення стилів для цього заповнювача.
  4. Використати slideMaster1.xml як резервний варіант для стилів текстового тіла заголовка за замовчуванням.
  5. Відстежити кольорові токени, такі як accent1 або tx1, у theme1.xml, щоб знайти шістнадцятковий код кольору.

Якщо пропустити цей граф успадкування, ваш парсер неправильно прочитає стилі, пропустивши шрифти, розміри шрифтів та прив’язки макету.

5. Практичний процес зворотного інжинірингу

Коли потрібно дослідити, як працює певна функція PowerPoint «під капотом» (наприклад, переходи morph, складні таблиці, векторні контури), дотримуйтесь цього емпіричного підходу:

Крок 1: Створити мінімальну “Diff Pair”

  1. Відкрийте PowerPoint і створіть порожній слайд.
  2. Збережіть його як before.pptx.
  3. Застосуйте саме одну зміну, яку ви хочете розкрити (наприклад, додайте тінь до кола, змініть стиль маркера, вставте вбудоване відео).
  4. Збережіть його як after.pptx.

Крок 2: Розпакувати обидва архіви

unzip before.pptx -d before/
unzip after.pptx -d after/

Крок 3: Форматувати XML

Необроблений XML у архівах Office зазвичай позбавлений відступів і символів нового рядка. Перед порівнянням відформатуйте файли:

find before/ after/ -name "*.xml" -exec xmllint --format {} --output {} \;

Крок 4: Запустити уніфікований Diff

diff -uNr before/ after/ > changes.patch

Перегляд changes.patch показує точну назву тегу, атрибут простору ієрархії контейнера, які додав PowerPoint. Це найшвидший спосіб виявити недокументовані або складні властивості схеми без копання в тисячах сторінок документації ECMA-376.

6. Створення власного мікро-двигуна: розпакування, модифікація, повторне пакування

Іноді ви не хочете важку корпоративну залежність, таку як Apache POI або Microsoft OpenXML SDK — особливо в легких безсерверних середовищах (AWS Lambda, Cloudflare Workers, edge‑вузли).

Ось самодостатній шаблон Python, який демонструє, як безпечно розпакувати PPTX у пам’яті, вставити власні дані за допомогою інструментів стандартної бібліотеки та знову упакувати його:

import zipfile
import io
import xml.etree.ElementTree as ET

def modify_slide_title(input_pptx_bytes: bytes, new_title: str) -> bytes:
    input_zip = zipfile.ZipFile(io.BytesIO(input_pptx_bytes))
    output_buffer = io.BytesIO()
    
    with zipfile.ZipFile(output_buffer, "w", zipfile.ZIP_DEFLATED) as output_zip:
        for item in input_zip.infolist():
            content = input_zip.read(item.filename)
            
            # Target slide 1
            if item.filename == "ppt/slides/slide1.xml":
                namespaces = {
                    'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
                    'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'
                }
                
                # Register namespaces to preserve prefixes
                for prefix, uri in namespaces.items():
                    ET.register_namespace(prefix, uri)
                    
                root = ET.fromstring(content)
                
                # Find title placeholder text run
                for title_run in root.findall(".//p:sp[p:nvSpPr/p:nvPr/p:ph[@type='title']]//a:t", namespaces):
                    title_run.text = new_title
                    break
                
                content = ET.tostring(root, encoding="utf-8", xml_declaration=True)
            
            output_zip.writestr(item, content)
            
    return output_buffer.getvalue()

Ключові підводні камені при модифікації файлів на рівні сирих байтів:

  1. Збереження простору імен: XML‑парсери часто переписують префікси (xmlns:p може стати xmlns:ns0). Хоча це дійсний XML, сувора внутрішня валідація схеми PowerPoint іноді відхиляє нестандартні псевдоніми префіксів. Реєструйте простори імен явно.
  2. Методи стиснення ZIP: Переконайтеся, що ви записуєте файли назад, використовуючи стандартне стиснення deflate (zipfile.ZIP_DEFLATED).
  3. Скидання потоку: Завжди перевіряйте, що ваш буфер zip закривається і повністю скидається перед передачею байтів далі.
  4. Збереження зв’язків: Якщо ви видаляєте слайд, ви також повинні видалити його запис у ppt/presentation.xml, видалити його зв’язок у ppt/_rels/presentation.xml.rels і очистити його тип вмісту у [Content_Types].xml.

7. Розгляд продуктивності та безпеки

Реверс-інженерія файлів PPTX — це не лише редагування слайдів; це також аудит того, що потрапляє у ваші системи.

Безпека: Billion Laughs та XXE

Оскільки файли PPTX парсять XML, будь‑який серверний конвеєр, що приймає презентації, надіслані користувачами, вразливий до:

  • Впровадження зовнішньої сутності XML (XXE): Шкідливий XML, який намагається отримати доступ до /etc/passwd або запитати внутрішні кінцеві точки метаданих хмари (http://169.254.169.254/).
  • Атаки розширення сутностей (Billion Laughs): Експоненційні цикли сутностей, що вичерпують оперативну пам’ять системи.

Пом’якшення: Завжди вимикайте resolve_entities, load_dtd та зовнішнє мережеве розв’язання у вашому XML‑парсері (наприклад, використовуючи defusedxml у Python).

Безпека: Навантаження Макросів та Приховані Потоки

Перевіряйте файли на наявність вмісту .pptm, що маскується під розширенням .pptx. Слідкуйте за ppt/vbaProject.bin, який містить скомпільований код Visual Basic. У стандартних .pptx файлах код VBA заборонений; виявлення посилань на бінарні корисні навантаження у зв’язках має негайно викликати позначки карантину.

Висновок

Зворотний інжиніринг .pptx файлів розкриває таємниці програмного забезпечення для презентацій. Коли ви розумієте, що файли PowerPoint — це просто структуровані zip‑пакети, заповнені координатами, посиланнями на схеми та деревами XML‑зв’язків, ви більше не обмежені існуючими сторонніми абстракціями.

Незалежно від того, чи оптимізуєте ви пропускну здатність генерації слайдів, пишете власні автоматизовані санітайзери, чи усуваєте проблеми з рендерингом, прямий погляд на базову архітектуру OpenXML дає вам повний контроль над конвеєром презентації.

Поширені запитання (FAQ)

**Q: Чи можна конвертувати .pptx у звичайну папку та редагувати файли безпосередньо в IDE?

A1: Так, ви можете розпакувати архів, відредагувати XML у редакторі типу VS Code і знову заархівувати вміст каталогу, щоб відкрити його у PowerPoint.

**Q: Чому PowerPoint повідомляє, що мій вручну змінений файл PPTX потребує ремонту?

A2: Це зазвичай трапляється, якщо ви внесли некоректний XML, пропустили новий ресурс у файлі [Content_Types].xml або залишили «повішений» посилання у пов’язаному файлі .rels.

**Q: Яку одиницю вимірювання використовує PowerPoint для позицій та відступів форм?

A3: PowerPoint використовує English Metric Units (EMUs), де 1 дюйм дорівнює 914 400 EMU, а 1 пункт — 12 700 EMU.

**Q: Як я можу програмно витягнути усі зображення з презентації без зовнішніх бібліотек?

A4: Просто відкрийте файл .pptx за допомогою будь-якої стандартної zip‑утиліти та витягніть усі бінарні файли, розташовані у каталозі ppt/media/.

**Q: Чи безпечно розбирати (парсити) завантажені користувачами PPTX‑файли за допомогою стандартних XML‑парсерів?

A5: Ні, вам потрібно посилити ваш парсер або використовувати безпечні обгортки, такі як defusedxml, щоб блокувати атаки XML External Entity (XXE) та zip‑бомби.

Дивіться також