<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>PPTX Omvendt Ingeniørarbejde on File Format Blog</title>
    <link>https://blog.fileformat.com/da/tag/pptx-omvendt-ingeni%C3%B8rarbejde/</link>
    <description>Recent content in PPTX Omvendt Ingeniørarbejde on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>da</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/da/tag/pptx-omvendt-ingeni%C3%B8rarbejde/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>PPTX Omvendt Ingeniørarbejde: Forståelse af PowerPoint-filer internt</title>
      <link>https://blog.fileformat.com/da/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/da/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</guid>
      <description>Opdag hvad der virkelig gemmer sig inde i en `.pptx`-fil. Lær hvordan OpenXML-pakning, relationsgrafer, former og tegne‑markup fungerer under overfladen.</description>
      <content:encoded><![CDATA[<p><strong>Sidst opdateret</strong>: 16 sept., 2026</p>
<figure class="align-center ">
    <img loading="lazy" src="images/pptx-reverse-engineering-understanding-powerpoint-files-internally.png#center"
         alt="PPTX Reverse Engineering: Understanding PowerPoint Files Internally"/> 
</figure>

<hr>
<h2 id="omvendt-ingeniørarbejde-af-pptx4-filer-en-udviklerguide">Omvendt Ingeniørarbejde af <a href="https://docs.fileformat.com/presentation/pptx/">PPTX</a>-filer: En Udviklerguide</h2>
<p>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.</p>
<p>Når biblioteker som <a href="https://products.fileformat.com/presentation/python/python-pptx/"><code>python-pptx</code></a>, <a href="https://products.fileformat.com/presentation/java/apache-poi-xslf/">Apache POI</a> eller <a href="https://products.fileformat.com/presentation/net/openxmlsdk/">OpenXML SDK</a> 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.</p>
<p>I dette dybdegående kig vil vi trække gardinet til side for <code>.pptx</code>‑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.</p>
<h2 id="1-hvad-er-en-pptx-fil-egentlig">1. Hvad er en <code>.pptx</code>-fil egentlig?</h2>
<p>I sin kerne er en <code>.pptx</code>-fil ikke en proprietær monolitisk binær som det gamle <code>.ppt</code>-format fra 1990&rsquo;erne. Siden Microsoft introducerede Office Open XML (ECMA-376 og ISO/IEC 29500), er moderne Office-dokumenter <strong>Open Packaging Conventions (OPC) arkiver</strong>.</p>
<p>På almindeligt dansk: <strong>en <code>.pptx</code>-fil er simpelthen et zip-arkiv, der indeholder XML-dokumenter og medie‑ressourcer organiseret i et deterministisk mappe‑træ.</strong></p>
<p>Du kan bevise dette på få sekunder ved at bruge standard terminalværktøjer:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Rename the extension and unpack it</span>
</span></span><span style="display:flex;"><span>cp presentation.pptx presentation.zip
</span></span><span style="display:flex;"><span>unzip presentation.zip -d presentation_unpacked/
</span></span><span style="display:flex;"><span>cd presentation_unpacked/
</span></span><span style="display:flex;"><span>tree -L <span style="color:#ae81ff">2</span>
</span></span></code></pre></div><p>Det resulterende mappe‑træ ser bemærkelsesværdigt konsistent ud:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>.
</span></span><span style="display:flex;"><span>├── [Content_Types].xml
</span></span><span style="display:flex;"><span>├── _rels/
</span></span><span style="display:flex;"><span>│   └── .rels
</span></span><span style="display:flex;"><span>├── docProps/
</span></span><span style="display:flex;"><span>│   ├── app.xml
</span></span><span style="display:flex;"><span>│   └── core.xml
</span></span><span style="display:flex;"><span>└── ppt/
</span></span><span style="display:flex;"><span>    ├── presentation.xml
</span></span><span style="display:flex;"><span>    ├── _rels/
</span></span><span style="display:flex;"><span>    ├── slides/
</span></span><span style="display:flex;"><span>    ├── slideLayouts/
</span></span><span style="display:flex;"><span>    ├── slideMasters/
</span></span><span style="display:flex;"><span>    ├── theme/
</span></span><span style="display:flex;"><span>    └── media/
</span></span></code></pre></div><p>Hvert enkelt visuelt element, overgang, slide‑master‑arv, tekstboks‑koordinat og vektorgrafik er kodificeret i denne fil‑hierarki.</p>
<h2 id="2-anatomien-af-pakken-vigtige-undersystemer">2. Anatomien af pakken: Vigtige undersystemer</h2>
<p>For effektivt at reverse‑engineere præsentationer skal du forstå ansvaret for hver top‑niveau komponent.</p>
<h3 id="content_typesxml"><code>[Content_Types].xml</code></h3>
<p>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 <code>[Content_Types].xml</code>, vil PowerPoint erklære decket som korrupt og bede om gendannelse.</p>
<p>Eksempel‑snippet:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;Types</span> <span style="color:#a6e22e">xmlns=</span><span style="color:#e6db74">&#34;http://schemas.openxmlformats.org/package/2006/content-types&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;xml&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;rels&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/vnd.openxmlformats-package.relationships+xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Default</span> <span style="color:#a6e22e">Extension=</span><span style="color:#e6db74">&#34;png&#34;</span> <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;image/png&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;Override</span> <span style="color:#a6e22e">PartName=</span><span style="color:#e6db74">&#34;/ppt/presentation.xml&#34;</span> 
</span></span><span style="display:flex;"><span>            <span style="color:#a6e22e">ContentType=</span><span style="color:#e6db74">&#34;application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/Types&gt;</span>
</span></span></code></pre></div><h3 id="relationgrafen-_rels">Relationgrafen <code>_rels/</code></h3>
<p>Et af de mest afgørende begreber i OpenXML er <strong>indirektion gennem relationer</strong>. Dele peger sjældent direkte på rå filstier. I stedet har en fil (f.eks. <code>slide1.xml</code>) en tilknyttet relationsfil placeret i en søskende <code>_rels</code>-mappe (f.eks. <code>_rels/slide1.xml.rels</code>).</p>
<p>Relationer definerer:</p>
<ul>
<li>Hyperlinks (<code>r:id=&quot;rId2&quot;</code>, TargetMode=&ldquo;External&rdquo;)</li>
<li>Billeder og lydspor gemt i <code>ppt/media/</code></li>
<li>Layout-arvepegepinde (<code>slideLayout1.xml</code>)</li>
<li>Notesslides, kommentarer og indlejrede skrifttyper</li>
</ul>
<h3 id="docprops-metadata"><code>docProps/</code> (Metadata)</h3>
<ul>
<li><strong><code>core.xml</code></strong>: Dublin Core-metadata—forfatter, titel, oprettelsesdato, ændringstidspunkt.</li>
<li><strong><code>app.xml</code></strong>: Applikationsspecifik statistik—PowerPoint-version, samlet antal slides, antal skjulte slides, ordtælling, navne på præsentationsskabeloner.</li>
</ul>
<h3 id="ppt-præsentationsmotoren"><code>ppt/</code> (Præsentationsmotoren)</h3>
<p>Det er her den faktiske præsentation findes:</p>
<ul>
<li><strong><code>presentation.xml</code></strong>: Den overordnede rygsøjle. Den registrerer slide-ID&rsquo;er, slide-størrelsesdimensioner, referencer til notemaster og standard skrifttypeindstillinger.</li>
<li><strong><code>slides/</code></strong>: De enkelte slides (<code>slide1.xml</code>, <code>slide2.xml</code> osv.).</li>
<li><strong><code>slideLayouts/</code></strong>: Master strukturelle forudindstillinger (Titel-slide, To kolonner, Sektion-header).</li>
<li><strong><code>slideMasters/</code></strong>: Globale stilarter, standardpaletter, baggrundsudfyldninger og pladsholderarv.</li>
<li><strong><code>theme/</code></strong>: Farvepaletter (accent 1 til 6, mørke/lyse varianter) og skrifttypeordninger (hoved-/sekundære skrifttyper).</li>
<li><strong><code>media/</code></strong>: Rå billeder (PNG, JPEG, SVG), lyd- og videofiler.</li>
</ul>
<h2 id="3-undersøgelse-af-et-dias-presentationml-p--drawingml-a-dialekter">3. Undersøgelse af et dias: PresentationML (<code>p:</code>) &amp; DrawingML (<code>a:</code>) dialekter</h2>
<p>Når du åbner <code>ppt/slides/slide1.xml</code>, støder du på to primære XML-namespace:</p>
<ol>
<li><strong>PresentationML (<code>p:</code>)</strong>: Styrer strukturelle præsentationselementer (dias, formtræ, lærredgrupper).</li>
<li><strong>DrawingML (<code>a:</code>)</strong>: Styrer typografi, geometri, 2D-koordinater, gradientfyldninger og vektorgengivelse.</li>
</ol>
<p>Her er et forenklet eksempel på, hvordan en standard tekstform ser ud:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;p:sp&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 1. Non-visual shape properties (Identifiers, names) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:nvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:cNvPr</span> <span style="color:#a6e22e">id=</span><span style="color:#e6db74">&#34;4&#34;</span> <span style="color:#a6e22e">name=</span><span style="color:#e6db74">&#34;Title Box 1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:cNvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:spLocks</span> <span style="color:#a6e22e">noGrp=</span><span style="color:#e6db74">&#34;1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/p:cNvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;p:nvPr&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;p:ph</span> <span style="color:#a6e22e">type=</span><span style="color:#e6db74">&#34;title&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/p:nvPr&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:nvSpPr&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 2. Visual shape properties (Position, size, geometry) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:spPr&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:xfrm&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:off</span> <span style="color:#a6e22e">x=</span><span style="color:#e6db74">&#34;1524000&#34;</span> <span style="color:#a6e22e">y=</span><span style="color:#e6db74">&#34;1143000&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:ext</span> <span style="color:#a6e22e">cx=</span><span style="color:#e6db74">&#34;9144000&#34;</span> <span style="color:#a6e22e">cy=</span><span style="color:#e6db74">&#34;1828800&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:xfrm&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:prstGeom</span> <span style="color:#a6e22e">prst=</span><span style="color:#e6db74">&#34;rect&#34;</span><span style="color:#f92672">&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:avLst/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:prstGeom&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:solidFill&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:schemeClr</span> <span style="color:#a6e22e">val=</span><span style="color:#e6db74">&#34;accent1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:solidFill&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:spPr&gt;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">&lt;!-- 3. Text Body (Paragraphs, runs, styling) --&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;p:txBody&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:bodyPr</span> <span style="color:#a6e22e">rtlCol=</span><span style="color:#e6db74">&#34;0&#34;</span> <span style="color:#a6e22e">anchor=</span><span style="color:#e6db74">&#34;ctr&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:lstStyle/&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:p&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;a:r&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;a:rPr</span> <span style="color:#a6e22e">lang=</span><span style="color:#e6db74">&#34;en-US&#34;</span> <span style="color:#a6e22e">sz=</span><span style="color:#e6db74">&#34;3200&#34;</span> <span style="color:#a6e22e">b=</span><span style="color:#e6db74">&#34;1&#34;</span><span style="color:#f92672">/&gt;</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">&lt;a:t&gt;</span>Mission Critical Architecture<span style="color:#f92672">&lt;/a:t&gt;</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">&lt;/a:r&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;/a:p&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/p:txBody&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/p:sp&gt;</span>
</span></span></code></pre></div><h3 id="vigtige-måleenheder-emuer-og-hundrededele-af-et-punkt">Vigtige måleenheder: EMU&rsquo;er og hundrededele af et punkt</h3>
<p>Bemærk koordinattallene i <code>&lt;a:xfrm&gt;</code>:</p>
<ul>
<li><code>x=\&quot;1524000\&quot;</code></li>
<li><code>cx=\&quot;9144000\&quot;</code></li>
</ul>
<p>Dette er <strong>English Metric Units (EMUs)</strong>.</p>
<ul>
<li>$1 \text{ inch} = 914,400 \text{ EMUs}$</li>
<li>$1 \text{ cm} = 360,000 \text{ EMUs}$</li>
<li>$1 \text{ pt} = 12,700 \text{ EMUs}$</li>
</ul>
<p>EMU&rsquo;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.</p>
<p>Bemærk også skriftstørrelsen:</p>
<ul>
<li><code>sz=&quot;3200&quot;</code> betyder <strong>32,00 pt</strong>. Skriftstørrelser i DrawingML måles i hundrededele af et punkt.</li>
</ul>
<h2 id="4-arvekæden-hvorfor-former-arver-usynlige-stilarter">4. Arvekæden: Hvorfor former arver usynlige stilarter</h2>
<p>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 <code>slideX.xml</code>.</p>
<p>I virkeligheden er OpenXML afhængig af en streng <strong>4-niveau kaskadearvmodel</strong>:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>[Theme: ppt/theme/theme1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide Master: ppt/slideMasters/slideMaster1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide Layout: ppt/slideLayouts/slideLayout1.xml]
</span></span><span style="display:flex;"><span>              │
</span></span><span style="display:flex;"><span>              ▼
</span></span><span style="display:flex;"><span>[Slide: ppt/slides/slide1.xml]
</span></span></code></pre></div><p>Hvis en tekstboks på <code>slide1.xml</code> indeholder:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-xml" data-lang="xml"><span style="display:flex;"><span><span style="color:#f92672">&lt;a:p&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;a:r&gt;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">&lt;a:t&gt;</span>Revenue Projections<span style="color:#f92672">&lt;/a:t&gt;</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">&lt;/a:r&gt;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">&lt;/a:p&gt;</span>
</span></span></code></pre></div><p>Der er ingen skrifttype, ingen eksplicit farve og ingen størrelse angivet på kørslen (<code>&lt;a:r&gt;</code>). For at finde ud af, hvordan PowerPoint gengiver denne tekst, skal din parser:</p>
<ol>
<li>Identificer pladsholdertypen (<code>&lt;p:ph type=&quot;title&quot;/&gt;</code>).</li>
<li>Læs layoutet, der refereres til i <code>slide1.xml.rels</code>.</li>
<li>Kontroller om <code>slideLayout1.xml</code> giver stiloverstyringer for den pladsholder.</li>
<li>Fald tilbage på <code>slideMaster1.xml</code> for standardtiteltekstkropsstile.</li>
<li>Spor farvetokens som <code>accent1</code> eller <code>tx1</code> i <code>theme1.xml</code> for at finde den hexadecimale farvekode.</li>
</ol>
<p>Hvis du springer dette arvegraf over, vil din parser læse stilarter forkert, manglende skrifttyper, skriftstørrelser og layoutankre.</p>
<h2 id="5-praktisk-reverse-engineering-arbejdsgang">5. Praktisk Reverse Engineering-arbejdsgang</h2>
<p>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:</p>
<h3 id="trin-1-opret-et-minimalt-diff-par">Trin 1: Opret et minimalt &ldquo;Diff-par&rdquo;</h3>
<ol>
<li>Åbn PowerPoint og opret et tomt slide.</li>
<li>Gem den som <code>before.pptx</code>.</li>
<li>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).</li>
<li>Gem den som <code>after.pptx</code>.</li>
</ol>
<h3 id="trin-2-pak-begge-arkiver-ud">Trin 2: Pak begge arkiver ud</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>unzip before.pptx -d before/
</span></span><span style="display:flex;"><span>unzip after.pptx -d after/
</span></span></code></pre></div><h3 id="trin-3-formater-xmlen">Trin 3: Formater XML&rsquo;en</h3>
<p>Rå XML inde i Office-arkiver fjernes normalt for indrykning og linjeskiftstegn. Før du sammenligner, formatér filerne:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>find before/ after/ -name <span style="color:#e6db74">&#34;*.xml&#34;</span> -exec xmllint --format <span style="color:#f92672">{}</span> --output <span style="color:#f92672">{}</span> <span style="color:#ae81ff">\;</span>
</span></span></code></pre></div><h3 id="trin-4-kør-en-samlet-diff">Trin 4: Kør en samlet diff</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>diff -uNr before/ after/ &gt; changes.patch
</span></span></code></pre></div><p>Gennemgang af <code>changes.patch</code> 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.</p>
<h2 id="6-byg-en-tilpasset-mikromotor-pak-ud-modificer-pak-igen">6. Byg en tilpasset mikro‑motor: Pak ud, modificer, pak igen</h2>
<p>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).</p>
<p>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:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-python" data-lang="python"><span style="display:flex;"><span><span style="color:#f92672">import</span> zipfile
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> io
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> xml.etree.ElementTree <span style="color:#66d9ef">as</span> ET
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">def</span> <span style="color:#a6e22e">modify_slide_title</span>(input_pptx_bytes: bytes, new_title: str) <span style="color:#f92672">-&gt;</span> bytes:
</span></span><span style="display:flex;"><span>    input_zip <span style="color:#f92672">=</span> zipfile<span style="color:#f92672">.</span>ZipFile(io<span style="color:#f92672">.</span>BytesIO(input_pptx_bytes))
</span></span><span style="display:flex;"><span>    output_buffer <span style="color:#f92672">=</span> io<span style="color:#f92672">.</span>BytesIO()
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">with</span> zipfile<span style="color:#f92672">.</span>ZipFile(output_buffer, <span style="color:#e6db74">&#34;w&#34;</span>, zipfile<span style="color:#f92672">.</span>ZIP_DEFLATED) <span style="color:#66d9ef">as</span> output_zip:
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">for</span> item <span style="color:#f92672">in</span> input_zip<span style="color:#f92672">.</span>infolist():
</span></span><span style="display:flex;"><span>            content <span style="color:#f92672">=</span> input_zip<span style="color:#f92672">.</span>read(item<span style="color:#f92672">.</span>filename)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>            <span style="color:#75715e"># Target slide 1</span>
</span></span><span style="display:flex;"><span>            <span style="color:#66d9ef">if</span> item<span style="color:#f92672">.</span>filename <span style="color:#f92672">==</span> <span style="color:#e6db74">&#34;ppt/slides/slide1.xml&#34;</span>:
</span></span><span style="display:flex;"><span>                namespaces <span style="color:#f92672">=</span> {
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#39;p&#39;</span>: <span style="color:#e6db74">&#39;http://schemas.openxmlformats.org/presentationml/2006/main&#39;</span>,
</span></span><span style="display:flex;"><span>                    <span style="color:#e6db74">&#39;a&#39;</span>: <span style="color:#e6db74">&#39;http://schemas.openxmlformats.org/drawingml/2006/main&#39;</span>
</span></span><span style="display:flex;"><span>                }
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                <span style="color:#75715e"># Register namespaces to preserve prefixes</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> prefix, uri <span style="color:#f92672">in</span> namespaces<span style="color:#f92672">.</span>items():
</span></span><span style="display:flex;"><span>                    ET<span style="color:#f92672">.</span>register_namespace(prefix, uri)
</span></span><span style="display:flex;"><span>                    
</span></span><span style="display:flex;"><span>                root <span style="color:#f92672">=</span> ET<span style="color:#f92672">.</span>fromstring(content)
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                <span style="color:#75715e"># Find title placeholder text run</span>
</span></span><span style="display:flex;"><span>                <span style="color:#66d9ef">for</span> title_run <span style="color:#f92672">in</span> root<span style="color:#f92672">.</span>findall(<span style="color:#e6db74">&#34;.//p:sp[p:nvSpPr/p:nvPr/p:ph[@type=&#39;title&#39;]]//a:t&#34;</span>, namespaces):
</span></span><span style="display:flex;"><span>                    title_run<span style="color:#f92672">.</span>text <span style="color:#f92672">=</span> new_title
</span></span><span style="display:flex;"><span>                    <span style="color:#66d9ef">break</span>
</span></span><span style="display:flex;"><span>                
</span></span><span style="display:flex;"><span>                content <span style="color:#f92672">=</span> ET<span style="color:#f92672">.</span>tostring(root, encoding<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;utf-8&#34;</span>, xml_declaration<span style="color:#f92672">=</span><span style="color:#66d9ef">True</span>)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>            output_zip<span style="color:#f92672">.</span>writestr(item, content)
</span></span><span style="display:flex;"><span>            
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> output_buffer<span style="color:#f92672">.</span>getvalue()
</span></span></code></pre></div><h3 id="vigtige-faldgruber-ved-modificering-af-filer-på-rå-byteniveau">Vigtige faldgruber ved modificering af filer på rå byte‑niveau:</h3>
<ol>
<li><strong>Bevarelse af navnerum</strong>: XML-parsere omskriver ofte præfikser (<code>xmlns:p</code> kan blive <code>xmlns:ns0</code>). Selvom det er gyldig XML, afviser PowerPoints strenge interne skemavalidering lejlighedsvis ikke‑standard præfiks‑aliaser. Registrer navnerum eksplicit.</li>
<li><strong>ZIP-komprimeringsmetoder</strong>: Sørg for at skrive filer tilbage ved brug af standard deflate-komprimering (<code>zipfile.ZIP_DEFLATED</code>).</li>
<li><strong>Strømudrensning</strong>: Kontroller altid, at din zip‑buffer lukker og tømmes fuldstændigt, før du sender bytes videre.</li>
<li><strong>Bevar relationer</strong>: Hvis du fjerner et dias, skal du også fjerne dets post fra <code>ppt/presentation.xml</code>, slette dets relation i <code>ppt/_rels/presentation.xml.rels</code> og rense dets indholdstype fra <code>[Content_Types].xml</code>.</li>
</ol>
<h2 id="7-ydelses-og-sikkerhedsovervejelser">7. Ydelses‑ og sikkerhedsovervejelser</h2>
<p>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.</p>
<h3 id="sikkerhed-milliard-latter--xxe">Sikkerhed: Milliard Latter &amp; XXE</h3>
<p>Da PPTX-filer parser XML, er enhver server‑side pipeline, der indtager bruger‑indsendte præsentationer, sårbar over for:</p>
<ul>
<li><strong>XML External Entity (XXE) Injection</strong>: Ondsindet XML, der forsøger at få adgang til <code>/etc/passwd</code> eller forespørge interne cloud‑metadata‑endepunkter (<code>http://169.254.169.254/</code>).</li>
<li><strong>Entity Expansion Angreb (Billion Laughs)</strong>: Eksponentielle entitets‑loops, der udtømmer systemets RAM.</li>
</ul>
<p><strong>Afhjælpning</strong>: Deaktiver altid <code>resolve_entities</code>, <code>load_dtd</code> og ekstern netværksopløsning i din XML-parser (f.eks. ved at bruge <code>defusedxml</code> i Python).</p>
<h3 id="sikkerhed-makropayloads-og-skjulte-strømme">Sikkerhed: Makro‑payloads og skjulte strømme</h3>
<p>Undersøg filer for <code>.pptm</code>-indhold, der udgiver sig for <code>.pptx</code>-udvidelser. Hold øje med <code>ppt/vbaProject.bin</code>, som indeholder kompileret Visual Basic-kode. I standard <code>.pptx</code>-filer er VBA-kode forbudt; at finde referencer til binære payloads i relationer bør straks udløse karantæneflag.</p>
<h2 id="konklusion">Konklusion</h2>
<p>Reverse engineering af <code>.pptx</code>-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.</p>
<p>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&rsquo;en.</p>
<h2 id="ofte-stillede-spørgsmål-faq">Ofte stillede spørgsmål (FAQ)</h2>
<p>**Q: Kan du konvertere en .pptx til en standardmappe og redigere filer direkte i en IDE?</p>
<p><strong>A1:</strong> Ja, du kan udpakke arkivet, redigere XML&rsquo;en i en editor som VS Code, og genkomprimere mappeindholdet for at åbne det igen i PowerPoint.</p>
<p>**Q: Hvorfor siger PowerPoint, at min manuelt modificerede PPTX-fil skal repareres?</p>
<p><strong>A2:</strong> Dette sker normalt, hvis du har indført fejlformet XML, udeladt en ny ressource fra <code>[Content_Types].xml</code>, eller efterladt en hængende reference i en tilknyttet <code>.rels</code>-fil.</p>
<p>**Q: Hvilken måleenhed bruger PowerPoint til formens positioner og margener?</p>
<p><strong>A3:</strong> PowerPoint bruger English Metric Units (EMUs), hvor 1 tomme svarer til 914.400 EMU&rsquo;er og 1 punkt svarer til 12.700 EMU&rsquo;er.</p>
<p>**Q: Hvordan kan jeg <a href="https://products.fileformat.com/presentation/python/python-pptx/">programmatisk udtrække</a> alle billeder fra en præsentation uden eksterne biblioteker?</p>
<p><strong>A4:</strong> Åbn blot <code>.pptx</code>-filen med ethvert standard zip-værktøj og udtræk alle binære filer, der er placeret i <code>ppt/media/</code>-mappen.</p>
<p>**Q: Er det sikkert at parse bruger-uploadede PPTX-filer med standard XML-parsere?</p>
<p><strong>A5:</strong> Nej, du skal styrke din parser eller bruge sikre indpakninger som <code>defusedxml</code> for at blokere XML External Entity (XXE) og zip‑bombe‑angreb.</p>
<h2 id="se-også">Se også</h2>
<ul>
<li><a href="https://blog.fileformat.com/presentation/powerpoint-file-formats/">Præsentationsfilformater på FileFormat.com?</a></li>
<li><a href="https://blog.fileformat.com/presentation/apache-poi-api-to-access-powerpoint-file-formats/">Java API til at få adgang til PowerPoint-filformater</a></li>
<li><a href="https://blog.fileformat.com/presentation/odp-vs-pptx-opendocument-vs-microsoft-powerpoint-format-comparison/">ODP vs PPTX: OpenDocument vs Microsoft PowerPoint-præsentationsformat-sammenligning</a></li>
<li><a href="https://blog.fileformat.com/presentation/difference-between-ppt-and-pptx/">Forskellen mellem PPT og PPTX</a></li>
<li><a href="https://blog.fileformat.com/presentation/create-presentation-in-java-with-apache-poi-api/">Opret PowerPoint-præsentation i Java med Apache POI API</a></li>
</ul>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    
  </channel>
</rss>
