Última actualización: 16 sept, 2026

PPTX Reverse Engineering: Understanding PowerPoint Files Internally

Ingeniería inversa PPTX archivos: Guía para desarrolladores

Los decks de presentaciones modernos impulsan todo, desde presentaciones a inversores hasta métricas internas trimestrales. Pero si alguna vez has tenido que extraer texto programáticamente, reemplazar plantillas en tiempo de ejecución, crear generadores automáticos de diapositivas o sanitizar presentaciones confidenciales, probablemente te hayas dado cuenta rápidamente de que las bibliotecas de presentación de alto nivel pueden sentirse como una caja negra impredecible.

Cuando bibliotecas como python-pptx, Apache POI o OpenXML SDK alcanzan sus límites — o introducen errores de diseño no documentados — la única salida es atravesarlos. Necesitas entender qué es realmente una presentación de PowerPoint a nivel de bytes y de esquema.

En esta inmersión profunda, levantaremos el velo del formato .pptx, desentrañaremos su estructura interna, rastrearemos su grafo de relaciones, disecaremos sus jerarquías de dibujo y examinaremos estrategias prácticas para la ingeniería inversa, inspección y manipulación de presentaciones con código sin procesar.

1. ¿Qué es realmente un archivo .pptx?

En su esencia, un archivo .pptx no es un binario propietario monolítico como el antiguo formato .ppt de los años 90. Desde que Microsoft introdujo Office Open XML (ECMA-376 y ISO/IEC 29500), los documentos modernos de Office son archivos de Open Packaging Conventions (OPC).

En palabras simples: un archivo .pptx es simplemente un archivo zip que contiene documentos XML y recursos multimedia organizados en un árbol de directorios determinista.

Puedes demostrarlo en segundos usando herramientas estándar de terminal:

# Rename the extension and unpack it
cp presentation.pptx presentation.zip
unzip presentation.zip -d presentation_unpacked/
cd presentation_unpacked/
tree -L 2

El árbol de directorios resultante se ve notablemente consistente:

.
├── [Content_Types].xml
├── _rels/
│   └── .rels
├── docProps/
│   ├── app.xml
│   └── core.xml
└── ppt/
    ├── presentation.xml
    ├── _rels/
    ├── slides/
    ├── slideLayouts/
    ├── slideMasters/
    ├── theme/
    └── media/

Cada activo visual, transición, herencia de la diapositiva maestra, coordenada de cuadro de texto y gráfico vectorial está codificado en esta jerarquía de archivos.

2. Anatomía del paquete: subsistemas clave

Para ingenierizar inversamente presentaciones de manera eficaz, debes comprender las responsabilidades de cada componente de nivel superior.

[Content_Types].xml

Este es el manifiesto de entrada para el lector OPC. Mapea extensiones de archivo y nombres internos explícitos de partes a tipos MIME/contenido estandarizados. Si creas una nueva diapositiva o añades una imagen y no la declaras en [Content_Types].xml, PowerPoint declarará la presentación como corrupta y solicitará recuperación.

Fragmento de ejemplo:

<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>

El gráfico de relaciones _rels/

Uno de los conceptos más cruciales en OpenXML es indirección a través de relaciones. Las partes rara vez apuntan directamente a rutas de archivo crudas. En su lugar, un archivo (p. ej., slide1.xml) tiene un archivo de relación asociado ubicado en una carpeta hermana _rels (p. ej., _rels/slide1.xml.rels).

Las relaciones definen:

  • Hipervínculos (r:id="rId2", TargetMode=“External”)
  • Imágenes y pistas de audio almacenadas en ppt/media/
  • Punteros de herencia de diseño (slideLayout1.xml)
  • Diapositivas de notas, comentarios y fuentes incrustadas

docProps/ (Metadatos)

  • core.xml: Metadatos Dublin Core—autor, título, fecha de creación, marca de tiempo de modificación.
  • app.xml: Estadísticas específicas de la aplicación—versión de PowerPoint, recuento total de diapositivas, recuentos de diapositivas ocultas, recuento de palabras, nombres de plantillas de presentación.

ppt/ (El motor de presentación)

Aquí es donde se encuentra la presentación real:

  • presentation.xml: La columna vertebral maestra. Registra los IDs de diapositivas, las dimensiones del tamaño de la diapositiva, referencias al maestro de notas y la configuración de fuente predeterminada.
  • slides/: Las diapositivas individuales (slide1.xml, slide2.xml, etc.).
  • slideLayouts/: Preajustes estructurales maestros (Diapositiva de título, Dos columnas, Encabezado de sección).
  • slideMasters/: Estilos globales, paletas predeterminadas, rellenos de fondo y herencia de marcadores de posición.
  • theme/: Paletas de colores (acentos del 1 al 6, variaciones oscuras/claras) y esquemas de fuentes (fuentes principales/secundarias).
  • media/: Imágenes sin procesar (PNG, JPEG, SVG), audio y archivos de video.

