¿Por qué no se puede automatizar la ingeniería inversa?

31

Todavía estoy en la universidad para obtener un título en seguridad informática y tomé mi primera clase basada en lenguaje ensamblador el último semestre. Nos referimos al tema de la ingeniería inversa y por qué es una parte importante de la lucha contra el malware y las aplicaciones malintencionadas.

Durante mi clase, usamos principalmente IDA pro, pero también verificamos algunas aplicaciones similares y gratuitas basadas en navegador.

En estas aplicaciones, pudimos obtener tanta información sobre las instrucciones y el código de bajo nivel que me preguntaba por qué incluso necesitamos un humano para revisar y recrear los idiomas de nivel superior (como escribir una versión 'C' de una pieza de malware).

Aquí mi pregunta:

¿Por qué un programa no puede usar la información que está presente en el código de ensamblaje y convertirla en un lenguaje simplista automáticamente?

Entiendo que no se vería exactamente igual que cuando se escribió por primera vez, pero ¿no debería ser posible recrearlo de una manera que facilite su lectura y seguimiento?

Es solo algo que no puedo entender, ¡gracias!

    
pregunta PositriesElectron 22.06.2015 - 20:33
fuente

3 respuestas

66

Respuesta corta

Es absolutamente posible, pero la precisión y la legibilidad es un asunto completamente diferente. Se debe hacer una aclaración: la ingeniería inversa no es la descompilación.

Respuesta larga

Ingeniería inversa es generalmente el proceso mediante el cual se toma algo (algo realmente) para ver cómo funciona. Desmontaje es cuando toma un archivo con formato binario e interpreta el código de máquina en su código de ensamblaje. Descompilar es interpretar el código de ensamblaje en un lenguaje de nivel superior.

Creo que su pregunta es realmente, ¿Por qué no se puede automatizar la descompilación de un programa? ¡Bien puede ser!

Hay varios Descompiladores de Java diferentes. El código de bytes de Java es completamente reversible debido a su independencia de arquitectura. Lo que se vuelve complicado es descompilar un lenguaje como C. Hex Rays proporciona un descompilador de C, pero C es un problema complicado. idioma. Hay 10 maneras diferentes de realizar la misma tarea. Lo que se puede hacer en 20 líneas, se puede hacer en 3 o 10. Es la interpretación del lenguaje lo que hace que la automatización de descompilar C sea difícil.

Seguro que puedes descompilar C en sus instrucciones más simples. Luego obtienes líneas como **(*var1) = 3; o (*bytecode)(param1) , que puede ser una llamada a un puntero de función. Lo peor es que debes recordar que estas son solo una interpretación . No puedo enfatizar eso lo suficiente. ¿Qué pasa si la interpretación es incorrecta? Esto es algo de lo que tiene que preocuparse en el nivel de desensamblaje, pero al menos hay una cantidad razonable de resultados para 5-6 bytes para una instrucción. Ahora tiene que interpretar 15-20 bytes para descubrir una llamada de función o un bucle for. Si existen técnicas de ingeniería inversa, entonces la interpretación es aún más difícil.

El contexto juega un papel muy importante. ¿Cuál es la diferencia entre un puntero de función, un puntero char * y un uint32 ? Absolutamente nada, excepto el contexto en el que se utiliza. Las optimizaciones del compilador pueden usar __fastcall en lugar de __stdcall . Lo que significa que ahora tienes que interpretar dónde van a estar los parámetros de las funciones; ya sea en la pila o en un registro? Las funciones en línea, macro, #defines se convertirán en parte de una subrutina más grande. No hay una manera real de interpretar esos tipos de contextos.

    
respondido por el RoraΖ 22.06.2015 - 20:58
fuente
16

Es posible volver a crear automáticamente algo que se parece al código C del ensamblaje, pero la cantidad de trabajo de adivinanzas que tendría que hacer el encargado de la complicación es monumental.

Los compiladores son cosas muy complicadas que hacen una transformación complicada en el código fuente. Optimizaciones, sustituciones de macro / pre-compilador, alineación de código, verificación de tipo y error, vinculación estática, etc. El que complemente las cosas tendría que adivinar (o elegir por defecto) qué compilador utilizó, qué banderas de compilación se establecieron, qué versión de en qué sistema operativo se compiló, en qué bibliotecas se compiló, etc.

Entonces, si tomaste un código C, lo cumpliste y luego lo descompilaste, el resultado se vería nada como el original.

Y eso es solo para producir un código C que se ejecuta, ni siquiera hemos hablado de legibilidad todavía. Los nombres de variables, nombres de funciones, etc., son arrancados por el compilador y reemplazados por direcciones sin procesar, por lo que los descompiladores como el que está imaginando normalmente nombran sus funciones A() , B() , C() ... y todas las variables a , b , c porque no tiene forma de conocer la semántica (es decir, qué se supone que representan estas cosas).

El resultado final es que cualquier persona con un poco de experiencia en ensamblaje diría que leer el código descompilado es realmente más difícil que leer el ensamblaje en bruto. (Con algunas excepciones: Java, por ejemplo, se descompila de forma bastante limpia).

    
respondido por el Mike Ounsworth 22.06.2015 - 20:58
fuente
2

Todavía tengo que encontrar un papel o un software que automatice completamente la ingeniería inversa, pero hay algunos campos que están particularmente interesados en la automatización de la ingeniería inversa , como el análisis forense. La automatización de ingeniería inversa no pretende (al menos en la actualidad) automatizar totalmente todo el proceso de ingeniería inversa, sino al menos algunas partes para que pueda escalar su procedimiento a un sistema de archivos completo. Esto se describe, por ejemplo, en este artículo :

  

Introducción

     

Este artículo abordará la creciente necesidad de automatización   en ingeniería inversa (Automatización de ingeniería inversa), cómo la   Introducción de la automatización en el proceso de investigación puede ahorrar valioso   tiempo y ayuda en la recuperación de información sin la cual, ya sea nuestra   la investigación sería menos exhaustiva, o se llevaría a cabo en una   escala significativamente menor.

     

También en este artículo, presentaré ejemplos de scripts de automatización,   y los haré accesibles a través de mi cuenta de Github. Yo tambien te invito   para agregar más ejemplos, más allá de los ejemplos que se encuentran en este artículo,   y enviarme solicitudes de extracción, para que pueda agregarlas.

     

¿Por qué se necesita automatización en ingeniería inversa?

     

En primer lugar, me siento   Es importante señalar que la ingeniería de ingeniería inversa guarda   tiempo de investigación pero no reemplaza el resto del proceso, y   En segundo lugar, por razones que incluyen las siguientes:

     
  1. Acciones repetidas.
  2.   
  3. Fragmentos de código dinámico que se detectan más adelante.   etapa del programa (Crypters, Packers).
  4.   
  5. Anular las protecciones de software, como SSDT.
  6.   
  7. Asignación de memoria del software que se ejecuta dentro de Ollydbg
  8.   

El artículo continúa describiendo algunas herramientas como OllyDBG-Python y OllyDBG-Playtime, y luego algunos fragmentos de código que también están disponibles aquí y aquí en opensource.

    
respondido por el gaborous 22.09.2015 - 19:28
fuente

Lea otras preguntas en las etiquetas