Poslední aktualizace: 16. září 2026

PPTX Reverse Engineering: Understanding PowerPoint Files Internally

Reverzní inženýrství PPTX soubory: Průvodce pro vývojáře

Moderní prezentační sady pohánějí vše od investičních pitchů po interní čtvrtletní metriky. Ale pokud jste někdy museli programově extrahovat text, nahrazovat šablony za běhu, vytvářet automatizované generátory snímků nebo čistit důvěrné prezentace, pravděpodobně jste si rychle uvědomili: standardní knihovny pro prezentace na vysoké úrovni mohou působit jako nepředvídatelná černá skříňka.

Když knihovny jako python-pptx, Apache POI nebo OpenXML SDK narazí na své limity — nebo zavádějí nezdokumentované chyby rozvržení — jediný způsob ven je skrz. Musíte pochopit, co PowerPointová prezentace ve skutečnosti je na úrovni bajtů a schématu.

V tomto podrobném průzkumu odhalíme formát .pptx, rozbalíme jeho vnitřní strukturu, vystopujeme graf vztahů, rozebíráme hierarchie kreslení a podíváme se na praktické strategie pro reverzní inženýrství, inspekci a manipulaci s prezentacemi pomocí surového kódu.

1. Co je vlastně soubor .pptx?

V jádru není soubor .pptx proprietární monolitický binární soubor jako starý formát .ppt z 90. let. Od chvíle, kdy Microsoft představil Office Open XML (ECMA-376 a ISO/IEC 29500), jsou moderní dokumenty Office archivy podle Open Packaging Conventions (OPC).

Jednoduše řečeno: soubor .pptx je jen zip archiv obsahující XML dokumenty a mediální soubory uspořádané v deterministickém adresářovém stromu.

Můžete to dokázat během několika sekund pomocí standardních nástrojů v terminálu:

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

Výsledný adresářový strom vypadá pozoruhodně konzistentně:

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

Každý vizuální prvek, přechod, dědičnost hlavního snímku, souřadnice textového pole a vektorová grafika jsou zakódovány v této hierarchii souborů.

2. Anatomie balíčku: Klíčové subsystémy

Abyste mohli efektivně reverzně analyzovat prezentace, musíte pochopit odpovědnosti každé komponenty na nejvyšší úrovni.

[Content_Types].xml

Toto je vstupní manifest pro čtečku OPC. Mapuje přípony souborů a explicitní interní názvy částí na standardizované MIME/content typy. Pokud vytvoříte nový snímek nebo přidáte obrázek a nezadáte jej v [Content_Types].xml, PowerPoint označí prezentaci jako poškozenou a vyzve k obnovení.

Ukázkový úryvek:

<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>

Graf vztahů _rels/

Jedním z nejdůležitějších konceptů v OpenXML je nepřímý odkaz prostřednictvím vztahů. Části zřídka ukazují přímo na surové cesty k souborům. Místo toho má soubor (např. slide1.xml) přidružený soubor vztahů umístěný ve vedlejším adresáři _rels (např. _rels/slide1.xml.rels).

