Tipo de conversión de código utilizada en archivos ejecutables de Linux

13

Quiero preguntar qué tipo de codificación se utiliza para hacer que los archivos ejecutables de Linux, por ejemplo, hexadecemal, binario o cualquier otra cosa. ¿Cómo se convierte? ¿Hay alguna forma de recuperar el código original de este archivo ejecutable?

Aquí hay un poco de código que tengo:

ELF���������>�����%|�����@�������������������@�8��@���������������������@�������@�����7<�����7<������� ������������������f�����f���������������������� ������[�UPX!L
h�h�8����������?�E�h=��ڊ̓�N�    4���9ISloB�q�w�]ȉ.��,ς��Q䝦����#e��-�N����/�b,���d<��'��-E��6E�s�/�U���ly�V�Y2]"a��S�.�hU�|�S�J�I�2���X}
�G0�;���5d�$���.)

¿Qué se supone que significa?

pañuelo rojo
fuente
Aunque no le ayudará a recuperar mucho de nada, vale la pena señalar que el stringsprograma de filtro puede ser muy útil para identificar qué es o hace un programa binario en particular porque imprimirá todas las cadenas de texto incrustadas más de una longitud especificada en un archivo binario y mirar los mensajes en un programa a veces te dice mucho sobre lo que es y hace.
Joe

Respuestas:

29

Es binario. El código fuente ha sido compilado. Puede verlo en un editor (un editor hexadecimal como blesspodría hacer cambios más refinados) pero realmente necesita saber lo que está haciendo. Probablemente solo sea bueno para hacer cambios de cadena.

Para algo más duro, puede comenzar a realizar ingeniería inversa del binario en el código de ensamblaje . Esto a menudo se considera como el lenguaje informático analizable por humanos de nivel más bajo.

objdump -d helloworld | less

Pero también incluirá muchas tonterías del compilador. Por ejemplo, si compila lo más simplehelloworld.cpp con G ++ y luego objdump, termina con 226 líneas (208 despojadas) de yuck. Podrías escribir un "hola mundo" en solo 15 líneas de ensamblaje , compilarlo y objdumpque aún así se convierta en 166 líneas (despojado).

Si eres lo suficientemente bueno con el ensamblaje, esto puede darte suficiente acceso para comprender lo que está sucediendo e incluso permitirte cambiarlo ... Pero para responder a tu pregunta original:

No puede volver a convertir el código compilado en el código fuente original .

Lo siento. Es una transformación unidireccional que pierde información (comentarios, formato, conceptos de algoritmos legibles, etc.), está estáticamente vinculada a otras cosas y generalmente está optimizada de tal manera que la haría ininteligible para cualquier cosa que no sean los mejores y más experimentados programadores.

Para darle una idea de la magnitud del problema, toda la idea del software de ingeniería inversa tiene su propio sitio Stack Exchange .

Oli
fuente
¿Me puede decir cómo puedo técnicas de ingeniería inversa y volver máxima cantidad de código coz He perdido la fuente
redchief
77
Ver mi edición reciente. No hay vuelta atrás a la fuente original. Con mucho aprendizaje y mucho tiempo, es posible que pueda reescribir la fuente en función del código de ensamblaje desmontado, pero en la mayoría de los casos, sería más barato (a menos que su tiempo no valga la pena) y más fácil simplemente reescribirlo desde cero.
Oli
1
La forma de recuperar la cantidad máxima de código es restaurar la copia de seguridad más reciente. Esa es también, por cierto, la única forma de recuperar de manera confiable algo parecido al código fuente original.
un CVn
1
No estoy en desacuerdo con el último párrafo, solo una nota al margen: algunos descompiladores IME hacen un gran trabajo al restaurar la estructura exacta del código (aparte de, por supuesto, como dijiste comentarios, formato, nombres de símbolos ...). Si no escribió el programa en primer lugar, el código fuente recuperado podría seguir siendo ininteligible, sin embargo, creo que es una excelente opción para recuperar (al menos parcialmente) un código fuente perdido / un código fuente desconocido (con al menos partes de él) realmente inteligible, dependiendo del código específico y de si tienes suerte también)
kos
1
Eso es lo que todos esos EULA en el mundo del software propietario dicen que no está permitido hacer: ingeniería inversa / desmontaje. Incluyen cláusulas como esta porque es posible hacerlo, ¡pero ciertamente no es fácil! Pero como dice @ MichaelKjörling, la única buena manera de recuperar las cosas es desde múltiples niveles de respaldo para cualquier cosa que le interese.
Joe
7

No tengo suficientes puntos de reputación para un comentario, así que es una respuesta:

No, no es posible convertirlo "de regreso". Mencionaste upx packer, ¿alguna vez leíste el manual de upx?

Si perdió la fuente, o no tiene acceso al código de otra persona, no importa aquí, simplemente no es posible.

