<?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/ja/tag/%E7%84%A1%E6%96%99-pptx-%E3%82%AF%E3%83%AA%E3%82%A8%E3%82%A4%E3%82%BF%E3%83%BC/</link>
    <description>Recent content in 無料 PPTX クリエイター on File Format Blog</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja</language>
    <lastBuildDate>Wed, 16 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.fileformat.com/ja/tag/%E7%84%A1%E6%96%99-pptx-%E3%82%AF%E3%83%AA%E3%82%A8%E3%82%A4%E3%82%BF%E3%83%BC/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>PPTXリバースエンジニアリング：PowerPointファイルの内部構造を理解する</title>
      <link>https://blog.fileformat.com/ja/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</link>
      <pubDate>Wed, 16 Sep 2026 00:00:00 +0000</pubDate>
      
      <guid>https://blog.fileformat.com/ja/presentation/pptx-reverse-engineering-understanding-powerpoint-files-internally/</guid>
      <description>`.pptx` ファイルの内部に実際に何があるかを発見しましょう。OpenXML パッケージング、リレーションシップ グラフ、シェイプ、描画マークアップがどのように機能しているかを学びます。</description>
      <content:encoded><![CDATA[<p><strong>最終更新</strong>: 2026年9月16日</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> ファイルは 1990 年代の古い <code>.ppt</code> フォーマットのような独自のモノリシックバイナリではありません。Microsoft が Office Open XML（ECMA-376 および ISO/IEC 29500）を導入して以来、最新の Office ドキュメントは <strong>Open Packaging Conventions (OPC) アーカイブ</strong> です。</p>
<p>簡単に言えば、<strong><code>.pptx</code> ファイルは単に XML ドキュメントとメディア資産を含む zip アーカイブで、決定的なディレクトリツリーに整理されています。</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=&quot;External&quot;）</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>: マスタースパインです。スライドID、スライドサイズの寸法、ノートマスタ参照、デフォルトフォント設定を登録します。</li>
<li><strong><code>slides/</code></strong>: 個々のスライド（<code>slide1.xml</code>、<code>slide2.xml</code> など）。</li>
<li><strong><code>slideLayouts/</code></strong>: マスタ構造プリセット（タイトルスライド、2カラム、セクションヘッダー）。</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>) と DrawingML (<code>a:</code>) の方言</h2>
<p><code>ppt/slides/slide1.xml</code> を開くと、2つの主要なXML名前空間に出会います:</p>
<ol>
<li><strong>PresentationML (<code>p:</code>)</strong>: 構造的なプレゼンテーション要素（スライド、シェイプツリー、キャンバスグループ）を管理します。</li>
<li><strong>DrawingML (<code>a:</code>)</strong>: タイポグラフィ、ジオメトリ、2D座標、グラデーション塗り、ベクター描画を管理します。</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>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>EMUs は、整数を使用してインチとミリメートルの両方の正確な分数を表現でき、異なるハードウェアアーキテクチャ間での浮動小数点丸め誤差を防ぎます。</p>
<p>フォントサイズにも注目してください：</p>
<ul>
<li><code>sz=&quot;3200&quot;</code> は <strong>32.00 pt</strong> を意味します。DrawingML のフォントサイズはポイントの百分の一単位で測定されます。</li>
</ul>
<h2 id="4-継承チェーン-シェイプが不可視スタイルを継承する理由">4. 継承チェーン: シェイプが不可視スタイルを継承する理由</h2>
<p>PPTX ファイルをリバースエンジニアリングする際の最も一般的な落とし穴の一つは、シェイプの視覚的スタイリングがその独自の <code>slideX.xml</code> 内に完全に宣言されていると想定することです。</p>
<p>実際には、OpenXML は厳密な <strong>4-tier cascading inheritance model</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-最小限のdiff-pairを作成する">ステップ 1: 最小限の&quot;Diff Pair&quot;を作成する</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>Office アーカイブ内の生の XML は通常、インデントや改行文字が除去されています。差分を取る前に、ファイルを整形してください：</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、エッジノード）では。</p>
<p>以下は、メモリ上の PPTX を安全に解凍し、標準ライブラリツールを使用してカスタムデータを注入し、再パッケージ化する方法を示す自己完結型の Python パターンです：</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>Namespace Preservation</strong>: XML パーサはしばしばプレフィックスを書き換えます（<code>xmlns:p</code> が <code>xmlns:ns0</code> になることがあります）。有効な XML ですが、PowerPoint の厳格な内部スキーマ検証は時折、標準外のプレフィックスエイリアスを拒否します。名前空間は明示的に登録してください。</li>
<li><strong>ZIP Compression Methods</strong>: 標準のデフレート圧縮（<code>zipfile.ZIP_DEFLATED</code>）を使用してファイルを書き戻すようにしてください。</li>
<li><strong>Stream Flushing</strong>: バイトを下流に送信する前に、zip バッファが完全に閉じられ、フラッシュされていることを必ず確認してください。</li>
<li><strong>Preserve Relationships</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">セキュリティ: ビリオン・ラフス &amp; XXE</h3>
<p>PPTX ファイルは XML を解析するため、ユーザーが提出したプレゼンテーションを取り込むサーバー側パイプラインは以下の脅威にさらされます：</p>
<ul>
<li><strong>XML External Entity (XXE) Injection</strong>: <code>/etc/passwd</code> へのアクセスや内部クラウドメタデータエンドポイント（<code>http://169.254.169.254/</code>）へのクエリを試みる悪意ある XML。</li>
<li><strong>Entity Expansion Attacks (Billion Laughs)</strong>: システムの RAM を使い果たす指数的なエンティティループ。</li>
</ul>
<p><strong>緩和策</strong>: 常に XML パーサーで <code>resolve_entities</code>、<code>load_dtd</code>、および外部ネットワーク解決を無効にしてください（例: Python の <code>defusedxml</code> を使用）。</p>
<h3 id="セキュリティ-マクロペイロードと隠れたストリーム">セキュリティ: マクロペイロードと隠れたストリーム</h3>
<p><code>.pptm</code> コンテンツが <code>.pptx</code> 拡張子で偽装していないかファイルを検査してください。コンパイルされた Visual Basic コードを含む <code>ppt/vbaProject.bin</code> に注意してください。標準の <code>.pptx</code> ファイルでは VBA コードは禁止されており、リレーションシップ内でバイナリペイロードの参照が見つかった場合は直ちに隔離フラグを発動すべきです。</p>
<h2 id="結論">結論</h2>
<p><code>.pptx</code> ファイルのリバースエンジニアリングはプレゼンテーションソフトウェアの謎を解き明かします。PowerPoint ファイルが座標、スキーマ参照、XML リレーションシップツリーで構成された単純な zip パッケージであることを認識すれば、既存のサードパーティ抽象に縛られることはなくなります。</p>
<p>スライド生成のスループットを最適化する場合でも、カスタム自動サニタイザーを作成する場合でも、レンダリングの不具合をトラブルシュートする場合でも、基盤となる OpenXML アーキテクチャを直接見ることで、プレゼンテーションパイプラインを完全に制御できます。</p>
<h2 id="よくある質問-faq">よくある質問 (FAQ)</h2>
<p>**Q: .pptx を標準フォルダーに変換し、IDE で直接ファイルを編集できますか？</p>
<p><strong>A1:</strong> はい、アーカイブを展開し、VS Code のようなエディタで XML を編集し、ディレクトリの内容を再度 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> 任意の標準的な zip ユーティリティで <code>.pptx</code> ファイルを開き、<code>ppt/media/</code> ディレクトリ内にあるすべてのバイナリファイルを抽出するだけです。</p>
<p>**Q: 標準の XML パーサーでユーザーがアップロードした PPTX ファイルを解析するのは安全ですか？</p>
<p><strong>A5:</strong> いいえ、パーサーを強化するか、<code>defusedxml</code> のような安全なラッパーを使用して XML 外部エンティティ (XXE) や zip‑bomb 攻撃を防止する必要があります。</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/">PowerPoint ファイル形式にアクセスする Java API</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/">Apache POI API を使用した Java での PowerPoint プレゼンテーション作成</a></li>
</ul>
<!-- raw HTML omitted -->
]]></content:encoded>
    </item>
    
  </channel>
</rss>
