<?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>Inżynieria wsteczna PPTX on File Format Blog</title>
    <link>https://blog.fileformat.com/pl/tag/in%C5%BCynieria-wsteczna-pptx/</link>
    <description>Recent content in Inżynieria wsteczna PPTX on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>pl</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/pl/tag/in%C5%BCynieria-wsteczna-pptx/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Inżynieria wsteczna PPTX: Zrozumienie wewnętrznej struktury plików PowerPoint</title>
      <link>https://blog.fileformat.com/pl/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/pl/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</guid>
      <description>Odkryj, co naprawdę kryje się wewnątrz pliku `.pptx`. Dowiedz się, jak działają pakowanie OpenXML, grafy relacji, kształty i znacznik rysowania w tle.</description>
      <content:encoded><![CDATA[<p><strong>Ostatnia aktualizacja</strong>: 16 wrz, 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="inżynieria-wsteczna-pptx4-files-przewodnik-dla-programistów">Inżynieria wsteczna <a href="https://docs.fileformat.com/presentation/pptx/">PPTX</a> Files: Przewodnik dla programistów</h2>
<p>Nowoczesne zestawy prezentacji napędzają wszystko, od prezentacji dla inwestorów po wewnętrzne kwartalne metryki. Ale jeśli kiedykolwiek musiałeś programowo wyodrębniać tekst, zamieniać szablony w czasie rzeczywistym, budować automatyczne generatory slajdów lub oczyszczać poufne prezentacje, prawdopodobnie szybko zdałeś sobie sprawę: standardowe biblioteki prezentacji wysokiego poziomu mogą przypominać nieprzewidywalną czarną skrzynkę.</p>
<p>Gdy biblioteki takie jak <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> lub <a href="https://products.fileformat.com/presentation/net/openxmlsdk/">OpenXML SDK</a> napotykają swoje ograniczenia — lub wprowadzają nieudokumentowane błędy układu — jedynym wyjściem jest przejście przez nie. Musisz zrozumieć, czym tak naprawdę jest prezentacja PowerPoint na poziomie bajtów i schematu.</p>
<p>W tym dogłębnym zanurzeniu odsłonimy kulisy formatu <code>.pptx</code>, rozpakujemy jego wewnętrzną strukturę, prześledzimy graf zależności, rozłożymy hierarchie rysunków i przyjrzymy się praktycznym strategiom inżynierii wstecznej, inspekcji oraz manipulacji prezentacjami przy użyciu surowego kodu.</p>
<h2 id="1-czym-naprawdę-jest-plik-pptx">1. Czym naprawdę jest plik <code>.pptx</code>?</h2>
<p>Zasadniczo plik <code>.pptx</code> nie jest własnościowym monolitycznym plikiem binarnym, jak staroformat <code>.ppt</code> z lat 90. Od momentu wprowadzenia przez Microsoft Office Open XML (ECMA-376 i ISO/IEC 29500), nowoczesne dokumenty Office są <strong>archiwami Open Packaging Conventions (OPC)</strong>.</p>
<p>Mówiąc prosto: <strong>plik <code>.pptx</code> to po prostu archiwum zip zawierające dokumenty XML i zasoby multimedialne uporządkowane w deterministycznym drzewie katalogów.</strong></p>
<p>Możesz to udowodnić w kilka sekund, używając standardowych narzędzi terminalowych:</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>Otrzymane drzewo katalogów wygląda niezwykle spójnie:</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>Każdy pojedynczy zasób wizualny, przejście, dziedziczenie szablonu slajdu, współrzędne pola tekstowego i grafika wektorowa są zakodowane w tej hierarchii plików.</p>
<h2 id="2-anatomia-pakietu-kluczowe-podsystemy">2. Anatomia pakietu: kluczowe podsystemy</h2>
<p>Aby skutecznie inżynierować wstecz prezentacje, musisz zrozumieć zadania każdego komponentu najwyższego poziomu.</p>
<h3 id="content_typesxml"><code>[Content_Types].xml</code></h3>
<p>To jest manifest wejściowy dla czytnika OPC. Mapuje on rozszerzenia plików i explicite nazwy wewnętrznych części na standardowe typy MIME/treści. Jeśli utworzysz nowy slajd lub dodasz obraz i nie zadeklarujesz go w <code>[Content_Types].xml</code>, PowerPoint uzna prezentację za uszkodzoną i poprosi o odzyskanie.</p>
<p>Przykładowy fragment:</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="graf-relacji-_rels">Graf relacji <code>_rels/</code></h3>
<p>Jednym z najważniejszych pojęć w OpenXML jest <strong>pośrednictwo poprzez relacje</strong>. Części rzadko wskazują bezpośrednio na surowe ścieżki plików. Zamiast tego plik (np. <code>slide1.xml</code>) ma powiązany plik relacji znajdujący się w sąsiednim folderze <code>_rels</code> (np. <code>_rels/slide1.xml.rels</code>).</p>
<p>Relacje definiują:</p>
<ul>
<li>Odnośniki hipertekstowe (<code>r:id=&quot;rId2&quot;</code>, TargetMode=&ldquo;External&rdquo;)</li>
<li>Obrazy i ścieżki dźwiękowe przechowywane w <code>ppt/media/</code></li>
<li>Wskaźniki dziedziczenia układu (<code>slideLayout1.xml</code>)</li>
<li>Slajdy notatek, komentarze i osadzone czcionki</li>
</ul>
<h3 id="docprops-metadane"><code>docProps/</code> (Metadane)</h3>
<ul>
<li><strong><code>core.xml</code></strong>: Metadane Dublin Core — autor, tytuł, data utworzenia, znacznik czasu modyfikacji.</li>
<li><strong><code>app.xml</code></strong>: Statystyki specyficzne dla aplikacji — wersja PowerPoint, łączna liczba slajdów, liczba ukrytych slajdów, liczba słów, nazwy szablonów prezentacji.</li>
</ul>
<h3 id="ppt-silnik-prezentacji"><code>ppt/</code> (Silnik prezentacji)</h3>
<p>Tutaj znajduje się rzeczywista prezentacja:</p>
<ul>
<li><strong><code>presentation.xml</code></strong>: Główny szkielet. Rejestruje identyfikatory slajdów, wymiary rozmiaru slajdu, odwołania do szablonu notatek oraz domyślne ustawienia czcionki.</li>
<li><strong><code>slides/</code></strong>: Poszczególne slajdy (<code>slide1.xml</code>, <code>slide2.xml</code>, itp.).</li>
<li><strong><code>slideLayouts/</code></strong>: Główne szablony strukturalne (Slajd tytułowy, Dwie kolumny, Nagłówek sekcji).</li>
<li><strong><code>slideMasters/</code></strong>: Globalne style, domyślne palety, wypełnienia tła oraz dziedziczenie pól zastępczych.</li>
<li><strong><code>theme/</code></strong>: Palety kolorów (akcent 1‑6, warianty ciemny/jasny) oraz schematy czcionek (czcionki główne/podrzędne).</li>
<li><strong><code>media/</code></strong>: Surowe obrazy (PNG, JPEG, SVG), audio i pliki wideo.</li>
</ul>
<h2 id="3-analiza-slajdu-dialekty-presentationml-p-i-drawingml-a">3. Analiza slajdu: dialekty PresentationML (<code>p:</code>) i DrawingML (<code>a:</code>)</h2>
<p>Gdy otwierasz <code>ppt/slides/slide1.xml</code>, napotykasz dwa podstawowe przestrzenie nazw XML:</p>
<ol>
<li><strong>PresentationML (<code>p:</code>)</strong>: Zarządza strukturalnymi elementami prezentacji (slajdy, drzewa kształtów, grupy płócien).</li>
<li><strong>DrawingML (<code>a:</code>)</strong>: Zarządza typografią, geometrią, współrzędnymi 2D, wypełnieniami gradientowymi i renderowaniem wektorowym.</li>
</ol>
<p>Oto uproszczony przykład tego, jak wygląda standardowy kształt tekstowy:</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="kluczowe-jednostki-miary-emu-i-setne-punktu">Kluczowe jednostki miary: EMU i setne punktu</h3>
<p>Zauważ liczby współrzędnych w <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>To są <strong>Jednostki Metryczne Angielskie (EMU)</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>EMUs pozwalają używać liczb całkowitych do reprezentowania dokładnych ułamków zarówno cali, jak i milimetrów, bez błędów zaokrągleń zmiennoprzecinkowych na różnych architekturach sprzętowych.</p>
<p>Zauważ także rozmiar czcionki:</p>
<ul>
<li><code>sz=\&quot;3200\&quot;</code> oznacza <strong>32,00 pt</strong>. Rozmiary czcionek w DrawingML są mierzone w setnych częściach punktu.</li>
</ul>
<h2 id="4-łańcuch-dziedziczenia-dlaczego-kształty-dziedziczą-niewidzialne-style">4. Łańcuch dziedziczenia: dlaczego kształty dziedziczą niewidzialne style</h2>
<p>Jednym z najczęstszych pułapek przy inżynierii wstecznej plików PPTX jest zakładanie, że wizualny styl kształtu jest w pełni zadeklarowany we własnym pliku <code>slideX.xml</code>.</p>
<p>W rzeczywistości OpenXML opiera się na ścisłym <strong>czterowarstwowym modelu dziedziczenia kaskadowego</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>Jeśli pole tekstowe w <code>slide1.xml</code> zawiera:</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>Nie ma określonej rodziny czcionki, żadnego wyraźnego koloru ani rozmiaru zadeklarowanego w elemencie (<code>&lt;a:r&gt;</code>). Aby dowiedzieć się, jak PowerPoint renderuje ten tekst, twój parser musi:</p>
<ol>
<li>Zidentyfikuj typ zastępczego elementu (<code>&lt;p:ph type=&quot;title&quot;/&gt;</code>).</li>
<li>Odczytaj układ odwołany w <code>slide1.xml.rels</code>.</li>
<li>Sprawdź, czy <code>slideLayout1.xml</code> zawiera nadpisania stylów dla tego zastępczego elementu.</li>
<li>Użyj <code>slideMaster1.xml</code> jako domyślnego źródła stylów tekstu tytułu.</li>
<li>Śledź tokeny kolorów, takie jak <code>accent1</code> lub <code>tx1</code>, w <code>theme1.xml</code>, aby znaleźć szesnastkowy kod koloru.</li>
</ol>
<p>Jeśli pominiesz ten graf dziedziczenia, twój parser błędnie odczyta style, brakujące czcionki, rozmiary czcionek i kotwice układu.</p>
<h2 id="5-praktyczny-przepływ-pracy-inżynierii-wstecznej">5. Praktyczny przepływ pracy inżynierii wstecznej</h2>
<p>Gdy musisz zbadać, jak dana funkcja PowerPoint działa pod maską (np. przejścia morph, złożone tabele, ścieżki wektorowe), zastosuj następujące empiryczne podejście:</p>
<h3 id="krok-1-utwórz-minimalną-diff-pair">Krok 1: Utwórz minimalną &ldquo;Diff Pair&rdquo;</h3>
<ol>
<li>Otwórz PowerPoint i utwórz pusty slajd.</li>
<li>Zapisz go jako <code>before.pptx</code>.</li>
<li>Zastosuj dokładnie jedną zmianę, którą chcesz odtworzyć (np. dodaj cień do koła, zmień styl wypunktowania, wstaw osadzony film).</li>
<li>Zapisz go jako <code>after.pptx</code>.</li>
</ol>
<h3 id="krok-2-rozpakuj-oba-archiwa">Krok 2: Rozpakuj oba archiwa</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="krok-3-sformatuj-xml">Krok 3: Sformatuj XML</h3>
<p>Surowy XML w archiwach Office jest zazwyczaj pozbawiony wcięć i znaków nowej linii. Przed porównywaniem sformatuj pliki:</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="krok-4-uruchom-jednolity-diff">Krok 4: Uruchom jednolity 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>Przeglądanie <code>changes.patch</code> ujawnia dokładną nazwę tagu, atrybut przestrzeni nazw oraz hierarchię kontenerów wprowadzonych przez PowerPoint. To najszybszy sposób na odkrycie nieudokumentowanych lub niejasnych właściwości schematu bez przeszukiwania tysięcy stron dokumentacji ECMA-376.</p>
<h2 id="6-tworzenie-własnego-mikrosilnika-rozpakuj-modyfikuj-spakuj-ponownie">6. Tworzenie własnego mikro‑silnika: rozpakuj, modyfikuj, spakuj ponownie</h2>
<p>Czasami nie chcesz ciężkiej zależności korporacyjnej, takiej jak Apache POI lub Microsoft OpenXML SDK — szczególnie w lekkich środowiskach serverless (AWS Lambda, Cloudflare Workers, węzły brzegowe).</p>
<p>Oto samodzielny wzorzec w Pythonie, który pokazuje, jak bezpiecznie rozpakować w pamięci PPTX, wstrzyknąć własne dane przy użyciu narzędzi standardowej biblioteki i ponownie spakować go:</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="kluczowe-pułapki-przy-modyfikowaniu-plików-na-poziomie-surowych-bajtów">Kluczowe pułapki przy modyfikowaniu plików na poziomie surowych bajtów:</h3>
<ol>
<li><strong>Zachowanie przestrzeni nazw</strong>: Parsery XML często przepisują prefiksy (<code>xmlns:p</code> może stać się <code>xmlns:ns0</code>). Choć jest to prawidłowy XML, ścisła walidacja wewnętrznego schematu PowerPointa czasami odrzuca niestandardowe aliasy prefiksów. Zarejestruj przestrzenie nazw explicite.</li>
<li><strong>Metody kompresji ZIP</strong>: Upewnij się, że zapisujesz pliki ponownie używając standardowej kompresji deflate (<code>zipfile.ZIP_DEFLATED</code>).</li>
<li><strong>Opróżnianie strumienia</strong>: Zawsze sprawdzaj, czy bufor zip zamyka się i jest całkowicie opróżniony przed przekazaniem bajtów dalej.</li>
<li><strong>Zachowanie relacji</strong>: Jeśli usuniesz slajd, musisz także usunąć jego wpis z <code>ppt/presentation.xml</code>, usunąć jego relację w <code>ppt/_rels/presentation.xml.rels</code> oraz wyczyścić jego typ zawartości z <code>[Content_Types].xml</code>.</li>
</ol>
<h2 id="7-rozważania-dotyczące-wydajności-i-bezpieczeństwa">7. Rozważania dotyczące wydajności i bezpieczeństwa</h2>
<p>Inżynieria wsteczna plików PPTX to nie tylko edycja slajdów; to także audyt tego, co trafia do twoich systemów.</p>
<h3 id="bezpieczeństwo-billion-laughs-i-xxe">Bezpieczeństwo: Billion Laughs i XXE</h3>
<p>Ponieważ pliki PPTX parsują XML, każdy serwerowy pipeline przyjmujący prezentacje przesłane przez użytkowników jest podatny na:</p>
<ul>
<li><strong>Wstrzyknięcie zewnętrznego podmiotu XML (XXE)</strong>: Złośliwy XML próbujący uzyskać dostęp do <code>/etc/passwd</code> lub zapytać wewnętrzne endpointy metadanych chmury (<code>http://169.254.169.254/</code>).</li>
<li><strong>Ataki rozszerzania podmiotów (Billion Laughs)</strong>: Eksponencjalne pętle podmiotów wyczerpujące pamięć RAM systemu.</li>
</ul>
<p><strong>Mitigacja</strong>: Zawsze wyłączaj <code>resolve_entities</code>, <code>load_dtd</code> oraz rozwiązywanie zewnętrznych sieci w parserze XML (np. używając <code>defusedxml</code> w Pythonie).</p>
<h3 id="bezpieczeństwo-ładunki-makr-i-ukryte-strumienie">Bezpieczeństwo: Ładunki Makr i Ukryte Strumienie</h3>
<p>Sprawdzaj pliki pod kątem zawartości <code>.pptm</code> podszywającej się pod rozszerzenia <code>.pptx</code>. Zwróć uwagę na <code>ppt/vbaProject.bin</code>, który zawiera skompilowany kod Visual Basic. W standardowych plikach <code>.pptx</code> kod VBA jest zabroniony; wykrycie odwołań do binarnych ładunków w relacjach powinno natychmiast wywołać flagi kwarantanny.</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p>Inżynieria wsteczna plików <code>.pptx</code> demistyfikuje oprogramowanie prezentacyjne. Gdy zrozumiesz, że pliki PowerPoint to po prostu strukturalne pakiety zip wypełnione współrzędnymi, odwołaniami do schematów i drzewami relacji XML, nie jesteś już ograniczony istniejącymi abstrakcjami firm trzecich.</p>
<p>Niezależnie od tego, czy optymalizujesz przepustowość generowania slajdów, piszesz własne automatyczne sanitizatory, czy rozwiązujesz problemy z renderowaniem, bezpośrednie spojrzenie na bazową architekturę OpenXML daje pełną kontrolę nad pipeline&rsquo;em prezentacji.</p>
<h2 id="najczęściej-zadawane-pytania-faq">Najczęściej zadawane pytania (FAQ)</h2>
<p>**Q: Czy możesz przekonwertować plik .pptx na standardowy folder i edytować pliki bezpośrednio w IDE?</p>
<p><strong>A1:</strong> Tak, możesz rozpakować archiwum, edytować XML w edytorze takim jak VS Code i ponownie spakować zawartość katalogu, aby otworzyć go ponownie w PowerPoint.</p>
<p>**Q: Dlaczego PowerPoint mówi, że mój ręcznie zmodyfikowany plik PPTX wymaga naprawy?</p>
<p><strong>A2:</strong> Zwykle dzieje się tak, gdy wprowadziłeś nieprawidłowy XML, pominąłeś nowy zasób w <code>[Content_Types].xml</code>, lub pozostawiłeś nieaktualne odwołanie w powiązanym pliku <code>.rels</code>.</p>
<p>**Q: Jaką jednostkę miary używa PowerPoint do położenia kształtów i marginesów?</p>
<p><strong>A3:</strong> PowerPoint używa jednostek English Metric Units (EMUs), gdzie 1 cal równa się 914 400 EMU, a 1 punkt równa się 12 700 EMU.</p>
<p>**Q: Jak mogę <a href="https://products.fileformat.com/presentation/python/python-pptx/">programowo wyodrębnić</a> wszystkie obrazy z prezentacji bez użycia zewnętrznych bibliotek?</p>
<p><strong>A4:</strong> Po prostu otwórz plik <code>.pptx</code> dowolnym standardowym narzędziem zip i wyodrębnij wszystkie pliki binarne znajdujące się w katalogu <code>ppt/media/</code>.</p>
<p>**Q: Czy bezpieczne jest parsowanie przesłanych przez użytkowników plików PPTX przy użyciu standardowych parserów XML?</p>
<p><strong>A5:</strong> Nie, musisz wzmocnić swój parser lub użyć bezpiecznych wrapperów, takich jak <code>defusedxml</code>, aby zablokować ataki XML External Entity (XXE) oraz zip‑bomb.</p>
<h2 id="zobacz-także">Zobacz także</h2>
<ul>
<li><a href="https://blog.fileformat.com/presentation/powerpoint-file-formats/">Formaty plików prezentacji na FileFormat.com?</a></li>
<li><a href="https://blog.fileformat.com/presentation/apache-poi-api-to-access-powerpoint-file-formats/">Java API do dostępu do formatów plików PowerPoint</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 – porównanie formatów prezentacji</a></li>
<li><a href="https://blog.fileformat.com/presentation/difference-between-ppt-and-pptx/">Różnica między PPT a PPTX</a></li>
<li><a href="https://blog.fileformat.com/presentation/create-presentation-in-java-with-apache-poi-api/">Tworzenie prezentacji PowerPoint w Javie przy użyciu Apache POI API</a></li>
</ul>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    
  </channel>
</rss>
