2012-06-20 17 views
10

Necesito encontrar el modo exe/dll fue construido mirando sus encabezados. [edit] Usando C++ solo sin herramientas externas. [/ edit]Cómo verificar si un archivo ejecutable o una DLL se compila en modo Liberar o Depurar (C++)

Hay una vieja discusión sobre cómo determinar dll fue creada en modo Release o Debug. http://forums.codeguru.com/archive/index.php/t-485996.html

Pero desafortunadamente no encontré ninguna respuesta clara.

+0

¿Qué le falta exactamente a esa discusión, o qué le gustaría haber aclarado? No hay una respuesta clara a esto, porque no hay forma de saber esto sin analizar de cerca el dll. – RedX

+0

¿Qué considera como modo de liberación o depuración? ¿Su exe/dll incluye un recurso de versión? – harper

+0

No hay garantía del 100% de que la versión esté incluida. – ChatCloud

Respuesta

6

Necesito encontrar el modo exe/dll fue construido mirando sus encabezados.

Si por "cabeceras" quiere decir secciones o recursos PE (cabeceras no le dirá nada, y los programas no son enviados generalmente con sus cabeceras de desarrollo!), Esto es tipo de posible, dentro de ciertos límites, y poco confiable. De lo contrario, este es un esfuerzo completamente imposible a menos que usted mismo haya escrito el programa.

En general, es difícil hacer algo así de manera confiable, más aún cuando "depuración compilación" es una simplificación de Microsoft Visual Studio que no existe como tal en la mayoría de los compiladores. Por ejemplo, con GCC es perfectamente permisible tener una compilación optimizada de que, sin embargo, contenga símbolos de depuración. Incluso es posible activar y desactivar las optimizaciones con #pragma (¡y cambiar el nivel de optimización e incluso la máquina de destino!) Y así tener funciones optimizadas (o grupos de funciones) en una compilación no optimizada, y viceversa.

La presencia de símbolos de depuración es su mejor estimación para un programa que no ha escrito. No es posible (no de manera realista, de una manera simple y automática, de todos modos) contar desde un binario generado si ha sido optimizado o no.

Las secciones .debug$S y .debug$T contienen símbolos de depuración y tipos de depuración, respectivamente. También hay otras secciones que comienzan con .debug, pero están en desuso. Un programa que se ha creado en "modo de depuración" y que luego no se ha eliminado contendrá algunas o todas estas secciones.
Usando C++ sin herramientas externas, querrá omitir el código auxiliar "MZ" de DOS y el encabezado PE. Después de esto vienen los encabezados de las secciones, que puedes analizar. Se puede descargar la documentación completa del formato de archivo here.
Probablemente, leer el archivo y hacer una coincidencia de cadena para .debug será igual de bueno.

De forma similar, puede ver VERSIONINFO o el archivo de manifiesto (también permiten especificar si un programa es una creación de depuración), pero estos no son obligatorios. Puedes escribir prácticamente todo lo que quieras en estos. Hasta ahora, son incluso menos confiables que buscar símbolos de depuración.

Otra sugerencia, poco confiable de nuevo, sería comprobar a qué versiones de las bibliotecas del sistema se vinculó un programa. Si se trata de la versión de depuración, es probable que haya sido una compilación de depuración. Sin embargo, uno podría hacer una compilación de lanzamiento y seguir enlazando con bibliotecas de depuración, nada puede evitar que lo haga.

La siguiente mejor suposición sería la ausencia de llamadas a la función CRT assert (que se puede hacer con una simple coincidencia de cadena), ya que la macro assert (de la que normalmente se llama) se elimina por completo en una compilación con NDEBUG definido. Sin uso de ese símbolo, sin cadena presente en el binario.
Desafortunadamente, un programa que no tiene se identificará falsamente como "release build" independientemente de su compilación real, y es completamente posible redefinir la macro assert para hacer algo completamente diferente (como printf a texto y continuar). Y, por último, no sabe si alguna biblioteca estática de terceros con la que se vincula (que obviamente ya pasó el preprocesador) contiene llamadas al assert que no conoce.

Si desea verificar un programa que haya escrito usted mismo, puede aprovechar el hecho de que el optimizador eliminará por completo las cosas que probablemente no se pueden alcanzar o que no se utilizan. Puede tomar 2-3 intentos para hacerlo bien, pero básicamente debe ser tan simple como definir una variable (o una función exportada si su compilador/vinculador no exporta símbolos que no se usan) y escribir dos o tres valores mágicos desde una ubicación de programa que no es alcanzable. Un compilador de optimización al menos colapsará esos varios movimientos redundantes en uno, o más probablemente los terminará completamente.
Luego puede hacer una búsqueda de cadenas binarias para los valores mágicos. Si no están presentes, es una compilación optimizada.

+0

la mayoría de mis aplicaciones compiladas de depuración (win32, vs2010) de mí no contienen la cadena '.debug'. Una alternativa sería verificar qué versión del tiempo de ejecución de C++ utiliza la aplicación. p.ej. buscando 'MSVCR80D.dll'' MSVCR90D.dll'' MSVCR100D.dll' ... – smerlin

+0

@smerlin: Sí, esa es otra cosa (aunque poco fiable) que uno podría buscar (como se indicó anteriormente, consulte el párrafo nº 6) . La cosa es que realmente no se puede decir con certeza. – Damon

0

Cuando crea un proyecto de C++ en Visual Studio genera dos configuraciones para usted. Los nombres de estas configuraciones son Depurar y Versión. La configuración de depuración incluye generación de información de depuración, menos optimización y soporte para Editar & Continuar.

Pero esto es solo un punto de partida. Puede crear configuraciones arbitrarias e incluso agregar toda la información de depuración a la configuración de Release. Por lo tanto, no hay una versión clara de depuración o liberación.

Puede intentar identificar si se ha definido el símbolo del preprocesador _DEBUG. Esto rara vez se cambia y se usa en el recurso de versión. El bit 0 del campo FILEFLAGES normalmente indica que los símbolos _DEBUG se definieron al compilar el recurso.

1

La pregunta es muy buena, y como ya se mencionó, no existen indicadores reales (únicos) que marquen si una imagen es depurada o no.

Como explained aquí y here, la presencia de un directorio de depuración NO es un indicador de si una imagen se ha creado o no en modo de liberación. Es muy común que las imágenes publicadas estén compiladas con soporte de depuración. Como cuestión de hecho, casi TODOS los archivos de imagen del sistema operativo Windows están diseñados con soporte de depuración (de lo contrario, NO habría posibilidad de vincular estas imágenes liberadas con los archivos de símbolos del servidor de símbolos de Microsoft). ¡Aunque estas imágenes son imágenes de lanzamiento!

Incluso la presencia de la sección .debug (en realidad, los nombres de las Secciones NO desempeñan un papel en la especificación PE; el nombre de una sección se puede cambiar y configurar como lo desee; ¡al Cargador no le importa!) NO es un indicador de la imagen Release vs. Debug.

1

Hay una vieja herramienta de inversión llamada LordPE. Le permitirá abrir dos archivos y diferir los encabezados. Recopilé un programa "hello world" en VS2008 en modo Release y Debug y los comparé. Como en los otros carteles, no vi nada que sirviera de indicador.

Pero lo que encontré como indicador fue el relleno en la sección .text del binario. Hay más de cien bytes con el valor 0xCC después del último byte de código en la sección .text en la versión de depuración. En la versión de lanzamiento, no había 0xCC bytes. 0xCC bytes aparecerán como int3 o puntos de interrupción en un depurador.

Cuestiones relacionadas