El ejecutable binario fue producido con un compilador, no creas nada de lo que se dice en este sitio, solo lee el manual de ese compilador. Luego, puede agregar aquí, en qué idioma se escribió el código original, qué compilador se usó, y luego podría notar que estos pasos (preprocesamiento, compilación, vinculación, tal vez empaquetar) no se invierten en su conjunto, sino que solo podrían ser analizado lo que el autor original podría haber pretendido y escrito.

justabot
fuente
3

Como ya señaló Oli en su respuesta, no se puede obtener el código fuente muy original de un ejecutable.

Durante la compilación de un código fuente (compilación destinada a su aceptación más amplia típica, por lo tanto, como todo el proceso que "transforma" un código fuente en un ejecutable), se pierde mucha información.

El preprocesador C, por ejemplo, hará lo siguiente (entre otras cosas):

  • Interpretar, ejecutar y eliminar directivas de preprocesador ( #declaraciones)
  • Eliminar comentarios
  • Eliminar espacios en blanco innecesarios

Por otro lado, lo que no se pierde durante la compilación del código fuente es técnicamente reversible a un código fuente funcionalmente equivalente.

Esto es porque:

  • Las instrucciones binarias tienen una correspondencia 1: 1 con las instrucciones de montaje; el ensamblaje de un código fuente de ensamblaje es solo una mera conversión de las instrucciones de ensamblaje a las instrucciones binarias basadas en una tabla de correspondencias; una sola instrucción binaria siempre es identificable y reversible a una sola instrucción de ensamblaje ;
  • Las instrucciones de montaje no tienen una correspondencia 1: 1 con las instrucciones C; la compilación de un código fuente C generalmente no es solo una mera conversión de las instrucciones C a las instrucciones de ensamblaje basadas en una tabla de correspondencias, de hecho, a menudo es lo contrario; generalmente una instrucción C se convierte en instrucciones de ensamblaje múltiples (a menudo diferentes según el compilador); sin embargo, los patrones de múltiples instrucciones de ensamblaje son usualmente identificables y reversibles a una sola instrucción C ;

Hay herramientas llamadas descompiladores cuyo propósito es tratar de revertir un ejecutable a un código fuente funcionalmente equivalente; sin embargo, el resultado suele ser algo alejado del código fuente muy original (y, por lo general, también no es compatible);

Considere este programa:

#include <stdio.h>

#define MESSAGE "Literal strings will be recovered" // This preprocessor directive won't be recovered

/*

This comment and the comment above won't be recovered

*/

int main(int argc, char* argv[]) {
    printf(MESSAGE);
    return 0;
}

Al compilarlo en un ejecutable y descompilarlo en un código fuente nuevamente, esto es más o menos lo que generalmente obtienes (en este caso específico usé gcc/ Boomerang ):

// address: 0x80483fb
int main(int argc, char **argv, char **envp) {
    printf("Literal strings will be recovered");
    return 0;
}

Como se predijo:

  • Faltan directivas de preprocesador
  • Faltan comentarios (aparte de // address: 0x80483fb, que ha sido agregado por el descompilador)
  • Falta un espacio en blanco innecesario (aparte de las nuevas líneas y tabulaciones, que el descompilador ha agregado)

Este también es un resultado bastante bueno; No es raro obtener instrucciones de ensamblaje en línea en el código:

asm("assembly_instruction");
__asm__("assembly_instruction");

La conclusión es (como ya se señaló en las otras respuestas): no se puede obtener la fuente original de un ejecutable *.

* Sin embargo, dependiendo del ejecutable y de su suerte, puede obtener algo usando un descompilador.

kos
fuente
2

Los ejecutables suelen ser binarios si se trata de programas compilados. Puede encontrar más información utilizando file path/to/executable. Puede mostrar ejecutables binarios en hexadecimal usando, por ejemplo, hexdump -C path/to/executable | less(lo que sea bueno para usted). Si desea "volver a convertirlo a su forma original", tendría que usar un descompilador adecuado. Consulte esta publicación, por ejemplo , aunque eso le daría un código bastante ilegible, no el original del que fue compilado. Si no es un binario compilado, sería algún tipo de script ejecutable, que debería ser fácilmente legible en cualquier editor de texto. Lo que nos mostró aquí es probablemente un ejecutable compilado. ELF significa "formato ejecutable y de enlace", que es un formato binario común en sistemas Linux / Unix. Allí'strings path/to/executable, si esto es lo que necesitas.

Hinz
fuente
Traté de realizar ingeniería inversa con upx packer pero no funcionó y también con la publicación que sugirió. Así que por favor dime si hay otra manera.
redchief
Lo siento mucho, pero no puedo decirte nada más que lo que está escrito en la excelente publicación de @ Oli.
Hinz