3. Desglosando una diapositiva: los dialectos PresentationML (p:) y DrawingML (a:)

Cuando abres ppt/slides/slide1.xml, encuentras dos espacios de nombres XML principales:

  1. PresentationML (p:): Regula los elementos estructurales de presentación (diapositivas, árboles de formas, grupos de lienzo).
  2. DrawingML (a:): Regula la tipografía, la geometría, coordenadas 2D, rellenos degradados y renderizado vectorial.

Aquí hay un ejemplo simplificado de cómo se ve una forma de texto estándar:

<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>

Unidades de medida cruciales: EMUs y centésimas de punto

Observe los números de coordenadas en <a:xfrm>:

  • x="1524000"
  • cx="9144000"

Estas son Unidades Métricas Inglesas (EMUs).

  • $1 \text{ pulgada} = 914,400 \text{ EMUs}$
  • $1 \text{ cm} = 360,000 \text{ EMUs}$
  • $1 \text{ pt} = 12,700 \text{ EMUs}$

Los EMU permiten que los enteros representen fracciones exactas tanto de pulgadas como de milímetros sin errores de redondeo de punto flotante en diferentes arquitecturas de hardware.

Observe también el tamaño de fuente:

  • sz="3200" significa 32,00 pt. Los tamaños de fuente en DrawingML se miden en centésimas de punto.

4. La cadena de herencia: por qué las formas heredan estilos invisibles

Uno de los errores más comunes al invertir la ingeniería de archivos PPTX es asumir que el estilo visual de una forma está completamente declarado dentro de su propio slideX.xml.

En realidad, OpenXML se basa en un estricto modelo de herencia en cascada de 4 niveles:

[Theme: ppt/theme/theme1.xml]
[Slide Master: ppt/slideMasters/slideMaster1.xml]
[Slide Layout: ppt/slideLayouts/slideLayout1.xml]
[Slide: ppt/slides/slide1.xml]

Si un cuadro de texto en slide1.xml contiene:

<a:p>
  <a:r>
    <a:t>Revenue Projections</a:t>
  </a:r>
</a:p>

No hay familia de fuentes, ni color explícito, ni tamaño declarado en la ejecución (<a:r>). Para averiguar cómo PowerPoint representa este texto, su analizador debe:

  1. Identifique el tipo de marcador de posición (<p:ph type="title"/>).
  2. Lea el diseño referenciado en slide1.xml.rels.
  3. Verifique si slideLayout1.xml proporciona anulaciones de estilo para ese marcador de posición.
  4. Recurra a slideMaster1.xml para los estilos predeterminados del cuerpo de texto del título.
  5. Rastrear los tokens de color como accent1 o tx1 en theme1.xml para encontrar el código de color hexadecimal.

Si omite este gráfico de herencia, su analizador leerá incorrectamente los estilos, fuentes faltantes, tamaños de fuente y anclajes de diseño.

5. Flujo de trabajo práctico de ingeniería inversa

Cuando necesite investigar cómo funciona bajo el capó una característica particular de PowerPoint (p. ej., transiciones morph, tablas complejas, rutas vectoriales), siga este enfoque empírico:

Paso 1: Crear un “Par de diferencias” mínimo

  1. Abre PowerPoint y crea una diapositiva en blanco.
  2. Guárdalo como before.pptx.
  3. Aplica el cambio único exacto que deseas revertir (p. ej., agregar una sombra paralela a un círculo, cambiar el estilo de viñeta, insertar un video incrustado).
  4. Guárdalo como after.pptx.

Paso 2: Descomprimir ambos archivos

unzip before.pptx -d before/
unzip after.pptx -d after/

Paso 3: Formatear el XML

El XML sin procesar dentro de los archivos de Office suele estar sin sangrías ni caracteres de nueva línea. Antes de comparar, formatea los archivos:

find before/ after/ -name "*.xml" -exec xmllint --format {} --output {} \;

Paso 4: Ejecutar un diff unificado

diff -uNr before/ after/ > changes.patch

Revisar changes.patch revela el nombre exacto de la etiqueta, el atributo de espacio de nombres y la jerarquía del contenedor que introdujo PowerPoint. Esta es la forma más rápida de descubrir propiedades de esquema no documentadas u oscuras sin tener que buscar entre miles de páginas de la documentación ECMA-376.

6. Construcción de un micro‑motor personalizado: descomprimir, modificar, volver a empaquetar

