Sidst opdateret: 16 sept., 2026

PPTX Reverse Engineering: Understanding PowerPoint Files Internally

Omvendt Ingeniørarbejde af PPTX-filer: En Udviklerguide

Moderne præsentationsdæk driver alt fra investorpitches til interne kvartalsmålinger. Men hvis du nogensinde har skulle programmere udtræk af tekst, erstatte skabeloner i realtid, bygge automatiske slide‑generatorer eller rense fortrolige præsentationer, har du sandsynligvis hurtigt indset: standardbiblioteker på højt niveau kan føles som en uforudsigelig sort boks.

Når biblioteker som python-pptx, Apache POI eller OpenXML SDK rammer deres grænser—eller introducerer udocumenterede layout‑fejl—er den eneste vej ud gennem dem. Du skal forstå, hvad en PowerPoint‑præsentation egentlig er på byte‑ og skemaniveau.

I dette dybdegående kig vil vi trække gardinet til side for .pptx‑formatet, pakke dets interne struktur ud, spore dets relationsgraf, dissekere dets tegnehierarkier og se på praktiske strategier for reverse engineering, inspektion og manipulation af præsentationer med rå kode.

1. Hvad er en .pptx-fil egentlig?

I sin kerne er en .pptx-fil ikke en proprietær monolitisk binær som det gamle .ppt-format fra 1990’erne. Siden Microsoft introducerede Office Open XML (ECMA-376 og ISO/IEC 29500), er moderne Office-dokumenter Open Packaging Conventions (OPC) arkiver.

På almindeligt dansk: en .pptx-fil er simpelthen et zip-arkiv, der indeholder XML-dokumenter og medie‑ressourcer organiseret i et deterministisk mappe‑træ.

Du kan bevise dette på få sekunder ved at bruge standard terminalværktøjer:

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

Det resulterende mappe‑træ ser bemærkelsesværdigt konsistent ud:

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

Hvert enkelt visuelt element, overgang, slide‑master‑arv, tekstboks‑koordinat og vektorgrafik er kodificeret i denne fil‑hierarki.

2. Anatomien af pakken: Vigtige undersystemer

For effektivt at reverse‑engineere præsentationer skal du forstå ansvaret for hver top‑niveau komponent.

[Content_Types].xml

Dette er indgangsmanifestet for OPC‑læseren. Det kortlægger fil‑udvidelser og eksplicitte interne delnavne til standardiserede MIME-/indholdstyper. Hvis du opretter et nyt slide eller tilføjer et billede og undlader at deklarere det i [Content_Types].xml, vil PowerPoint erklære decket som korrupt og bede om gendannelse.

Eksempel‑snippet:

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

Relationgrafen _rels/

Et af de mest afgørende begreber i OpenXML er indirektion gennem relationer. Dele peger sjældent direkte på rå filstier. I stedet har en fil (f.eks. slide1.xml) en tilknyttet relationsfil placeret i en søskende _rels-mappe (f.eks. _rels/slide1.xml.rels).

Relationer definerer:

  • Hyperlinks (r:id="rId2", TargetMode=“External”)
  • Billeder og lydspor gemt i ppt/media/
  • Layout-arvepegepinde (slideLayout1.xml)
  • Notesslides, kommentarer og indlejrede skrifttyper

docProps/ (Metadata)

  • core.xml: Dublin Core-metadata—forfatter, titel, oprettelsesdato, ændringstidspunkt.
  • app.xml: Applikationsspecifik statistik—PowerPoint-version, samlet antal slides, antal skjulte slides, ordtælling, navne på præsentationsskabeloner.

ppt/ (Præsentationsmotoren)

Det er her den faktiske præsentation findes:

  • presentation.xml: Den overordnede rygsøjle. Den registrerer slide-ID’er, slide-størrelsesdimensioner, referencer til notemaster og standard skrifttypeindstillinger.
  • slides/: De enkelte slides (slide1.xml, slide2.xml osv.).
  • slideLayouts/: Master strukturelle forudindstillinger (Titel-slide, To kolonner, Sektion-header).
  • slideMasters/: Globale stilarter, standardpaletter, baggrundsudfyldninger og pladsholderarv.
  • theme/: Farvepaletter (accent 1 til 6, mørke/lyse varianter) og skrifttypeordninger (hoved-/sekundære skrifttyper).
  • media/: Rå billeder (PNG, JPEG, SVG), lyd- og videofiler.