Vztahy definují:

  • Hyperlinky (r:id=\"rId2\", TargetMode="External")
  • Obrázky a zvukové stopy uložené v ppt/media/
  • Ukazatele dědičnosti rozvržení (slideLayout1.xml)
  • Poznámkové snímky, komentáře a vložená písma

docProps/ (Metadata)

  • core.xml: metadata Dublin Core — autor, název, datum vytvoření, časová značka úpravy.
  • app.xml: aplikačně specifické statistiky — verze PowerPointu, celkový počet snímků, počet skrytých snímků, počet slov, názvy šablon prezentace.

ppt/ (Prezentace)

Zde se nachází skutečná prezentace:

  • presentation.xml: Hlavní struktura. Registruje ID snímků, rozměry velikosti snímků, odkazy na hlavní poznámky a výchozí nastavení písma.
  • slides/: Jednotlivé snímky (slide1.xml, slide2.xml, atd.).
  • slideLayouts/: Hlavní strukturální předvolby (titulní snímek, dva sloupce, záhlaví sekce).
  • slideMasters/: Globální styly, výchozí palety, výplně pozadí a dědičnost zástupných prvků.
  • theme/: Barevné palety (akcent 1 až 6, tmavé/světlé varianty) a schémata písem (hlavní/vedlejší písma).
  • media/: Surové obrázky (PNG, JPEG, SVG), audio a video soubory.

3. Rozbor snímku: Dialekty PresentationML (p:) a DrawingML (a:)

Když otevřete ppt/slides/slide1.xml, setkáte se se dvěma hlavními XML jmennými prostory:

  1. PresentationML (p:): Řídí strukturované prezentační prvky (snímky, stromové tvary, skupiny pláten).
  2. DrawingML (a:): Řídí typografii, geometrii, 2D souřadnice, gradientové výplně a vektorové vykreslování.

Zde je zjednodušený příklad toho, jak vypadá standardní textový tvar:

<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>

Klíčové jednotky měření: EMU a setiny bodu

Všimněte si čísel souřadnic v <a:xfrm>:

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

Jedná se o anglické metrické jednotky (EMU).

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

EMUs umožňují celým číslům představovat přesné zlomky jak palců, tak milimetrů bez chyb zaokrouhlování s plovoucí desetinnou čárkou napříč různými hardwarovými architekturami.

Všimněte si také velikosti písma:

  • sz="3200" znamená 32,00 pt. Velikosti písma v DrawingML jsou měřeny v setinách bodu.

4. Řetězec dědičnosti: Proč tvary dědí neviditelné styly

Jedním z nejčastějších úskalí při reverzním inženýrství souborů PPTX je předpoklad, že vizuální stylování tvaru je plně deklarováno v jeho vlastním souboru slideX.xml.

Ve skutečnosti OpenXML spoléhá na přísný čtyřúrovňový kaskádový model dědičnosti:

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

Pokud textové pole v slide1.xml obsahuje:

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

Na běhu (<a:r>) není deklarována žádná rodina písma, žádná explicitní barva ani velikost. Abyste zjistili, jak PowerPoint tento text vykresluje, váš parser musí:

  1. Identifikovat typ zástupného prvku (<p:ph type="title"/>).
  2. Přečíst rozvržení odkazované v slide1.xml.rels.
  3. Zkontrolovat, zda slideLayout1.xml poskytuje přepsání stylů pro tento zástupný prvek.
  4. Vrátit se k slideMaster1.xml pro výchozí styly těla titulního textu.
  5. Sledovat tokeny barev jako accent1 nebo tx1 v theme1.xml, abyste našli hexadecimální kód barvy.

Pokud tento graf dědičnosti přeskočíte, váš parser špatně přečte styly, chybějící písma, velikosti písma a ukotvení rozvržení.

5. Praktický postup reverzního inženýrství

Když potřebujete prozkoumat, jak konkrétní funkce PowerPointu funguje pod povrchem (např. morph přechody, složité tabulky, vektorové cesty), postupujte podle tohoto empirického přístupu:

Krok 1: Vytvořte minimální “Diff Pair”

  1. Otevřete PowerPoint a vytvořte prázdný snímek.
  2. Uložte jej jako before.pptx.
  3. Použijte přesně tu jedinou změnu, kterou chcete reverzně analyzovat (např. přidejte stín k kruhu, změňte styl odrážky, vložte vložené video).
  4. Uložte jej jako after.pptx.

Krok 2: Rozbalte oba archivy

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

Krok 3: Naformátujte XML

Surový XML uvnitř archivů Office je obvykle zbaven odsazení a znaků nových řádků. Před porovnáním (diffem) souborů je naformátujte:

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

Krok 4: Spusťte Unified Diff

diff -uNr before/ after/ > changes.patch

Prohlížením changes.patch odhalíte přesný název značky, atribut jmenného prostoru a hierarchii kontejneru, kterou PowerPoint zavedl. To je nejrychlejší způsob, jak objevit nedokumentované nebo nejasné vlastnosti schématu, aniž byste prohrabávali tisíce stránek dokumentace ECMA-376.

6. Vytváření vlastního mikroenginu: rozbalit, upravit, znovu zabalit

Někdy nechcete těžkou podnikatelskou závislost jako Apache POI nebo Microsoft OpenXML SDK – zejména v lehkých serverless prostředích (AWS Lambda, Cloudflare Workers, edge uzly).

Zde je samostatný Python vzor, který ukazuje, jak bezpečně rozbalit PPTX v paměti, vložit vlastní data pomocí nástrojů standardní knihovny a znovu jej zabalit:

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()

Klíčové úskalí při úpravě souborů na úrovni surových bajtů:

  1. Zachování jmenných prostorů: XML parsery často přepisují předpony (xmlns:p může být přepsáno na xmlns:ns0). Přestože je to platné XML, přísná interní validace schématu PowerPointu občas odmítá nestandardní aliasy předpon. Registrujte jmenné prostory explicitně.
  2. Metody komprese ZIP: Ujistěte se, že soubory zapisujete zpět pomocí standardní deflate komprese (zipfile.ZIP_DEFLATED).
  3. Vyprázdnění proudu: Vždy zkontrolujte, že váš zip buffer se uzavře a kompletně vyprázdní před odesláním bajtů dál.
  4. Zachování vztahů: Pokud odstraníte snímek, musíte také odstranit jeho záznam z ppt/presentation.xml, smazat jeho vztah v ppt/_rels/presentation.xml.rels a vyčistit jeho typ obsahu z [Content_Types].xml.

7. Úvahy o výkonu a zabezpečení

Reverse engineering souborů PPTX není jen o úpravě snímků; jde také o audit toho, co vstupuje do vašich systémů.

Bezpečnost: miliarda smíchů a XXE

Protože soubory PPTX parsují XML, jakýkoli serverový pipeline přijímající uživatelsky zaslané prezentace je zranitelný vůči:

  • Injekce XML externí entity (XXE): Škodlivé XML pokoušející se přistoupit k /etc/passwd nebo dotazovat interní koncové body cloudových metadat (http://169.254.169.254/).
  • Útoky rozšířením entit (Billion Laughs): Exponenciální smyčky entit vyčerpávající RAM systému.

Zmírnění: Vždy zakazujte resolve_entities, load_dtd a externí síťové řešení ve vašem XML parseru (např. pomocí defusedxml v Pythonu).

Bezpečnost: makro payloady a skryté proudy

Prohlédněte soubory na obsah .pptm maskovaný pod příponou .pptx. Dávejte pozor na ppt/vbaProject.bin, který obsahuje zkompilovaný kód Visual Basic. Ve standardních souborech .pptx je VBA kód zakázán; nalezení odkazů na binární payload v relacích by mělo okamžitě spustit karanténní příznaky.

Závěr

Reverse engineering souborů .pptx demystifikuje prezentační software. Jakmile si uvědomíte, že soubory PowerPoint jsou jen strukturované zip balíčky naplněné souřadnicemi, odkazy na schémata a XML stromy vztahů, již nejste omezeni existujícími abstrakcemi třetích stran.

Ať už optimalizujete propustnost generování snímků, píšete vlastní automatizované čističe, nebo řešíte problémy s vykreslováním, přímý pohled na podkladovou architekturu OpenXML vám poskytuje úplnou kontrolu nad prezentačním pipeline.

Často kladené otázky (FAQ)

**Q: Můžete převést .pptx na standardní složku a upravovat soubory přímo v IDE?

A1: Ano, můžete rozbalit archiv, upravit XML v editoru jako VS Code a znovu zkomprimovat obsah adresáře, aby se otevřel zpět v PowerPointu.

**Q: Proč PowerPoint říká, že můj ručně upravený soubor PPTX potřebuje opravu?

A2: Toto se obvykle stane, pokud jste zavlekl poškozené XML, vynechal nový asset z [Content_Types].xml, nebo zanechal visící odkaz v přidruženém souboru .rels.

**Q: Jakou měrnou jednotku PowerPoint používá pro pozice tvarů a okraje?

A3: PowerPoint používá English Metric Units (EMUs), kde 1 palec odpovídá 914 400 EMU a 1 bod odpovídá 12 700 EMU.

**Q: Jak mohu programově extrahovat všechny obrázky z prezentace bez externích knihoven?

A4: Jednoduše otevřete soubor .pptx pomocí libovolného standardního zip nástroje a extrahujte všechny binární soubory umístěné ve složce ppt/media/.

**Q: Je bezpečné parsovat uživateli nahrané soubory PPTX pomocí standardních XML parserů?

A5: Ne, musíte svůj parser zpevnit nebo použít bezpečné obaly jako defusedxml, aby se zablokovaly útoky XML External Entity (XXE) a zip‑bomba.

Viz také