A veces no deseas una dependencia empresarial pesada como Apache POI o el Microsoft OpenXML SDK, especialmente en entornos serverless ligeros (AWS Lambda, Cloudflare Workers, nodos de borde).

Aquí tienes un patrón de Python autocontenido que muestra cómo descomprimir de forma segura un PPTX en memoria, inyectar datos personalizados usando herramientas de la biblioteca estándar y volver a empaquetarlo:

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()

Aspectos clave a tener en cuenta al modificar archivos a nivel de byte bruto:

  1. Preservación de espacios de nombres: Los analizadores XML a menudo reescriben los prefijos (xmlns:p puede convertirse en xmlns:ns0). Aunque es XML válido, la validación estricta del esquema interno de PowerPoint a veces rechaza alias de prefijo no estándar. Registre los espacios de nombres explícitamente.
  2. Métodos de compresión ZIP: Asegúrese de escribir los archivos de nuevo usando la compresión deflate estándar (zipfile.ZIP_DEFLATED).
  3. Vaciado de flujo: Siempre verifique que su búfer zip se cierre y vacíe completamente antes de enviar los bytes aguas abajo.
  4. Preservar relaciones: Si elimina una diapositiva, también debe eliminar su entrada de ppt/presentation.xml, borrar su relación en ppt/_rels/presentation.xml.rels y limpiar su tipo de contenido de [Content_Types].xml.

7. Consideraciones de rendimiento y seguridad

Ingeniería inversa de archivos PPTX no se trata solo de editar diapositivas; también implica auditar lo que ingresa a sus sistemas.

Seguridad: Billion Laughs y XXE

Debido a que los archivos PPTX analizan XML, cualquier canal de procesamiento del lado del servidor que ingiera presentaciones enviadas por el usuario es vulnerable a:

  • Inyección de entidad externa XML (XXE): XML malicioso que intenta acceder a /etc/passwd o consultar puntos finales de metadatos internos de la nube (http://169.254.169.254/).
  • Ataques de expansión de entidades (Billion Laughs): Bucles de entidades exponenciales que agotan la RAM del sistema.

Mitigación: Siempre desactive resolve_entities, load_dtd y la resolución de redes externas en su analizador XML (p. ej., usando defusedxml en Python).

Seguridad: Cargas de Macros y Flujos Ocultos

Inspeccione los archivos en busca de contenido .pptm que se haga pasar por extensiones .pptx. Busque ppt/vbaProject.bin, que contiene código Visual Basic compilado. En los archivos .pptx estándar, el código VBA está prohibido; encontrar referencias a cargas útiles binarias en las relaciones debería activar inmediatamente las banderas de cuarentena.

Conclusión

La ingeniería inversa de archivos .pptx desmitifica el software de presentaciones. Una vez que reconozca que los archivos de PowerPoint son simplemente paquetes zip estructurados llenos de coordenadas, referencias de esquemas y árboles de relaciones XML, ya no estará limitado por las abstracciones de terceros existentes.

Ya sea que esté optimizando el rendimiento de generación de diapositivas, escribiendo sanitizadores automáticos personalizados o solucionando fallos de renderizado, observar directamente la arquitectura subyacente de OpenXML le brinda un control total sobre la canalización de presentación.

Preguntas frecuentes (FAQ)

**Q: ¿Puede convertir un .pptx a una carpeta estándar y editar los archivos directamente en un IDE?

A1: Sí, puede extraer el archivo, editar el XML en un editor como VS Code y volver a comprimir el contenido del directorio para abrirlo nuevamente en PowerPoint.

**Q: ¿Por qué PowerPoint dice que mi archivo PPTX modificado manualmente necesita reparación?

A2: Esto suele ocurrir si introdujiste XML mal formado, omitiste un nuevo recurso de [Content_Types].xml, o dejaste una referencia colgante en un archivo .rels asociado.

**Q: ¿Qué unidad de medida usa PowerPoint para las posiciones y márgenes de las formas?

A3: PowerPoint usa Unidades Métricas Inglesas (EMUs), donde 1 pulgada equivale a 914,400 EMUs y 1 punto equivale a 12,700 EMUs.

**Q: ¿Cómo puedo extraer programáticamente todas las imágenes de una presentación sin bibliotecas externas?

A4: Simplemente abre el archivo .pptx con cualquier utilidad zip estándar y extrae todos los archivos binarios ubicados dentro del directorio ppt/media/.

**Q: ¿Es seguro analizar archivos PPTX subidos por usuarios con analizadores XML estándar?

A5: No, debes reforzar tu analizador o usar envoltorios seguros como defusedxml para bloquear ataques de Entidad Externa XML (XXE) y bombas zip.

Ver también