3. Undersøgelse af et dias: PresentationML (p:) & DrawingML (a:) dialekter

Når du åbner ppt/slides/slide1.xml, støder du på to primære XML-namespace:

  1. PresentationML (p:): Styrer strukturelle præsentationselementer (dias, formtræ, lærredgrupper).
  2. DrawingML (a:): Styrer typografi, geometri, 2D-koordinater, gradientfyldninger og vektorgengivelse.

Her er et forenklet eksempel på, hvordan en standard tekstform ser ud:

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

Vigtige måleenheder: EMU’er og hundrededele af et punkt

Bemærk koordinattallene i <a:xfrm>:

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

Dette er English Metric Units (EMUs).

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

EMU’er tillader heltal at repræsentere nøjagtige brøker af både tommer og millimeter uden flydende-komma afrundingsfejl på tværs af forskellige hardwarearkitekturer.

Bemærk også skriftstørrelsen:

  • sz="3200" betyder 32,00 pt. Skriftstørrelser i DrawingML måles i hundrededele af et punkt.

4. Arvekæden: Hvorfor former arver usynlige stilarter

En af de mest almindelige faldgruber ved reverse engineering af PPTX-filer er at antage, at en formes visuelle styling er fuldt deklareret inde i dens egen slideX.xml.

I virkeligheden er OpenXML afhængig af en streng 4-niveau kaskadearvmodel:

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

Hvis en tekstboks på slide1.xml indeholder:

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

Der er ingen skrifttype, ingen eksplicit farve og ingen størrelse angivet på kørslen (<a:r>). For at finde ud af, hvordan PowerPoint gengiver denne tekst, skal din parser:

  1. Identificer pladsholdertypen (<p:ph type="title"/>).
  2. Læs layoutet, der refereres til i slide1.xml.rels.
  3. Kontroller om slideLayout1.xml giver stiloverstyringer for den pladsholder.
  4. Fald tilbage på slideMaster1.xml for standardtiteltekstkropsstile.
  5. Spor farvetokens som accent1 eller tx1 i theme1.xml for at finde den hexadecimale farvekode.

Hvis du springer dette arvegraf over, vil din parser læse stilarter forkert, manglende skrifttyper, skriftstørrelser og layoutankre.

5. Praktisk Reverse Engineering-arbejdsgang

Når du har brug for at undersøge, hvordan en bestemt PowerPoint-funktion fungerer under overfladen (f.eks. morph-overgange, komplekse tabeller, vektorveje), skal du følge denne empiriske tilgang:

Trin 1: Opret et minimalt “Diff-par”

  1. Åbn PowerPoint og opret et tomt slide.
  2. Gem den som before.pptx.
  3. Anvend den præcise enkeltændring, du ønsker at omvendt udvikle (f.eks. tilføj en skygge til en cirkel, ændr en punktstil, indsæt en indlejret video).
  4. Gem den som after.pptx.

Trin 2: Pak begge arkiver ud

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

Trin 3: Formater XML’en

Rå XML inde i Office-arkiver fjernes normalt for indrykning og linjeskiftstegn. Før du sammenligner, formatér filerne:

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

Trin 4: Kør en samlet diff

diff -uNr before/ after/ > changes.patch

Gennemgang af changes.patch afslører det præcise tag-navn, navnerumsattributten og containerhierarkiet, som PowerPoint introducerede. Dette er den hurtigste måde at opdage udokumenterede eller obskure skemaegenskaber på uden at grave gennem tusindvis af sider i ECMA-376-dokumentationen.

6. Byg en tilpasset mikro‑motor: Pak ud, modificer, pak igen

Nogle gange ønsker du ikke en tung virksomhedsafhængighed som Apache POI eller Microsoft OpenXML SDK—særligt i letvægts serverløse runtime-miljøer (AWS Lambda, Cloudflare Workers, edge-noder).

Her er et selvstændigt Python-mønster, der demonstrerer, hvordan du sikkert kan pakke en PPTX ud i hukommelsen, injicere brugerdefinerede data ved hjælp af standardbibliotekets værktøjer og pakke den igen:

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

