PatchPE

He vuelto al desarrollo de nuevas utilidades, en este caso con PatchPE, que me iba a resultar muy útil en FileOptimizer, como ya ocurriera con zRecompress.

Si ZEROFILL, ya era muy sencillo, PatchPE, lo es aún más, con sus menos de 90 lineas de código fuente en C. Ciertamente, esta versión inicial 1.00, no ha recibido ninguna optimización, pero modestia a parte, me quedó bastante sencillo y limpio desde el principio. Lo tuve listo en menos de una hora, lo cual es todo un logro. O sea que tardé más en crear la web, y publicarlo, que en hacer.

El propósito de PatchPE, es parchear la cabecera de los archivos PE, para hacerlos compatibles con versiones anteriores de Windows. Como sabéis, un ejecutable de Windows, consiste en una cabecera DOS (MZ), seguida de una cabecera PE, luego una COFF, y luego una cabecera extendida PE, que en Microsoft llaman opcional, pero que realmente es obligatoria.

La cabecera extendida PE, guarda información que ha generado el enlazador (linker), y que instruye al sistema operativo sobre ciertos aspectos y requerimientos del mismo. Entre ellos, está la versión mínima de Windows necesaria para ejecutarlo. La inconsistencia ocurre, porque las versiones más recientes de los enlazadores como LINK 14 en Visual C++ 2015, o LINK 15 en Visual C++ 2017, fijan esa versión mínima a Windows 7.

Por tanto, todos los programas que lo utilicen, sólo podrán abrirse en Windows 7, 2008, 8, 8.1, 2012, 10 o 2016. Todo ello, independientemente de el código real del programa, use funciones de Windows 7 o no. La solución era sencilla, modificar la cabecera, para reducir el valor estampado como versión mínima de Windows requerida.

Tomamos los campos MajorOperatingSystemVersion, MinorOperatingSystemVersion, MajorSubsystemVersion y MinorSubsystemVersion, y los fijamos a versión mínima Windows NT 4. Si tenemos suerte, y ese programa, no usa características especiales disponibles en versiones más modernas del sistema operativo, podremos ejecutarlo sin problemas. Incluso si hace uso de esas funciones recientes, pero lo hace bien, como FileOptimizer, esto es, detecta el sistema operativo actual, y carga dinámicamente sus funciones en caso de estar disponibles, lo podremos usar.

En mi caso, esto ocurre con los binarios de Google Guetzli y de MuPDF Mutool, que vienen marcados como Windows 7 o superior, pero que una vez parcheados, se ejecutan sobre Windows XP correctamente.

Tienes el código fuente, y los binarios para Win32 y Win64, disponibles en Sourceforge.



6 comentarios en “PatchPE”

  1. Interesante.

    ¿Y qué haces cuando ese ejecutable pide una llamada a algún Win32 que no está en, digamos, XP?

    Los compiladores modernos de MS tienen la opción de compilar para XP, con unas LIB especiales que «parchean» las llamadas inexistentes en XP…

  2. En ese caso rfog, no se hace nada, y la ejecución fallará debido a no encontrarse el punto de entrada de esa función.

    Lo que es sorprendente, es la cantidad de ejecutables que tienen a nivel de enlazado que requieren Windows Vista o superior, y en realidad funcionan sobre XP una vez parcheados. Incluso me he topado alguno marcado como XP, y que funcionaba en NT 4.

    Digamos que el linker, que es quien fija la información de la cabecera del ejecutable, no conoce que funciones del sistema operativo estás utilizando, así que lo marca para la última versión que considera soportada. Hoy día, de momento Vista.

  3. Esta genial, que gran trabajo, un gran aporte para los desarrolladores y muy útil, porque permite saltarse las restricciones impuestas en muchas ocasiones -o en casi todas- sin motivo desde los mandamases de Microsoft.

    La parte mala… La parte mala es que no haces una GUI ni aunque te maten, Guti 😀 Parece mentira para alguien que precisamente tiene el FileOtimizer como una de sus herramientas famosas, y lo es precisamente por aportar interfaz de usuario a herramientas y plugins que no lo traen consigo.

  4. Muchas gracias BiaNamaran. No sólo es Microsoft. Te sorprendería que también lo he visto con el enlazador de IBM, y el de Embarcadero.

    Era una idea que me rondaba por la cabeza desde hace tiempo. A pesar de lo fácil que es de implementar, no había sacado el tiempo, las ganas, o la motivación necesaria. Sin embargo, en FileOptimizer me iba a ser muy útil, y no había nada parecido en el mercado, así que aprovechando el lanzamiento de Visual Studio 2017, me puse manos a la obra, y lo terminé.

    Es un desarrollo pequeño, menos de 100 lineas de código, pero modestia a parte, es bastante brillante. Más de la mitad del código es gestión de posibles errores. Por eso no tiene GUI, fue la excusa para probar Visual C++ 2017, sin invertir demasiado tiempo.

Deja un comentario