<?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 on File Format Blog</title>
    <link>https://blog.fileformat.com/ru/tag/%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-%D0%B8%D0%BD%D0%B6%D0%B8%D0%BD%D0%B8%D1%80%D0%B8%D0%BD%D0%B3-pptx/</link>
    <description>Recent content in Обратный Инжиниринг PPTX on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ru</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/ru/tag/%D0%BE%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D0%B9-%D0%B8%D0%BD%D0%B6%D0%B8%D0%BD%D0%B8%D1%80%D0%B8%D0%BD%D0%B3-pptx/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Обратный Инжиниринг PPTX: Понимание внутренней структуры файлов PowerPoint</title>
      <link>https://blog.fileformat.com/ru/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/ru/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</guid>
      <description>Узнайте, что действительно находится внутри файла `.pptx`. Узнайте, как работают упаковка OpenXML, графы связей, фигуры и разметка рисунков под капотом.</description>
      <content:encoded><![CDATA[<p><strong>Последнее обновление</strong>: 16 сент., 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="обратный-инжиниринг-файлов-pptx4-руководство-для-разработчиков">Обратный Инжиниринг файлов <a href="https://docs.fileformat.com/presentation/pptx/">PPTX</a>: Руководство для разработчиков</h2>
<p>Современные презентационные наборы поддерживают всё — от презентаций для инвесторов до внутренних квартальных метрик. Но если вам когда‑нибудь приходилось программно извлекать текст, заменять шаблоны во время выполнения, создавать автоматические генераторы слайдов или очищать конфиденциальные презентации, вы, вероятно, быстро поняли следующее: стандартные высокоуровневые библиотеки для работы с презентациями могут ощущаться как непредсказуемый «чёрный ящик».</p>
<p>Когда такие библиотеки, как <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> или <a href="https://products.fileformat.com/presentation/net/openxmlsdk/">OpenXML SDK</a>, достигают своих пределов — или вводят недокументированные ошибки макета — единственный выход — пройти сквозь них. Вам необходимо понять, что собой представляет презентация PowerPoint на уровне байтов и схемы.</p>
<p>В этом глубоком разборе мы приподнимем завесу над форматом <code>.pptx</code>, разберём его внутреннюю структуру, проследим граф отношений, разложим иерархии рисунков и рассмотрим практические стратегии обратного проектирования, инспекции и манипуляции презентациями с помощью сырого кода.</p>
<h2 id="1-что-такое-файл-pptx-на-самом-деле">1. Что такое файл <code>.pptx</code> на самом деле?</h2>
<p>По сути, файл <code>.pptx</code> не является проприетарным монолитным бинарным файлом, как древний формат <code>.ppt</code> 1990‑х годов. С тех пор как Microsoft представила Office Open XML (ECMA‑376 и ISO/IEC 29500), современные документы Office являются <strong>архивами Open Packaging Conventions (OPC)</strong>.</p>
<p>Простыми словами: <strong>файл <code>.pptx</code> — это просто zip‑архив, содержащий XML‑документы и медиа‑ресурсы, организованные в детерминированное дерево каталогов.</strong></p>
<p>Вы можете доказать это за секунды, используя стандартные инструменты терминала:</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>Получившееся дерево каталогов выглядит удивительно согласованно:</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>Каждый отдельный визуальный ресурс, переход, наследование шаблона слайда, координаты текстового поля и векторная графика закодированы в этой иерархии файлов.</p>
<h2 id="2-структура-пакета-ключевые-подсистемы">2. Структура пакета: ключевые подсистемы</h2>
<p>Чтобы эффективно проводить обратный инжиниринг презентаций, вы должны понимать функции каждого компонента верхнего уровня.</p>
<h3 id="content_typesxml"><code>[Content_Types].xml</code></h3>
<p>Это манифест входа для читателя OPC. Он сопоставляет расширения файлов и явные внутренние имена частей со стандартными типами MIME/контента. Если вы создаёте новый слайд или добавляете изображение и не укажете его в <code>[Content_Types].xml</code>, PowerPoint объявит набор повреждённым и предложит восстановление.</p>
<p>Пример фрагмента:</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="граф-отношений-_rels">Граф отношений <code>_rels/</code></h3>
<p>Одна из самых важных концепций в OpenXML — <strong>непрямой доступ через отношения</strong>. Части редко указывают напрямую на сырые пути к файлам. Вместо этого файл (например, <code>slide1.xml</code>) имеет связанный файл отношений, расположенный в соседней папке <code>_rels</code> (например, <code>_rels/slide1.xml.rels</code>).</p>
<p>Отношения определяют:</p>
<ul>
<li>Гиперссылки (<code>r:id=&quot;rId2&quot;</code>, TargetMode=&ldquo;External&rdquo;)</li>
<li>Изображения и аудиодорожки, хранящиеся в <code>ppt/media/</code></li>
<li>Указатели наследования макета (<code>slideLayout1.xml</code>)</li>
<li>Слайды заметок, комментарии и встроенные шрифты</li>
</ul>
<h3 id="docprops-метаданные"><code>docProps/</code> (Метаданные)</h3>
<ul>
<li><strong><code>core.xml</code></strong>: метаданные Dublin Core — автор, заголовок, дата создания, метка времени изменения.</li>
<li><strong><code>app.xml</code></strong>: специфическая для приложения статистика — версия PowerPoint, общее количество слайдов, количество скрытых слайдов, количество слов, имена шаблонов презентаций.</li>
</ul>
<h3 id="ppt-движок-презентаций"><code>ppt/</code> (Движок презентаций)</h3>
<p>Здесь находится фактическая презентация:</p>
<ul>
<li><strong><code>presentation.xml</code></strong>: Главный каркас. Он регистрирует идентификаторы слайдов, размеры слайдов, ссылки на мастер заметок и настройки шрифта по умолчанию.</li>
<li><strong><code>slides/</code></strong>: Отдельные слайды (<code>slide1.xml</code>, <code>slide2.xml</code> и т.д.).</li>
<li><strong><code>slideLayouts/</code></strong>: Предустановки основной структуры (Титульный слайд, Два столбца, Заголовок раздела).</li>
<li><strong><code>slideMasters/</code></strong>: Глобальные стили, палитры по умолчанию, фоновые заливки и наследование заполнителей.</li>
<li><strong><code>theme/</code></strong>: Цветовые палитры (акцент 1‑6, тёмные/светлые варианты) и схемы шрифтов (основные/второстепенные шрифты).</li>
<li><strong><code>media/</code></strong>: Исходные изображения (PNG, JPEG, SVG), аудио и видеофайлы.</li>
</ul>
<h2 id="3-разбор-слайда-диалекты-presentationml-p--drawingml-a">3. Разбор слайда: диалекты PresentationML (<code>p:</code>) &amp; DrawingML (<code>a:</code>)</h2>
<p>Когда вы открываете <code>ppt/slides/slide1.xml</code>, вы сталкиваетесь с двумя основными XML‑пространствами имён:</p>
<ol>
<li><strong>PresentationML (<code>p:</code>)</strong>: Управляет структурными элементами презентации (слайды, древовидные структуры фигур, группы холста).</li>
<li><strong>DrawingML (<code>a:</code>)</strong>: Управляет типографикой, геометрией, 2‑мерными координатами, градиентными заливками и векторным рендерингом.</li>
</ol>
<p>Ниже приведён упрощённый пример того, как выглядит стандартная текстовая фигура:</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="ключевые-единицы-измерения-emu-и-сотые-доли-пункта">Ключевые единицы измерения: EMU и сотые доли пункта</h3>
<p>Обратите внимание на числовые координаты в <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>Это <strong>английские метрические единицы (EMUs)</strong>.</p>
<ul>
<li>$1 \text{ inch} = 914,400 \text{ EMUs}$</li>
<li>$1 \text{ см} = 360,000 \text{ EMUs}$</li>
<li>$1 \text{ пт} = 12,700 \text{ EMUs}$</li>
</ul>
<p>EMUs позволяют использовать целые числа для точного представления дробей как дюймов, так и миллиметров без ошибок округления с плавающей точкой на разных аппаратных архитектурах.</p>
<p>Обратите также внимание на размер шрифта:</p>
<ul>
<li><code>sz=&quot;3200&quot;</code> означает <strong>32.00 пт</strong>. Размеры шрифтов в DrawingML измеряются в сотых долях пункта.</li>
</ul>
<h2 id="4-цепочка-наследования-почему-фигуры-наследуют-невидимые-стили">4. Цепочка наследования: почему фигуры наследуют невидимые стили</h2>
<p>Одной из самых распространённых ловушек при обратном проектировании файлов PPTX является предположение, что визуальное оформление фигуры полностью объявлено внутри её собственного <code>slideX.xml</code>.</p>
<p>На самом деле OpenXML опирается на строгую <strong>четырёхуровневую каскадную модель наследования</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>Если текстовое поле в <code>slide1.xml</code> содержит:</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>Для запуска (<code>&lt;a:r&gt;</code>) не указаны семейство шрифтов, явный цвет и размер. Чтобы понять, как PowerPoint отображает этот текст, ваш парсер должен:</p>
<ol>
<li>Определите тип заполнителя (<code>&lt;p:ph type=&quot;title&quot;/&gt;</code>).</li>
<li>Прочитайте макет, указанный в <code>slide1.xml.rels</code>.</li>
<li>Проверьте, предоставляет ли <code>slideLayout1.xml</code> переопределения стилей для этого заполнителя.</li>
<li>Обратитесь к <code>slideMaster1.xml</code> для получения стилей текста заголовка по умолчанию.</li>
<li>Отследите цветовые токены, такие как <code>accent1</code> или <code>tx1</code>, в <code>theme1.xml</code>, чтобы найти шестнадцатеричный код цвета.</li>
</ol>
<p>Если вы пропустите эту графу наследования, ваш парсер неправильно прочитает стили, пропустит шрифты, размеры шрифтов и привязки макета.</p>
<h2 id="5-практический-процесс-обратного-проектирования">5. Практический процесс обратного проектирования</h2>
<p>Когда необходимо исследовать, как работает конкретная функция PowerPoint изнутри (например, морф‑переходы, сложные таблицы, векторные пути), следуйте этому эмпирическому подходу:</p>
<h3 id="шаг-1-создать-минимальную-пару-различий">Шаг 1: Создать минимальную &ldquo;Пару различий&rdquo;</h3>
<ol>
<li>Откройте PowerPoint и создайте пустой слайд.</li>
<li>Сохраните его как <code>before.pptx</code>.</li>
<li>Внесите точное единственное изменение, которое вы хотите проанализировать (например, добавьте теневой эффект к кругу, измените стиль маркера, вставьте встроенное видео).</li>
<li>Сохраните его как <code>after.pptx</code>.</li>
</ol>
<h3 id="шаг-2-распаковать-оба-архива">Шаг 2: Распаковать оба архива</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="шаг-3-форматировать-xml">Шаг 3: Форматировать XML</h3>
<p>Сырой XML внутри архивов Office обычно лишён отступов и символов новой строки. Перед сравнением отформатируйте файлы:</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="шаг-4-выполнить-объединённый-diff">Шаг 4: Выполнить объединённый 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>Просмотр <code>changes.patch</code> показывает точное имя тега, атрибут пространства имён и иерархию контейнеров, которые добавил PowerPoint. Это самый быстрый способ обнаружить недокументированные или малоизвестные свойства схемы без необходимости просматривать тысячи страниц документации ECMA-376.</p>
<h2 id="6-создание-пользовательского-микродвижка-распаковать-изменить-упаковать-заново">6. Создание пользовательского микродвижка: распаковать, изменить, упаковать заново</h2>
<p>Иногда вам не нужна тяжёлая корпоративная зависимость, такая как Apache POI или Microsoft OpenXML SDK — особенно в лёгких безсерверных средах выполнения (AWS Lambda, Cloudflare Workers, edge‑узлы).</p>
<p>Ниже приведён автономный пример на Python, демонстрирующий, как безопасно распаковать PPTX в памяти, внедрить пользовательские данные с помощью стандартных библиотек и упаковать его обратно:</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="ключевые-подводные-камни-при-модификации-файлов-на-уровне-необработанных-байтов">Ключевые подводные камни при модификации файлов на уровне необработанных байтов:</h3>
<ol>
<li><strong>Сохранение пространств имён</strong>: XML‑парсеры часто переписывают префиксы (<code>xmlns:p</code> может стать <code>xmlns:ns0</code>). Хотя это валидный XML, строгая внутренняя проверка схемы PowerPoint иногда отклоняет нестандартные псевдонимы префиксов. Регистрируйте пространства имён явно.</li>
<li><strong>Методы сжатия ZIP</strong>: Убедитесь, что вы записываете файлы обратно, используя стандартное сжатие deflate (<code>zipfile.ZIP_DEFLATED</code>).</li>
<li><strong>Сброс потока</strong>: Всегда проверяйте, что ваш zip‑буфер закрывается и полностью сбрасывается перед передачей байтов дальше.</li>
<li><strong>Сохранение связей</strong>: Если вы удаляете слайд, необходимо также удалить его запись из <code>ppt/presentation.xml</code>, удалить его связь в <code>ppt/_rels/presentation.xml.rels</code> и очистить его тип содержимого из <code>[Content_Types].xml</code>.</li>
</ol>
<h2 id="7-соображения-производительности-и-безопасности">7. Соображения производительности и безопасности</h2>
<p>Реверс‑инжиниринг файлов PPTX — это не только редактирование слайдов; это также аудит того, что попадает в ваши системы.</p>
<h3 id="безопасность-миллиард-смехов-и-xxe">Безопасность: Миллиард Смехов и XXE</h3>
<p>Поскольку файлы PPTX парсят XML, любой серверный конвейер, принимающий пользовательские презентации, уязвим к:</p>
<ul>
<li><strong>Внедрение внешних сущностей XML (XXE)</strong>: Зловредный XML, пытающийся получить доступ к <code>/etc/passwd</code> или выполнить запрос к внутренним конечным точкам метаданных облака (<code>http://169.254.169.254/</code>).</li>
<li><strong>Атаки расширения сущностей (Billion Laughs)</strong>: Экспоненциальные циклы сущностей, исчерпывающие оперативную память системы.</li>
</ul>
<p><strong>Смягчение</strong>: Всегда отключайте <code>resolve_entities</code>, <code>load_dtd</code> и разрешение внешних сетевых запросов в вашем XML‑парсере (например, используя <code>defusedxml</code> в Python).</p>
<h3 id="безопасность-макросные-полезные-нагрузки-и-скрытые-потоки">Безопасность: Макросные полезные нагрузки и скрытые потоки</h3>
<p>Проверяйте файлы на наличие содержимого <code>.pptm</code> под расширением <code>.pptx</code>. Обращайте внимание на <code>ppt/vbaProject.bin</code>, который содержит скомпилированный код Visual Basic. В стандартных файлах <code>.pptx</code> код VBA запрещён; обнаружение ссылок на бинарные полезные нагрузки в отношениях должно немедленно вызвать флаги карантина.</p>
<h2 id="заключение">Заключение</h2>
<p>Обратный инжиниринг файлов <code>.pptx</code> раскрывает тайны программ для презентаций. Как только вы поймёте, что файлы PowerPoint — это просто структурированные zip‑пакеты, заполненные координатами, ссылками на схемы и деревьями XML‑отношений, вы больше не будете ограничены существующими сторонними абстракциями.</p>
<p>Независимо от того, оптимизируете ли вы пропускную способность генерации слайдов, пишете пользовательские автоматические санитайзеры или устраняете сбои рендеринга, прямой взгляд на базовую архитектуру OpenXML предоставляет вам полный контроль над конвейером презентаций.</p>
<h2 id="часто-задаваемые-вопросы-faq">Часто задаваемые вопросы (FAQ)</h2>
<p>**Q: Можно ли преобразовать .pptx в обычную папку и редактировать файлы напрямую в IDE?</p>
<p><strong>A1:</strong> Да, вы можете извлечь архив, отредактировать XML в редакторе, таком как VS Code, и снова упаковать содержимое каталога в zip, чтобы открыть его в PowerPoint.</p>
<p>**Q: Почему PowerPoint сообщает, что мой вручную изменённый файл PPTX нуждается в ремонте?</p>
<p><strong>A2:</strong> Это обычно происходит, если вы ввели некорректный XML, пропустили новый ресурс в файле <code>[Content_Types].xml</code> или оставили висячую ссылку в связанном файле <code>.rels</code>.</p>
<p>**Q: Какую единицу измерения использует PowerPoint для позиций фигур и отступов?</p>
<p><strong>A3:</strong> PowerPoint использует английские метрические единицы (EMUs), где 1 дюйм равен 914,400 EMU, а 1 пункт — 12,700 EMU.</p>
<p>**Q: Как я могу <a href="https://products.fileformat.com/presentation/python/python-pptx/">программно извлечь</a> все изображения из презентации без внешних библиотек?</p>
<p><strong>A4:</strong> Просто откройте файл <code>.pptx</code> любой стандартной утилитой zip и извлеките все бинарные файлы, находящиеся в каталоге <code>ppt/media/</code>.</p>
<p>**Q: Безопасно ли разбирать загруженные пользователями файлы PPTX с помощью стандартных XML‑парсеров?</p>
<p><strong>A5:</strong> Нет, вам необходимо укрепить ваш парсер или использовать безопасные обёртки, такие как <code>defusedxml</code>, чтобы блокировать атаки XML External Entity (XXE) и zip‑бомбы.</p>
<h2 id="см-также">См. также</h2>
<ul>
<li><a href="https://blog.fileformat.com/presentation/powerpoint-file-formats/">Форматы файлов презентаций на FileFormat.com?</a></li>
<li><a href="https://blog.fileformat.com/presentation/apache-poi-api-to-access-powerpoint-file-formats/">Java API для доступа к форматам файлов PowerPoint</a></li>
<li><a href="https://blog.fileformat.com/presentation/odp-vs-pptx-opendocument-vs-microsoft-powerpoint-format-comparison/">ODP vs PPTX: OpenDocument против формата презентаций Microsoft PowerPoint</a></li>
<li><a href="https://blog.fileformat.com/presentation/difference-between-ppt-and-pptx/">Разница между PPT и PPTX</a></li>
<li><a href="https://blog.fileformat.com/presentation/create-presentation-in-java-with-apache-poi-api/">Создать презентацию PowerPoint на Java с помощью Apache POI API</a></li>
</ul>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    
  </channel>
</rss>