Vigtige faldgruber ved modificering af filer på rå byte‑niveau:

  1. Bevarelse af navnerum: XML-parsere omskriver ofte præfikser (xmlns:p kan blive xmlns:ns0). Selvom det er gyldig XML, afviser PowerPoints strenge interne skemavalidering lejlighedsvis ikke‑standard præfiks‑aliaser. Registrer navnerum eksplicit.
  2. ZIP-komprimeringsmetoder: Sørg for at skrive filer tilbage ved brug af standard deflate-komprimering (zipfile.ZIP_DEFLATED).
  3. Strømudrensning: Kontroller altid, at din zip‑buffer lukker og tømmes fuldstændigt, før du sender bytes videre.
  4. Bevar relationer: Hvis du fjerner et dias, skal du også fjerne dets post fra ppt/presentation.xml, slette dets relation i ppt/_rels/presentation.xml.rels og rense dets indholdstype fra [Content_Types].xml.

7. Ydelses‑ og sikkerhedsovervejelser

Reverse engineering af PPTX-filer handler ikke kun om at redigere dias; det handler også om at revidere, hvad der kommer ind i dine systemer.

Sikkerhed: Milliard Latter & XXE

Da PPTX-filer parser XML, er enhver server‑side pipeline, der indtager bruger‑indsendte præsentationer, sårbar over for:

  • XML External Entity (XXE) Injection: Ondsindet XML, der forsøger at få adgang til /etc/passwd eller forespørge interne cloud‑metadata‑endepunkter (http://169.254.169.254/).
  • Entity Expansion Angreb (Billion Laughs): Eksponentielle entitets‑loops, der udtømmer systemets RAM.

Afhjælpning: Deaktiver altid resolve_entities, load_dtd og ekstern netværksopløsning i din XML-parser (f.eks. ved at bruge defusedxml i Python).

Sikkerhed: Makro‑payloads og skjulte strømme

Undersøg filer for .pptm-indhold, der udgiver sig for .pptx-udvidelser. Hold øje med ppt/vbaProject.bin, som indeholder kompileret Visual Basic-kode. I standard .pptx-filer er VBA-kode forbudt; at finde referencer til binære payloads i relationer bør straks udløse karantæneflag.

Konklusion

Reverse engineering af .pptx-filer afmystificerer præsentationssoftware. Når du indser, at PowerPoint-filer blot er strukturerede zip-pakker fyldt med koordinater, skemareferencer og XML-relationstræer, er du ikke længere begrænset af eksisterende tredjepartsabstraktioner.

Uanset om du optimerer gennemløbet for slide-generering, skriver tilpassede automatiserede sanitisatorer eller fejlsøger renderingsfejl, giver et direkte kig på den underliggende OpenXML-arkitektur dig fuld kontrol over præsentationspipeline’en.

Ofte stillede spørgsmål (FAQ)

**Q: Kan du konvertere en .pptx til en standardmappe og redigere filer direkte i en IDE?

A1: Ja, du kan udpakke arkivet, redigere XML’en i en editor som VS Code, og genkomprimere mappeindholdet for at åbne det igen i PowerPoint.

**Q: Hvorfor siger PowerPoint, at min manuelt modificerede PPTX-fil skal repareres?

A2: Dette sker normalt, hvis du har indført fejlformet XML, udeladt en ny ressource fra [Content_Types].xml, eller efterladt en hængende reference i en tilknyttet .rels-fil.

**Q: Hvilken måleenhed bruger PowerPoint til formens positioner og margener?

A3: PowerPoint bruger English Metric Units (EMUs), hvor 1 tomme svarer til 914.400 EMU’er og 1 punkt svarer til 12.700 EMU’er.

**Q: Hvordan kan jeg programmatisk udtrække alle billeder fra en præsentation uden eksterne biblioteker?

A4: Åbn blot .pptx-filen med ethvert standard zip-værktøj og udtræk alle binære filer, der er placeret i ppt/media/-mappen.

**Q: Er det sikkert at parse bruger-uploadede PPTX-filer med standard XML-parsere?

A5: Nej, du skal styrke din parser eller bruge sikre indpakninger som defusedxml for at blokere XML External Entity (XXE) og zip‑bombe‑angreb.

Se også