Análisis de malware

Ingeniería inversa C++

septiembre 10, por AJ Kumar

Introducción

La programación en C++ es popular entre los desarrolladores debido a sus capacidades avanzadas. La ingeniería inversa de malware depende en gran medida de C++ para traducir el código fuente a código binario para comprender la jerarquía interna de clases. La adquisición del modelo de un binario se logra mediante herramientas sofisticadas y análisis estático/dinámico.

Las industrias de software utilizan ingeniería inversa para analizar un producto con el fin de descubrir el propósito de cada segmento de código. La ingeniería inversa requiere una combinación de habilidades especiales y una comprensión profunda del descifrado de códigos, la programación, el análisis lógico, los componentes internos de las computadoras y los ciclos de vida del desarrollo de software.

¡Conviértete en un ingeniero inverso certificado!

Obtenga capacitación práctica en vivo sobre análisis de malware desde cualquier lugar y conviértase en un analista certificado de ingeniería inversa. Comienza a aprender

Los profesionales que realizan ingeniería inversa deben tener algún conocimiento de los códigos de operación en lenguaje ensamblador y la programación en C++. También es útil si tienen conocimientos de herramientas de desmontaje, incluidas IDA Pro, Immunity Debugger, Dumpbin, Radare, edición Hexa, WinDbg y CFF Explorer en plataformas Windows y Linux.

¿Por qué realizar ingeniería inversa en C++?

Hay tres casos típicos en los que se emplea ingeniería inversa para deconstruir el diseño, la estructura del código fuente y la arquitectura de un software.

Modificando código propietario

El código fuente es propiedad intelectual de las empresas de software y no les gusta publicarlo. Los clientes de los desarrolladores de software normalmente reciben el paquete ejecutable, pero no el código fuente.

A menudo se necesita ingeniería inversa cuando un cliente busca modificar las definiciones de software, pero la empresa de software está fuera del negocio. En esas situaciones, se realizan modificaciones en el código binario, satisfaciendo al cliente.

Depuración de código heredado

El código heredado puede contener errores. La ingeniería inversa facilita la detección de errores sin analizar el código fuente. El software con errores se descompila en código ensamblador mediante desensambladores avanzados. Una vez que se comprende el flujo del programa, el desarrollador manipula las instrucciones esenciales del código ensamblador, lo que a su vez da como resultado un código libre de errores, listo para su lanzamiento.

Revertir malware

Las organizaciones de ciberseguridad, las empresas de antivirus y las agencias de inteligencia también aprovechan la ingeniería inversa para buscar la estructura de datos y la firma del malware. Esto es especialmente importante porque el malware a menudo se empaqueta, cifra o empaqueta para evitar ser descubierto.

Identificar binarios de C++

La identificación de archivos binarios de C++ comienza con el preprocesamiento del código y luego la compilación del resultado en código ensamblador. A partir del lenguaje de código ensamblador, se crean archivos de objetos ensambladores.

Los archivos objeto contienen los binarios que permiten instalar un programa sin compilar el código fuente. Los binarios pueden incluir datos, código ejecutable, información de enlaces dinámicos, datos de depuración, tablas de símbolos e información de reubicación.

La funcionalidad/flujo del programa C++ se basa en la representación ensamblada de C++. Estas son algunas de las características principales del código C++ ensamblado.

este puntero

El puntero “este” juega un papel crucial en la identificación de secciones C++ en el código ensamblador. Se inicializa para apuntar al objeto utilizado, para invocar la función, cuando está disponible en funciones C++ no estáticas.

Tablas V

vtable es un instrumento que facilita la resolución en tiempo de ejecución de llamadas a funciones virtuales. El compilador genera una tabla virtual que contiene punteros a cada función virtual para las clases que contienen funciones virtuales.

Clases

Las clases actúan como esquemas de objetos. Es un tipo de datos que contiene sus propios miembros de datos y funciones miembro. Los miembros pueden ser públicos o privados y las clases base pueden tener clases secundarias, creando una relación jerárquica.

Constructores y destructores

El constructor de clases C++ es una función miembro que inicializa objetos de una clase y se puede identificar en ensamblaje estudiando los objetos en los que se crea. Por lo general, se llama a un constructor antes de la función main() del punto de entrada, y se llama a un destructor cuando el programa finaliza utilizando el operador de eliminación.

Información de tipo de tiempo de ejecución (RTTI)

La información de tipo de tiempo de ejecución es un mecanismo para identificar el tipo de objeto en tiempo de ejecución utilizando el operador typeid ydynamic_cast . Estas palabras clave pasan información, como el nombre de la clase y la jerarquía, a la clase.

Manejo estructurado de excepciones

Las excepciones son irregularidades en el código fuente que ocurren inesperadamente durante el tiempo de ejecución y terminan el programa. El manejo estructurado de excepciones es el mecanismo que controla el flujo de ejecución y maneja los errores aislando la sección de código donde se origina la condición inesperada. Este aislamiento se logra mediante el uso de construcciones de sintaxis try , catch y block para garantizar una ejecución sostenible y sin errores.

Herencia

La herencia permite que nuevos objetos adopten propiedades de objetos existentes. La clase original desde la cual se llama a la herencia es una clase base o superclase. Cuando una herencia proviene de una superclase, se la conoce como clase o subclase derivada.

La observación de las relaciones RTTI puede revelar la jerarquía de herencia, pero el método más simple para determinar la jerarquía es observar las llamadas a los constructores de la superclase cuando se crea un objeto.

Conclusión

La ingeniería inversa en C++ puede reconstruir el código fuente faltante y alterar la estructura de un programa, afectando su flujo lógico. Se utiliza en el ámbito empresarial y de desarrollo de software para modificar, depurar y resucitar código perdido o heredado, pero también lo utilizan empresas de ciberseguridad y agencias de aplicación de la ley para descubrir y eliminar malware.

Extraer información confidencial de código ensamblador de alto nivel es una habilidad necesaria y su importancia seguirá creciendo a medida que el malware crezca en complejidad y persista la competencia entre desarrolladores.

¡Conviértete en un ingeniero inverso certificado!

Obtenga capacitación práctica en vivo sobre análisis de malware desde cualquier lugar y conviértase en un analista certificado de ingeniería inversa. Comienza a aprender

Fuentes

  1. Examinando el listado de ensamblados generado por el compilador de C++ , Code Project
  2. TUTORIAL C++ – GUSTO DE MONTAJE – , BogoToBogo
  3. Trucos de codificación 101: cómo guardar el código ensamblador generado por GCC , Panthema
  4. Ingeniería inversa x64 para principiantes: Linux , inteligencia de red