Dernière mise à jour : 16 sept., 2026

Ingénierie inverse PPTX des fichiers : Guide du développeur
Les présentations modernes alimentent tout, des pitchs investisseurs aux métriques trimestrielles internes. Mais si vous avez déjà dû extraire du texte de façon programmatique, remplacer des modèles à l’exécution, créer des générateurs de diapositives automatisés ou assainir des présentations confidentielles, vous avez probablement rapidement réalisé que les bibliothèques de présentation de haut niveau peuvent ressembler à une boîte noire imprévisible.
Lorsque des bibliothèques comme python-pptx, Apache POI ou OpenXML SDK atteignent leurs limites — ou introduisent des bugs de mise en page non documentés — la seule issue est de passer au travers. Vous devez comprendre ce qu’est réellement une présentation PowerPoint au niveau des octets et du schéma.
Dans cette plongée approfondie, nous lèverons le voile sur le format .pptx, déballerons sa structure interne, tracerons son graphe de relations, disséquerons ses hiérarchies de dessin, et examinerons des stratégies pratiques pour l’ingénierie inverse, l’inspection et la manipulation de présentations avec du code brut.
1. Qu’est‑ce qu’un fichier .pptx réellement ?
En son cœur, un fichier .pptx n’est pas un binaire propriétaire monolithique comme l’ancien format .ppt des années 1990. Depuis que Microsoft a introduit Office Open XML (ECMA-376 et ISO/IEC 29500), les documents Office modernes sont des archives Open Packaging Conventions (OPC).
En termes simples : un fichier .pptx est simplement une archive zip contenant des documents XML et des ressources multimédias organisés dans un arbre de répertoires déterministe.
Vous pouvez le prouver en quelques secondes en utilisant les outils standard du terminal :
# Rename the extension and unpack it
cp presentation.pptx presentation.zip
unzip presentation.zip -d presentation_unpacked/
cd presentation_unpacked/
tree -L 2
L’arbre de répertoires résultant apparaît remarquablement cohérent :
.
├── [Content_Types].xml
├── _rels/
│ └── .rels
├── docProps/
│ ├── app.xml
│ └── core.xml
└── ppt/
├── presentation.xml
├── _rels/
├── slides/
├── slideLayouts/
├── slideMasters/
├── theme/
└── media/
Chaque ressource visuelle, transition, héritage du masque de diapositive, coordonnées de zone de texte et graphique vectoriel est codifié dans cette hiérarchie de fichiers.
2. Anatomie du paquet : sous‑systèmes clés
Pour rétroconcevoir efficacement les présentations, vous devez comprendre les responsabilités de chaque composant de niveau supérieur.
[Content_Types].xml
Ceci est le manifeste d’entrée pour le lecteur OPC. Il associe les extensions de fichiers et les noms de parties internes explicites aux types MIME/contenu standardisés. Si vous créez une nouvelle diapositive ou ajoutez une image et omettez de la déclarer dans [Content_Types].xml, PowerPoint déclarera le diaporama corrompu et demandera une récupération.
Exemple d’extrait :
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="xml" ContentType="application/xml"/>
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="png" ContentType="image/png"/>
<Override PartName="/ppt/presentation.xml"
ContentType="application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml"/>
</Types>
Le graphe de relations _rels/
L’un des concepts les plus cruciaux d’OpenXML est l’indirection via les relations. Les parties pointent rarement directement vers des chemins de fichiers bruts. Au lieu de cela, un fichier (par ex., slide1.xml) possède un fichier de relation associé situé dans un dossier frère _rels (par ex., _rels/slide1.xml.rels).
Les relations définissent :
- Hyperliens (
r:id=\"rId2\", TargetMode="External") - Images et pistes audio stockées dans
ppt/media/ - Pointeurs d’héritage de mise en page (
slideLayout1.xml) - Diapositives de notes, commentaires et polices intégrées
docProps/ (Métadonnées)
core.xml: métadonnées Dublin Core — auteur, titre, date de création, horodatage de modification.app.xml: statistiques spécifiques à l’application — version de PowerPoint, nombre total de diapositives, nombre de diapositives masquées, nombre de mots, noms de modèles de présentation.
ppt/ (Le moteur de présentation)
C’est ici que la présentation réelle se trouve :
presentation.xml: L’épine dorsale principale. Elle enregistre les ID des diapositives, les dimensions de la taille des diapositives, les références du maître des notes et les paramètres de police par défaut.slides/: Les diapositives individuelles (slide1.xml,slide2.xml, etc.).slideLayouts/: Préréglages structurels maîtres (Diapositive Titre, Deux Colonnes, En-tête de Section).slideMasters/: Styles globaux, palettes par défaut, remplissages d’arrière-plan et héritage des espaces réservés.theme/: Palettes de couleurs (accent 1 à 6, variantes sombre/clair) et schémas de polices (polices principales/secondaires).media/: Images brutes (PNG, JPEG, SVG), audio et fichiers vidéo.
3. Dissection d’une diapositive : les dialectes PresentationML (p:) et DrawingML (a:)
Lorsque vous ouvrez ppt/slides/slide1.xml, vous rencontrez deux espaces de noms XML principaux :
- PresentationML (
p:) : Gère les éléments de présentation structurels (diapositives, arbres de formes, groupes de canevas). - DrawingML (
a:) : Gère la typographie, la géométrie, les coordonnées 2D, les remplissages en dégradé et le rendu vectoriel.
Voici un exemple simplifié de ce à quoi ressemble une forme de texte standard :
<p:sp>
<!-- 1. Non-visual shape properties (Identifiers, names) -->
<p:nvSpPr>
<p:cNvPr id="4" name="Title Box 1"/>
<p:cNvSpPr>
<a:spLocks noGrp="1"/>
</p:cNvSpPr>
<p:nvPr>
<p:ph type="title"/>
</p:nvPr>
</p:nvSpPr>
<!-- 2. Visual shape properties (Position, size, geometry) -->
<p:spPr>
<a:xfrm>
<a:off x="1524000" y="1143000"/>
<a:ext cx="9144000" cy="1828800"/>
</a:xfrm>
<a:prstGeom prst="rect">
<a:avLst/>
</a:prstGeom>
<a:solidFill>
<a:schemeClr val="accent1"/>
</a:solidFill>
</p:spPr>
<!-- 3. Text Body (Paragraphs, runs, styling) -->
<p:txBody>
<a:bodyPr rtlCol="0" anchor="ctr"/>
<a:lstStyle/>
<a:p>
<a:r>
<a:rPr lang="en-US" sz="3200" b="1"/>
<a:t>Mission Critical Architecture</a:t>
</a:r>
</a:p>
</p:txBody>
</p:sp>
Unités de mesure cruciales : EMU et centièmes de point
Remarquez les nombres de coordonnées dans <a:xfrm> :
x="1524000"cx="9144000"
Ce sont des unités métriques anglaises (EMUs).
- $1 \text{ pouce} = 914,400 \text{ EMUs}$
- $1 \text{ cm} = 360,000 \text{ EMUs}$
- $1 \text{ pt} = 12,700 \text{ EMUs}$
Les EMUs permettent aux entiers de représenter des fractions exactes à la fois de pouces et de millimètres sans erreurs d’arrondi en virgule flottante sur différentes architectures matérielles.
Remarquez également la taille de la police :
sz=\"3200\"signifie 32,00 pt. Les tailles de police dans DrawingML sont mesurées en centièmes de point.
4. La chaîne d’héritage : pourquoi les formes héritent de styles invisibles
L’un des pièges les plus courants lors de la rétro‑ingénierie des fichiers PPTX est de supposer que le style visuel d’une forme est entièrement déclaré dans son propre slideX.xml.
En réalité, OpenXML repose sur un modèle d’héritage en cascade à 4 niveaux :
[Theme: ppt/theme/theme1.xml]
│
▼
[Slide Master: ppt/slideMasters/slideMaster1.xml]
│
▼
[Slide Layout: ppt/slideLayouts/slideLayout1.xml]
│
▼
[Slide: ppt/slides/slide1.xml]
Si une zone de texte dans slide1.xml contient :
<a:p>
<a:r>
<a:t>Revenue Projections</a:t>
</a:r>
</a:p>
Il n’y a aucune famille de polices, aucune couleur explicite, et aucune taille déclarée sur le run (<a:r>). Pour déterminer comment PowerPoint rend ce texte, votre analyseur doit :
- Identifier le type d’espace réservé (
<p:ph type="title"/>). - Lire la disposition référencée dans
slide1.xml.rels. - Vérifier si
slideLayout1.xmlfournit des surcharges de style pour cet espace réservé. - Revenir à
slideMaster1.xmlpour les styles par défaut du corps de texte du titre. - Tracer les jetons de couleur comme
accent1outx1danstheme1.xmlpour trouver le code couleur hexadécimal.
Si vous ignorez ce graphe d’héritage, votre analyseur lira mal les styles, les polices manquantes, les tailles de police et les ancres de mise en page.
5. Flux de travail pratique d’ingénierie inverse
Lorsque vous devez enquêter sur le fonctionnement interne d’une fonctionnalité particulière de PowerPoint (par exemple, les transitions morph, les tableaux complexes, les tracés vectoriels), suivez cette approche empirique :
Étape 1 : Créer une “paire de différences” minimale
- Ouvrez PowerPoint et créez une diapositive vierge.
- Enregistrez-le sous le nom
before.pptx. - Appliquez le changement unique exact que vous souhaitez rétroconcevoir (par ex., ajoutez une ombre portée à un cercle, modifiez le style d’une puce, insérez une vidéo intégrée).
- Enregistrez-le sous le nom
after.pptx.
Étape 2 : Décompresser les deux archives
unzip before.pptx -d before/
unzip after.pptx -d after/
Étape 3 : Formater le XML
Le XML brut à l’intérieur des archives Office est généralement dépourvu d’indentation et de caractères de nouvelle ligne. Avant de faire un diff, formatez les fichiers :
find before/ after/ -name "*.xml" -exec xmllint --format {} --output {} \;
Étape 4 : Exécuter un diff unifié
diff -uNr before/ after/ > changes.patch
L’examen de changes.patch révèle le nom exact de la balise, l’attribut d’espace de noms et la hiérarchie du conteneur introduits par PowerPoint. C’est le moyen le plus rapide de découvrir des propriétés de schéma non documentées ou obscures sans fouiller des milliers de pages de documentation ECMA-376.
6. Construire un micro-moteur personnalisé : décompresser, modifier, recompresser
Parfois, vous ne voulez pas d’une dépendance d’entreprise lourde comme Apache POI ou le SDK Microsoft OpenXML — surtout dans des environnements serverless légers (AWS Lambda, Cloudflare Workers, nœuds edge).
Voici un modèle Python autonome démontrant comment décompresser en toute sécurité un PPTX en mémoire, injecter des données personnalisées à l’aide des outils de la bibliothèque standard, puis le reconditionner :
import zipfile
import io
import xml.etree.ElementTree as ET
def modify_slide_title(input_pptx_bytes: bytes, new_title: str) -> bytes:
input_zip = zipfile.ZipFile(io.BytesIO(input_pptx_bytes))
output_buffer = io.BytesIO()
with zipfile.ZipFile(output_buffer, "w", zipfile.ZIP_DEFLATED) as output_zip:
for item in input_zip.infolist():
content = input_zip.read(item.filename)
# Target slide 1
if item.filename == "ppt/slides/slide1.xml":
namespaces = {
'p': 'http://schemas.openxmlformats.org/presentationml/2006/main',
'a': 'http://schemas.openxmlformats.org/drawingml/2006/main'
}
# Register namespaces to preserve prefixes
for prefix, uri in namespaces.items():
ET.register_namespace(prefix, uri)
root = ET.fromstring(content)
# Find title placeholder text run
for title_run in root.findall(".//p:sp[p:nvSpPr/p:nvPr/p:ph[@type='title']]//a:t", namespaces):
title_run.text = new_title
break
content = ET.tostring(root, encoding="utf-8", xml_declaration=True)
output_zip.writestr(item, content)
return output_buffer.getvalue()
Points clés à retenir lors de la modification des fichiers au niveau du octet brut :
- Préservation des espaces de noms : les analyseurs XML réécrivent souvent les préfixes (
xmlns:ppeut devenirxmlns:ns0). Bien que XML valide, la validation stricte du schéma interne de PowerPoint rejette parfois les alias de préfixe non standard. Enregistrez explicitement les espaces de noms. - Méthodes de compression ZIP : assurez-vous d’écrire les fichiers en utilisant la compression deflate standard (
zipfile.ZIP_DEFLATED). - Vidage du flux : vérifiez toujours que votre tampon zip se ferme et se vide complètement avant d’envoyer les octets en aval.
- Préserver les relations : si vous supprimez une diapositive, vous devez également supprimer son entrée dans
ppt/presentation.xml, supprimer sa relation dansppt/_rels/presentation.xml.rels, et nettoyer son type de contenu dans[Content_Types].xml.
7. Considérations de performance et de sécurité
Le rétro‑ingénierie des fichiers PPTX ne consiste pas seulement à modifier les diapositives ; il s’agit également d’auditer ce qui entre dans vos systèmes.
Sécurité : Billion Laughs & XXE
Comme les fichiers PPTX analysent du XML, toute chaîne de traitement côté serveur qui ingère des présentations soumises par les utilisateurs est vulnérable à :
- Injection d’entité externe XML (XXE) : XML malveillant tentant d’accéder à
/etc/passwdou d’interroger les points de terminaison de métadonnées cloud internes (http://169.254.169.254/). - Attaques d’expansion d’entités (Billion Laughs) : boucles d’entités exponentielles épuisant la RAM du système.
Atténuation: Désactivez toujours resolve_entities, load_dtd et la résolution réseau externe dans votre analyseur XML (par exemple, en utilisant defusedxml en Python).
Sécurité : Macro Payloads et flux cachés
Inspectez les fichiers à la recherche de contenu .pptm se masquant sous des extensions .pptx. Faites attention à ppt/vbaProject.bin, qui contient du code Visual Basic compilé. Dans les fichiers .pptx standard, le code VBA est interdit ; la découverte de références de charges utiles binaires dans les relations doit immédiatement déclencher des drapeaux de mise en quarantaine.
Conclusion
L’ingénierie inverse des fichiers .pptx démystifie les logiciels de présentation. Une fois que vous reconnaissez que les fichiers PowerPoint ne sont que des packages zip structurés contenant des coordonnées, des références de schéma et des arbres de relations XML, vous n’êtes plus limité par les abstractions tierces existantes.
Que vous optimisiez le débit de génération des diapositives, écriviez des désinfectants automatisés personnalisés ou dépanniez des problèmes d’affichage, examiner directement l’architecture OpenXML sous-jacente vous donne un contrôle total sur le pipeline de présentation.
Foire aux questions (FAQ)
**Q: Pouvez-vous convertir un .pptx en dossier standard et modifier les fichiers directement dans un IDE ?
R1: Oui, vous pouvez extraire l’archive, modifier le XML dans un éditeur comme VS Code, puis re-compresser le contenu du répertoire pour le rouvrir dans PowerPoint.
**Q: Pourquoi PowerPoint indique-t-il que mon fichier PPTX modifié manuellement nécessite une réparation ?
A2: Cela se produit généralement si vous avez introduit du XML malformé, omis un nouvel actif de [Content_Types].xml, ou laissé une référence en suspens dans un fichier .rels associé.
**Q: Quelle unité de mesure PowerPoint utilise-t-il pour les positions et les marges des formes ?
A3: PowerPoint utilise les English Metric Units (EMUs), où 1 pouce équivaut à 914 400 EMUs et 1 point à 12 700 EMUs.
**Q: Comment puis-je extraire de manière programmatique toutes les images d’une présentation sans bibliothèques externes ?
A4: Il suffit d’ouvrir le fichier .pptx avec n’importe quel utilitaire zip standard et d’extraire tous les fichiers binaires situés dans le répertoire ppt/media/.
**Q: Est-il sûr d’analyser les fichiers PPTX téléchargés par les utilisateurs avec des analyseurs XML standard ?
A5: Non, vous devez renforcer votre analyseur ou utiliser des enveloppes sécurisées comme defusedxml pour bloquer les attaques XML External Entity (XXE) et les bombes zip.