Windows Metafile ( WMF ) es un formato de archivo de imagen diseñado originalmente para Microsoft Windows en la década de 1990. El formato original de Windows Metafile no era independiente del dispositivo (aunque podía serlo más con encabezados de ubicación) y podía contener tanto gráficos vectoriales como componentes de mapa de bits . Actúa de manera similar a los archivos SVG . Los archivos WMF fueron reemplazados posteriormente por los archivos Enhanced Metafiles (EMF), que sí ofrecían independencia del dispositivo. Los archivos EMF se mejoraron a su vez mediante archivos EMF+ .
Básicamente, un metarchivo almacena una lista de registros que consiste en comandos de dibujo, definiciones de propiedades y objetos gráficos para mostrar una imagen en la pantalla. [1] Los comandos de dibujo utilizados están estrechamente relacionados con los comandos de la API de Interfaz de dispositivo gráfico (GDI) utilizada para dibujar en Microsoft Windows.
Existen tres tipos principales de metarchivos: un WMF es un formato de 16 bits introducido en Windows 3.0 . Es el formato vectorial nativo de las aplicaciones de Microsoft Office, como Word , PowerPoint y Publisher . A partir de 2023 [actualizar], está disponible la revisión 17 de la especificación del formato de metarchivo de Windows. [2] Los archivos EMF, que reemplazaron a los archivos WMF, funcionan según el mismo principio, solo que es un formato de archivo de 32 bits que también permite la incrustación de datos privados dentro de registros de "comentarios". [3] EMF+ es una extensión de los archivos EMF y se incrusta en estos registros de comentarios, lo que permite imágenes y texto utilizando comandos, objetos y propiedades similares a Windows GDI+ . [4]
El formato de archivo WMF original de 16 bits se especificó en su totalidad en el volumen 4 de la documentación del SDK de Windows 3.1 de 1992 [5] (al menos si se combinaba con las descripciones de las funciones y estructuras individuales en los otros volúmenes), pero esa especificación era vaga en cuanto a algunos detalles. Estos manuales se publicaron como libros impresos disponibles en las librerías sin necesidad de firmar un acuerdo de licencia de usuario final (EULA) ni otras restricciones de licencia inusuales (solo una advertencia general de que, si se compraba como parte de un paquete de software, el software estaría sujeto a una).
Con el tiempo, la existencia de esa especificación histórica se olvidó en gran medida y algunas implementaciones alternativas recurrieron a la ingeniería inversa para averiguar el formato de archivo a partir de los archivos WMF existentes, lo que era difícil y propenso a errores. [6] En septiembre de 2006, Microsoft volvió a publicar la especificación del formato de archivo WMF en una forma más completa [7] en el contexto de la Promesa de Especificación Abierta de Microsoft , prometiendo no hacer valer los derechos de patente a los implementadores de formatos de archivo. [8]
Más tarde, Microsoft desaprobó los archivos WMF en favor de los archivos EMF de 32 bits , ya que los archivos WMF tenían problemas reales con la independencia del dispositivo, a pesar del uso de un encabezado de archivo "ubicable" que proporcionaba una independencia básica del dispositivo. Microsoft descubrió que los desarrolladores que usaban el formato estaban "[incrustando] comentarios de aplicación, ubicación o escala en los metarchivos... Otros añadían encabezados al metarchivo que proporcionaban información específica de la aplicación", lo que causaba importantes problemas de compatibilidad. [9] Por lo tanto, en 1992 con Windows NT 3.1 , Microsoft introdujo el formato de metarchivo mejorado (EMF) [10] , un formato que se basaba en la API de Win32 y con el que incorporaron la independencia del dispositivo. [11] [9] — estos también se conocían como metarchivos NT. [12] Con el lanzamiento de Windows XP y GDI+, el conjunto de registros tuvo que aumentar significativamente, por lo que Microsoft lanzó EMF+ como una extensión del formato de archivo EMF existente. [10] [13]
Los archivos WMF, EMF y EMF+ constan de una serie de registros que se reproducen para generar una salida gráfica. Algunos registros definen objetos que pueden especificar objetos gráficos utilizados para determinar cómo se deben dibujar los gráficos (por ejemplo, los lápices especifican el color y el ancho de las líneas). Cada uno de estos objetos se almacena en metarchivos y se colocan en una tabla de objetos, que realiza un seguimiento del uso de los objetos gráficos mientras se procesa el metarchivo. La tabla de objetos es una matriz asociativa de índices a estructuras de objetos gráficos definidas dentro del metarchivo.
Los archivos WMF y EMF manejan el procesamiento de objetos de manera diferente a los registros EMF+ en los archivos EMF. A medida que se procesa un archivo WMF y EMF, los registros se leen en una tabla de objetos una vez que se define un objeto. Si se elimina un objeto, se libera el objeto de la tabla y se puede reutilizar el identificador. Cabe destacar que un objeto no se utilizará hasta que se seleccione específicamente durante la reproducción de la grabación. [14] [15] Esto difiere para los archivos EMF+, que también utilizan una matriz asociativa a través de un mapa hash que registra el objeto junto con un identificador de objeto. Sin embargo, a diferencia de los archivos WMF y EMF que pueden eliminar un objeto, cuando se crea un nuevo objeto que tiene el mismo índice que un objeto existente, la entrada en la tabla se reemplaza con el nuevo objeto. Un archivo EMF tampoco necesita seleccionar específicamente un objeto antes de usarlo. [16]
Extensión de nombre de archivo | .wmf |
---|---|
Tipo de medio de Internet | imagen/wmf [10] |
Identificador de tipo uniforme (UTI) | com.microsoft.wmf [10] |
Tipo de formato | Gráficos vectoriales |
Extendido a | Campo electromagnético |
Los archivos WMF no fueron diseñados originalmente para ser independientes del dispositivo, lo que significa que un archivo no podía reproducirse en dispositivos de salida que difirieran del dispositivo original en el que se grabó el archivo. Aldus Corporation inventó una solución parcial a este problema , al agregar un encabezado "ubicable" adicional, llamado "encabezado APM", [18] que agregó un rectángulo delimitador, una versión del metarchivo, el tamaño del metarchivo, la cantidad de objetos en el metarchivo y el tamaño del registro individual más grande en el metarchivo. [19] [20] Esto fue incorporado más tarde al formato WMF por Microsoft , a partir de Windows 2000. [ 21]
Los archivos WMF están estructurados por una serie de registros, comenzando con una serie de registros de control: el registro de encabezado, [19] [22] el registro de ubicación opcional antes mencionado, [23] y finalizando con un registro de fin de archivo . [19] [24]
Los registros de control encapsulan los registros que forman la imagen en sí. Estos registros funcionan dentro de lo que se conoce como el contexto del dispositivo de reproducción , que es la colección de propiedades y objetos que forman el entorno gráfico de un dispositivo mientras el metarchivo se "reproduce" en este dispositivo de salida. [25]
Los registros que no sean registros de control se pueden agrupar en gran medida en registros de mapa de bits, registros de dibujo, registros de objetos, registros de estado y registros de escape.
Los registros de mapa de bits administran y generan imágenes de mapa de bits .
Nombre | Descripción |
---|---|
META_BITBLT | Especifica cómo realizar una transferencia de bloques de bits . Estos registros pueden especificar un mapa de bits para utilizar como origen o una región. [26] |
META_DIBBITBLT | Especifica cómo realizar una transferencia de bloques de bits de una imagen de mapa de bits independiente del dispositivo . Estos registros pueden especificar un mapa de bits para utilizar como origen o una región. [27] |
META_DIBSTRETCHBITBLT | Especifica cómo realizar una transferencia de bloques de bits de una imagen de mapa de bits independiente del dispositivo, pero permite la expansión o contracción de la imagen. Estos registros pueden especificar un mapa de bits para utilizar como origen o una región. [28] |
META_SETDIBTODEV | Especifica el color para establecer un bloque de píxeles en una imagen de mapa de bits independiente del dispositivo. Estos registros pueden especificar un mapa de bits para utilizar como origen o una región. [29] |
META_STRETCHBLT | Especifica cómo realizar una transferencia de bloques de bits, pero permite la expansión o contracción de la imagen. [30] |
META_STRETCHDIB | Especifica cómo realizar una transferencia de bloques de bits de una imagen de mapa de bits independiente del dispositivo, pero permite la expansión o contracción de la imagen. Estos registros pueden especificar un mapa de bits para utilizar como origen o una región. [31] |
Los registros de dibujo producen salida gráfica.
Nombre | Descripción |
---|---|
Arco meta | Dibuja un arco elíptico . [32] |
META_ACORDE | Dibuja un acorde . [33] |
META_ELIPSE | Dibuja un arco elíptico . [34] |
META_EXTFLOODFILL | Rellena un área con un pincel. [35] |
META_EXTEXTEXTOUT (Texto de salida meta_extensión) | Dibujar texto con fuente, color de fondo y color de texto del contexto del dispositivo de reproducción. [36] |
META_REGIÓN DE RELLENO | Rellena una región con un pincel especificado. [37] |
META_RELLENO DE INUNDACIÓN | Rellena un área con un pincel. [38] |
REGIÓN DEL MARCO META | Dibuja un borde alrededor de una región de la página con un pincel. [39] |
META_INVERTREGION | Pinta una región del gráfico con colores invertidos. [40] |
META_LINEA | Dibuja una línea semiabierta desde la posición de dibujo definida en el contexto del dispositivo de reproducción hasta un punto especificado. [41] |
REGIÓN DE PINTURA META_ | Pinte una región con el pincel actual especificado en el contexto del dispositivo de reproducción. [42] |
META_PATBLT | Pinte una región con el pincel actual especificado en el contexto del dispositivo de reproducción y luego combine el color del pincel y los colores de la superficie mediante una operación rasterizada . [43] |
META_PIE | Dibuje una cuña con forma de pastel delimitada por la intersección de una elipse y dos radiales: la línea se establece mediante el lápiz establecido a través del contexto del dispositivo de reproducción, y el área delimitada por la forma de pastel se rellena con el pincel actual del contexto del dispositivo de reproducción. [44] |
META_POLILINEA | Dibuja una serie de segmentos de línea conectando los puntos en una matriz especificada. [45] |
META_POLÍGONO | Pinta un polígono que consta de dos o más vértices conectados por líneas rectas. El polígono se delinea con el lápiz y se rellena con el pincel y el modo de relleno de polígono que se definen en el contexto del dispositivo de reproducción. [46] |
META_POLIPOLÍGONO | Pinta una serie de polígonos cerrados que pueden superponerse. Cada polígono se delinea con el lápiz y se rellena con el pincel y el modo de relleno de polígono que se definen en el contexto del dispositivo de reproducción. [47] |
META_RECTANGLE | Pinta un rectángulo, que se delinea utilizando el lápiz y se rellena utilizando el pincel que está definido en el contexto del dispositivo de reproducción. [48] |
META_REDONDEAR | Pinta un rectángulo con esquinas redondeadas. El rectángulo se delinea con el lápiz y se rellena con el pincel definido en el contexto del dispositivo de reproducción. [49] |
META_SETPIXEL | Establece el píxel en las coordenadas especificadas con el color especificado. [50] |
META_TEXTO_EXPOSICIÓN | Genera una cadena de caracteres en la ubicación especificada utilizando la fuente, el color de fondo y el color del texto definidos en el contexto del dispositivo de reproducción. [51] |
Los registros de objetos crean y administran objetos gráficos. En los archivos WMF hay dos grandes categorías de objetos: objetos gráficos y objetos de estructura. Los objetos de estructura no se crean ni se eliminan explícitamente en un WMF, sino que son estructuras complejas. Por ejemplo, BitmapCoreHeader contiene información sobre las dimensiones y el formato de color de un mapa de bits independiente del dispositivo, [52] que es en sí mismo parte de un objeto DeviceIndependentBitmap. [53] Sin embargo, un objeto gráfico especifica parámetros para la salida de gráficos y, durante la reproducción del WMF, configura el contexto del dispositivo de reproducción. [54]
Los objetos gráficos pueden ser pinceles (definen el estilo, el color y el patrón de un pincel que define cómo pintar un área del gráfico), fuentes (definen propiedades que afectan cómo se muestra el texto), paletas (especifican colores como valores independientes del dispositivo, definidos por una aplicación), lápices (especifican los atributos gráficos de una línea) y regiones (que especifican segmentos de línea y curva que definen una forma). [54]
Nombre | Descripción |
---|---|
META_CREATEBRUSHINDIRECTO | Crea un objeto pincel a partir de un objeto LogBrush (pincel lógico). [55] |
META_CREATEFONTINDIRECT | Crea un objeto de pincel a partir de un objeto de fuente. [56] |
META_CREARPALETA | Crea un objeto de paleta. |
META_CREARCEPTÓN [57] | Crea un objeto pincel a partir de un objeto LogBrush (pincel lógico). [58] |
META_CREARPENINDIRECTO | Crea un objeto de pluma. [59] |
REGIÓN META_CREATER | Crea un objeto de región. [60] |
META_ELIMINAR OBJETO | Eliminar un objeto. [61] |
META_CREATEBRUSHINDIRECTO | Crea un objeto pincel a partir de un objeto LogBrush (pincel lógico). [62] |
META_DIBCREATEPATTERNBRUSH | Crea un objeto de pincel a partir de un mapa de bits independiente del dispositivo. [63] |
META_SELECTCLIPREGIÓN | Especifica el objeto de región que será la región de recorte actual . [64] |
META_SELECTOBJETO | Selecciona el objeto que será el objeto actual para el contexto del dispositivo de reproducción, lo que funciona en todos los objetos gráficos excepto los objetos de paleta, que deben configurarse con META_SELECTPALETTE. [65] |
PALETA META_SELECT | Selecciona la paleta lógica para el contexto del dispositivo de reproducción. [66] |
Los registros de estado administran las propiedades gráficas del contexto del dispositivo de reproducción. [67]
Nombre | Descripción |
---|---|
PALETA META_ANIMADA | Redefine las entradas en la paleta lógica que se define en el contexto del dispositivo de reproducción con un objeto de paleta especificado. [68] |
META_EXCLUDECLIPRECT | Establece la región de recorte que se define en el contexto del dispositivo de reproducción en la región de recorte existente menos un rectángulo especificado. [69] |
META_INTERSECTCLIPRECT | Establece la región de recorte que se define en el contexto del dispositivo de reproducción en la intersección de la región de recorte existente y un rectángulo especificado. [70] |
META_MOVETO | Establece la posición de salida en el contexto del dispositivo de reproducción en un punto especificado. [71] |
META_OFFSETCLIPRGN | Mueve la región de recorte que está definida en el contexto del dispositivo de reproducción mediante desplazamientos especificados. [72] |
META_OFFSETVIEWPORTORG | Mueve el origen de la ventana gráfica en el contexto del dispositivo de reproducción mediante desplazamientos horizontales y verticales especificados. [73] |
META_OFFSETWINDOWORG | Mueve el origen de la ventana de salida en el contexto del dispositivo de reproducción mediante desplazamientos horizontales y verticales especificados. [74] |
META_REALIZARPALETA | Asigna entradas de la paleta lógica definida en el contexto del dispositivo de reproducción a la paleta del sistema. [75] |
META_CAMBIAR TAMAÑO DE PALETA | Redefine el tamaño de la paleta lógica que se define en el contexto del dispositivo de reproducción. [76] |
META_RESTOREDC | Restaura el contexto del dispositivo de reproducción desde un contexto de dispositivo guardado previamente. [77] |
META_SAVEDC | Guarda el contexto del dispositivo de reproducción para su posterior recuperación. [78] |
META_SCALEVIEWPORTEXT | Escala las extensiones horizontales y verticales de la ventana gráfica que se define en el contexto del dispositivo de reproducción utilizando las proporciones formadas por los multiplicandos y divisores especificados. [79] |
META_ESCALAVENTANAEXTERIOR | Escala las extensiones horizontales y verticales de la ventana de salida que se define en el contexto del dispositivo de reproducción utilizando las proporciones formadas por multiplicandos y divisores especificados. [80] |
META_SETBKCOLOR | Establece el color de fondo en el contexto del dispositivo de reproducción a un color especificado. [81] |
META_SETBKMODE | Establece el modo de mezcla de fondo en el contexto del dispositivo de reproducción. [82] |
META_SETLAYOUT | Define la orientación del diseño en el contexto del dispositivo de reproducción. [83] |
META_SETMAPMODE | Define el modo de mapeo en el contexto del dispositivo de reproducción. [84] |
META_SETMAPPERFLAGS | Define el algoritmo que utiliza el asignador de fuentes cuando asigna fuentes lógicas a fuentes físicas. [85] |
META_SETPALENTRIES | Define valores de color RGB en un rango de entradas en la paleta lógica que se define en el contexto del dispositivo de reproducción. [86] |
META_SETPOLYFILLMODE | Define el modo de relleno de polígonos en el contexto del dispositivo de reproducción para operaciones gráficas que rellenan polígonos. [87] |
META_SETRELABS | Registro no utilizado. [88] |
META_SETROP2 | Define el modo de mezcla de operaciones de trama de primer plano en el contexto del dispositivo de reproducción. [89] |
META_SETSTRETCHBLTMODE | Define el modo de estiramiento de mapa de bits en el contexto del dispositivo de reproducción. [90] |
META_SETTEXTALIGN | Define valores de alineación de texto en el contexto del dispositivo de reproducción. [91] |
META_SETTEXTCHAREXTRA | Define el espaciado entre caracteres para la justificación del texto en el contexto del dispositivo de reproducción. [92] |
META_SETTEXTO COLOR | Define el color de primer plano del texto en el contexto del dispositivo de reproducción. [93] |
JUSTIFICACIÓN DEL TEXTO DEL SET META_SET | Define la cantidad de espacio que se debe agregar para dividir caracteres en una cadena de texto justificado. [94] |
META_SETVIEWPORTEXT | Define las extensiones horizontales y verticales de la ventana gráfica en el contexto del dispositivo de reproducción. [95] |
META_SETVIEWPORTORG | Define el origen de la ventana gráfica en el contexto del dispositivo de reproducción. [96] |
META_SETWINDOWEXT | Define las extensiones horizontales y verticales de la ventana de salida en el contexto del dispositivo de reproducción. [97] |
META_SETWINDOWORG | Define el origen de la ventana de salida en el contexto del dispositivo de reproducción. [98] |
Los registros de escape son un medio para ampliar la funcionalidad del metarchivo a través de registros que no están definidos de otro modo como un tipo de registro WMF. Cada registro de escape contiene una función de registro, una función de escape y, potencialmente, datos de escape.
Los siguientes registros de escape forman un archivo WMF.
Nombre | Descripción |
---|---|
ABORTODOC | Detiene el procesamiento del documento actual. [99] |
RUTA DE INICIO | Abre un camino. [100] |
COMPROBAR FORMATO JPEG | Determina si puede manejar la imagen JPEG dada . [101] |
COMPROBAR_FORMATO_PNG | Determina si puede manejar la imagen PNG dada . [102] |
CLIP_A_RUTA | Aplica una función a la ruta de recorte de PostScript actual . [103] |
CERRAR CANAL | Igual que ENDDOC. [104] |
DESCARGAR_CARA | Establece el nombre de la fuente en el dispositivo de salida. [105] |
DESCARGAR_ENCABEZADO | Descarga conjuntos de procedimientos PostScript. [106] |
DIBUJAR_PATRÓN | Dibuja un rectángulo con un patrón definido. [107] |
POSTSCRIPCIÓN ENCAPSULADA | Envía datos PostScript encapsulados (EPS) arbitrarios directamente al controlador de impresora. [108] |
FIN_RUTA | Termina un camino. [109] |
FIN DOC | Notifica al controlador de impresora que un nuevo trabajo de impresión está finalizando. [110] |
IMPRESIÓN EPS | Indica el inicio y el final de la impresión EPS. [111] |
EXTRACCIÓN DE TEXTO | Dibuja texto utilizando la fuente, el color de fondo y el color del texto actualmente seleccionados. [112] |
OBTENER TABLA DE COLORES | Obtiene los valores de la tabla de colores del controlador de impresora. [113] |
OBTENER_UNIDADES_DE_DISPOSITIVO | Obtiene las unidades del dispositivo configuradas actualmente en el dispositivo de salida. [114] |
OBTENER MÉTRICAS DE TEXTO EXTENDIDAS | Obtiene las métricas de texto extendidas que están configuradas actualmente en el controlador de impresora. [115] |
Obtener nombre_cara | Obtiene el nombre de la fuente actualmente configurada en el dispositivo de salida. [116] |
GET_PAIRKERNTABLE | Obtiene la tabla de interletraje de fuentes definida actualmente en el dispositivo de salida. [117] |
OBTENER TAMAÑO DE PÁGINA PHYSP | Recupera el tamaño de página física actualmente seleccionado en el dispositivo de salida. [118] |
OBTENER DESVENTAJA DE IMPRESIÓN | Recupera el desplazamiento desde la esquina superior izquierda de la página física donde comienza la impresión o el dibujo real. [119] |
OBTENER CONFIGURACIÓN DE FUNCIONES DE PS | Consulta al controlador de impresora para obtener información sobre las características PostScript compatibles con el dispositivo de salida. [120] |
OBTENER FACTOR DE ESCALA | Recupera los factores de escala para el eje x y el eje y de una impresora. [121] |
META_ESCAPE_METAFILE_MEJORADO | Se utiliza para incrustar un metarchivo EMF dentro de un metarchivo WMF. [122] |
CONTROLADOR DE METAFILE | Consulta al controlador de impresora sobre su compatibilidad con metarchivos en el dispositivo de salida. [123] |
NUEVO MARCO | Notifica al controlador de impresora que la aplicación ha terminado de escribir en una página. [124] |
BANDA SIGUIENTE | Notifica al controlador de impresora que la aplicación ha terminado de escribir en una banda. [125] |
PASO A TRAVÉS | Pasa datos arbitrarios al controlador de impresora. [126] |
DATOS DE LA POSTDATA | Envía datos PostScript arbitrarios al dispositivo de salida. [127] |
IDENTIFICACIÓN DE POSTDATA | Establece el controlador de impresora en modo centrado en PostScript o en GDI. [128] |
POSTDATA_IGNORAR | Notifica al dispositivo de salida que ignore los datos PostScript. [129] |
INYECCIÓN DE POSTDATA | Inserta un bloque de datos sin procesar en una secuencia PostScript. [130] |
PASO A TRAVÉS DE POSTSCRIPT | Envía datos arbitrarios directamente a un controlador de impresora, que se espera que procese estos datos solo cuando está en modo PostScript. [131] |
CANAL ABIERTO | Actúa de la misma manera que STARTDOC, con un documento y un nombre de archivo de salida NULL, y datos en modo sin procesar. [132] |
CONSULTA_DIBSUPPORT | Consulta al controlador de impresora sobre su compatibilidad con DIB en el dispositivo de salida. [133] |
CONSULTA_ESC SOPORTE | Consulta al controlador de impresora para determinar si una función de escape WMF específica es compatible con el dispositivo de salida. [134] |
CONJUNTO_TABLA_COLORABLE | Establece valores de la tabla de colores. [135] |
ESTABLECER_CONTADOR_DE_COPIAS | Establece el número de copias. [136] |
ESTABLECER_CAPITULO_DE_LÍNEA | Especifica el modo de final de línea que se utilizará al dibujar en el dispositivo de salida. [137] |
ESTABLECER UNIÓN DE LÍNEA | Especifica el modo de unión de líneas que se utilizará al dibujar en el dispositivo de salida. [138] |
ESTABLECER_LIMITE_DE_MITER | Establece el límite para la longitud de las uniones en inglete que se utilizarán al dibujar en el dispositivo de salida. [139] |
PASO A TRAVÉS DE SPCC2 | Permite que los documentos incluyan procedimientos privados y otros datos arbitrarios en los documentos. [140] |
DOCUMENTO DE INICIO | Notifica al controlador de impresora que se está iniciando un nuevo trabajo de impresión. [141] |
Se encontró una vulnerabilidad importante en los registros de escape alrededor del registro de escape Abort, que almacena el código del procedimiento de aborto dentro del propio registro. Esto afectó a los sistemas Windows (consulte CVE - 2005-4560) y al proyecto Wine (consulte CVE - 2006-0106). Según Secunia , "La vulnerabilidad se debe a un error en el manejo de los archivos Windows Metafile ('.wmf') que contienen registros 'Escape' SETABORTPROC especialmente diseñados. Dichos registros permiten que se ejecute una función arbitraria definida por el usuario cuando falla la representación de un archivo WMF". [142] Según la documentación del SDK de Windows 3.1, el escape SETABORTPROC quedó obsoleto y fue reemplazado por la función del mismo nombre en Windows 3.1, mucho antes de que se descubriera la vulnerabilidad de WMF. [143] Sin embargo, el código de escape obsoleto se mantuvo para la compatibilidad con programas de 16 bits escritos para (o al menos compatibles con versiones anteriores) Windows 3.0. Este cambio ocurrió aproximadamente al mismo tiempo que Microsoft estaba creando la reimplementación de 32 bits de GDI para Windows NT, y es probable que la vulnerabilidad haya ocurrido durante este esfuerzo.
Después de que Steve Gibson acusó a Microsoft de implementar deliberadamente una puerta trasera en su código, [144] [145] Mark Russinovich proporcionó una refutación y declaró que:
... las cosas eran diferentes cuando se diseñó el formato. En el modelo de memoria “grande” de Windows 3.1, el código es inherentemente independiente de la ubicación y Windows nunca fue parcheado, por lo que tanto Windows como una aplicación podían simplemente copiar una función de aplicación en el archivo WMF y asumir que funcionaría cuando la misma aplicación la reprodujera en una sesión de ejecución posterior. En cualquier caso, no está claro que los desarrolladores imaginaran que las aplicaciones crearan metarchivos en disco con procedimientos de cancelación. Además, como señaló Stephen Toulouse de Microsoft en la refutación de Microsoft a las afirmaciones de Steve, el panorama de seguridad a principios de los años 90 era muy diferente al de hoy y todo el código, incluido el almacenado en un archivo WMF, era inherentemente confiable. [146]
Peter Ferrie, de Symantec Security Response, EE.UU., también estuvo en desacuerdo con Gibson y señaló que:
Gibson afirmó que se crea un hilo para ejecutar el controlador SetAbortProc. De hecho, no se crea ningún hilo para ejecutar el controlador: es una devolución de llamada, que es llamada por el analizador, y el analizador tiene que esperar hasta que la devolución de llamada regrese, de lo contrario se pierde todo el objetivo de la función (abortar la impresión). Por su propia admisión, Gibson no leyó la documentación (de hecho, afirmó que no pudo encontrarla, aunque está disponible gratuitamente en el sitio web de Microsoft), y afirmó que el contexto del dispositivo no está disponible para el controlador de la función. Por supuesto, el contexto del dispositivo está disponible para el controlador de la función: es uno de los dos parámetros que se le pasan (ver arriba), y es necesario para abortar la impresión. Finalmente, Gibson afirmó que el flujo de control no podía regresar a Windows. Es simplemente una cuestión de que la función regrese y descarte los parámetros que se pasaron en la pila. Si el registro está bien formado, Windows continuará analizando el archivo, como antes. ... Gibson admite que estaba adivinando sobre varias cosas. Lamentablemente, su suposición fue errónea. Supongo que ahora sabemos más. [147]
Extensión de nombre de archivo | .fem |
---|---|
Tipo de medio de Internet | imagen/fem [10] |
Identificador de tipo uniforme (UTI) | com.microsoft.emf [10] |
Tipo de formato | Gráficos vectoriales |
Extendido desde | FMI |
Extendido a | Campo electromagnético+ |
Los archivos EMF tienen tres versiones posibles de encabezados. Los encabezados originales son solo un contenedor para imágenes, la segunda y tercera versión encapsulan el encabezado original y contienen un registro de formato de píxel y compatibilidad con registros OpenGL, y la tercera versión encapsula la segunda extensión de encabezado y aumenta la precisión y la escalabilidad de los EMF, ya que agrega la capacidad de medir distancias de superficies de dispositivos utilizando el sistema métrico. [148]
Cada encabezado EMF comienza con un registro EMR_HEADER y registra las propiedades relevantes del dispositivo en el que se grabó la imagen del metarchivo. El encabezado EMF original tiene un encabezado de 80 bytes y una cadena de descripción de longitud variable opcional. [149] Otros metarchivos contienen campos de extensión, que encapsulan el encabezado original. EmfMetafileHeaderExtension1
es un registro que se inserta directamente después del encabezado EMF original, especifica si hay un descriptor de formato de píxel y el desplazamiento hasta el objeto descriptor dentro del encabezado, así como un campo que especifica si existen registros OpenGL en el metarchivo. [150] El descriptor de formato de píxel especifica las capacidades de la superficie de dibujo y si un píxel está codificado en RGBA o es un índice en una tabla de colores. [151] EmfMetafileHeaderExtension2
es un registro que se inserta directamente después del EmfMetafileHeaderExtension1
registro y contiene dos campos con los valores X e Y para medir la superficie del dispositivo en micrómetros. [152]
Al igual que los archivos WMF, los registros se pueden clasificar por función; sin embargo, existen más tipos de registros en los archivos EMF que en los archivos WMF. Los registros se pueden clasificar como registros de control, de mapa de bits, de recorte, de comentario, de dibujo, de escape, de creación de objetos, de manipulación de objetos, OpenGL, de corchetes de ruta, de estado y de transformación.
Con el lanzamiento de Windows XP , se introdujo el formato Enhanced Metafile Format Plus Extensions (EMF+). EMF+ proporciona una forma de serializar llamadas a la API GDI+ de la misma manera que WMF/EMF almacena llamadas a GDI.
También existen versiones comprimidas de Metarchivos de Windows conocidas como Metarchivo Comprimido de Windows (WMZ) y Metarchivo Comprimido Mejorado de Windows (EMZ), [153] que son básicamente archivos WMF y EMF comprimidos con gzip respectivamente.
El formato WMF fue diseñado para ser ejecutado por la capa GDI de Windows con el fin de restaurar la imagen , pero como los archivos binarios WMF contienen la definición de las primitivas gráficas GDI que constituyen esta imagen, es posible diseñar bibliotecas alternativas que rendericen archivos binarios WMF o los conviertan en otros formatos gráficos.
Estos códigos de operación no están implementados porque no sé qué son y no se conoce documentación al respecto.
<55> Sección 2.3.2.3: Windows NT 3.1, Windows NT 3.5, Windows NT 3.51 y Windows 95: esta función no es compatible.