No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Ingeniería Reversa y Ensamblador en C para Análisis de Malware

6/18
Recursos

¿Qué es la ingeniería inversa y cómo se aplica en programación?

La ingeniería inversa es un proceso fascinante que nos permite desentrañar los misterios de cualquier objeto creado por el hombre. Así como el admirador de un café se detendría a descubrir el origen de los granos y su composición para replicar su bebida favorita, los ingenieros de software usan el mismo enfoque analítico para comprender y reproducir programas informáticos. Este proceso involucra descomponer el software en sus partes fundamentales para entender su estructura, funciones y operaciones, permitiendo a los programadores replicarlo o mejorarlo.

¿Cómo funciona el lenguaje ensamblador en programación?

El lenguaje ensamblador, en especial el x86 Assembly Language, es una herramienta clave para traducir los programas de C, un lenguaje de programación de alto nivel, a un código comprensible para las computadoras. Al utilizar sistemas de compiladores y herramientas de desensamblado, podemos convertir el código C en lenguaje ensamblador para su análisis o modificación. Por ejemplo, al generar el código ensamblador a partir de un programa simple en C como "Hola, Mundo", podemos observar cómo se transforma en instrucciones específicas que la CPU puede entender y ejecutar.

#include <stdio.h>
int main() {
    printf("Hola, Mundo\n");
    return 0;
}

El compilador traduce este código en lenguaje ensamblador:

global main
section .text
start:
    push message
    call printf
    add esp, 4
    ret

¿Cuáles son las instrucciones comunes en el lenguaje ensamblador?

Las instrucciones del lenguaje ensamblador son fundamentales para manipular directamente la arquitectura del hardware. Algunas de las más comunes incluyen:

  • Movimientos de datos: MOV, PUSH, POP.
  • Instrucciones aritméticas: ADD (suma), SUB (resta).
  • Operaciones lógicas: OR, XOR.
  • Condicionales para control de flujo: JMP (salto), JNE (salto si no es igual), JNZ (salto si no es cero).

Cada instrucción tiene un propósito específico y es crucial para la ejecución precisa de un programa. Es recomendable investigar más sobre estas instrucciones para entender su utilidad y función exacta.

¿Qué son los punteros y cómo se utilizan?

En el ámbito de la programación y el análisis de malware, los punteros son cruciales. Funcionan como "flechitas" que indican la dirección de memoria donde se almacenan variables o datos. Por ejemplo, si tienes una variable que almacena un valor importante, un puntero te dirá dónde encontrar ese valor en memoria para utilizarlo o modificarlo según sea necesario.

int a = 10;
int *ptr = &a;

En el ejemplo anterior, ptr es un puntero que apunta a la dirección de memoria de la variable a. Los punteros no solo son críticos para la eficiencia del almacenamiento en memoria, sino que también son vitales en la interacción con librerías de vínculos dinámicos (DLLs) y la ejecución de subrutinas.

¿Cómo influyen las DLL en el análisis de malware?

Las DLL, bibliotecas de vínculos dinámicos, son componentes esenciales en el entorno de Windows. Facilitan que múltiples programas puedan compartir instrucciones para funciones comunes sin duplicar código. Sin embargo, en el análisis de malware, es crucial identificar qué DLLs son llamadas por un programa, ya que algunas pueden indicar procesos inusuales o maliciosos, como bypassing de firewalls.

¿Qué son los archivos PIF y su importancia en la programación C?

Los archivos PIF (Portable Executable Format) son cruciales en la arquitectura de los programas ejecutables. Siguen un estándar que define cómo se almacenan los datos, cómo se carga un programa en la memoria y cómo se desarrollan sus funciones. En el contexto del análisis de malware, examinar los encabezados de las secciones dentro de un archivo PIF puede ofrecer pistas valiosas sobre posibles comportamientos maliciosos.

Con cada paso, desde entender las bases de la programación en C hasta desentrañar los aspectos intrincados de los archivos PIF y DLLs, te equipas con las herramientas necesarias para desentrañar, analizar y replicar programas. Esta base es fundamental no solo para el desarrollo de programas eficientes sino también para la defensa contra software malicioso. ¡Sigue adelante en tu travesía de aprendizaje y descubre las maravillas del mundo de la programación!

Aportes 13

Preguntas 2

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Hay una instrucción que he notado que es muy común que este antes de las de “control flow” es la de CMP, comparar. Otra que he visto es INC de incrementar.

Comparto una pequeña simplificación espero les sirva:

  • Punteros: Imagina que la memoria de la computadora es un enorme bloque de casilleros, cada uno con una dirección única. Un puntero es como una nota que tiene escrita la dirección de uno de esos casilleros. Así, puedes encontrar lo que hay en ese casillero particular mirando la dirección en tu nota.

  • Biblioteca de vínculos dinámicos (DLL): Es como una caja de herramientas que tu programa puede utilizar. En lugar de llevar todas tus herramientas contigo todo el tiempo, vas a la caja (DLL) y tomas la herramienta (función) que necesitas cuando la necesitas. Los punteros ayudan a tu programa a saber dónde encontrar cada herramienta (función) en la caja (DLL).

  • Métodos virtuales y tabla de métodos virtuales: En la programación orientada a objetos, los métodos virtuales son como reglas generales que puedes cambiar para adaptarse a situaciones específicas. La tabla de métodos virtuales es como un directorio que le dice a tu programa qué versión específica de la regla general usar en cada situación. Nuevamente, los punteros ayudan a tu programa a encontrar la versión correcta de la regla.

Instrucciones comunes en ensamblador.

Con calma, se puede entender, solo hay que repasar esta clase un par de veces y complementar

Algunas notas de la clase
Fases de compilacion en C :
Pre-procesamiento -> Compilacion -> Assembly -> linking

PE Files(Portable Executable):
~el formato de windows PE describe la estructura de los archivos de windows modernos como .exe,.dll y .sys
~Contiene informacion,recursos y diferencias hacia DLL’s(librerias/bibliotecas de enlace dinamico)
~define la manera en que se almacenan los datos contenido instrucciones x86,imagenes,textos y metadatos que un programa necesita para funcionar y ejecutarse

Fue diseñado para:
~Decirle a window como cargar un programa en la memoria
~proporcionar los medios o recursos que un programa al ejecutarse podria utilizar.
~proporcionar los medios o recursos que un programa al ejecutarse podria utilizar.
~proporciona datos de seguridad como codigo de firmas digitales

Muy importante

tuve que repetir la clase varias veces, mi cabeza exploto, pero se siente bien cuando empiezas a entender

Lo siento no lo pude evitar…
… Aseembly y la programación en C son considerados de un nivel más cercano al ser humano es interpretado por un compilador que convierte el código a instrucciones de maquina y al utilizar una herramienta de densamblador puedes obtener el lenguaje ensamblador de un programa C compilado.

f![](

Una lastima que el curso no tenga un pdf con las slide del curso hay unos cuantos principios aqui que memorizar

La arquitectura de programas en C se refiere al diseño y la estructura de cómo se organizan y se implementan los programas escritos en el lenguaje de programación C. Dado que C es un lenguaje de programación de propósito general, de bajo nivel y con una sintaxis relativamente simple, ofrece a los desarrolladores una gran flexibilidad para estructurar sus programas de manera eficiente y efectiva. La arquitectura de un programa en C implica la organización de código en funciones, módulos, archivos y el uso adecuado de variables globales y locales, tipos de datos, y estructuras de control. A continuación, se describen algunos aspectos clave de la arquitectura de programas en C. ### **Estructura Básica de un Programa en C** Un programa típico en C comienza con la definición de librerías necesarias, seguido de la declaración de variables globales, la definición de funciones, y finalmente, la función `main()`, que es el punto de entrada del programa. cCopy code \#include \<stdio.h> // Inclusión de una biblioteca estándar// Declaración de variables globales int globalVariable; // Declaración de funciones void exampleFunction() { // Código de la función } int main() { // Código del programa principal return 0; // Indica que el programa terminó con éxito } ### **Modularización y Organización del Código** * **Funciones:** permiten dividir el código en bloques reutilizables y autónomos que realizan tareas específicas. Las funciones pueden recibir datos a través de parámetros y retornar un valor. * **Archivos de cabecera (.h):** se utilizan para declarar la interfaz de los módulos, como prototipos de funciones, definiciones de tipos de datos y macros. Facilitan la separación entre la implementación de las funciones y su uso en otros archivos. * **Archivos de implementación (.c):** contienen la definición de funciones y variables. Los programas se pueden dividir en múltiples archivos de implementación para mejorar la organización y facilitar la mantenibilidad. ### **Principios de Diseño** * **Encapsulamiento:** cada módulo o función debe ser responsable de una parte específica de la funcionalidad del programa, con una clara interfaz y separación de las demás partes del programa. * **Cohesión:** los elementos dentro de un módulo o función deben estar estrechamente relacionados y trabajar juntos hacia un objetivo común. * **Acoplamiento:** los módulos y funciones deben estar lo menos dependientes posible entre sí, comunicándose a través de sus interfaces bien definidas. ### **Gestión de Memoria** C ofrece un control manual de la gestión de memoria, lo que significa que los programadores deben asignar y liberar memoria explícitamente utilizando funciones como `malloc`, `calloc`, `realloc`, y `free`. Esto permite una gran flexibilidad y eficiencia, pero también impone la responsabilidad de evitar fugas de memoria y otros errores relacionados. ### **Uso de Punteros** Los punteros son una herramienta poderosa en C, permitiendo manipular direcciones de memoria directamente. Son esenciales para la gestión dinámica de la memoria, la implementación de estructuras de datos complejas y la manipulación de arrays y cadenas de caracteres. ### **Estilo de Codificación y Normas** Adherirse a un estilo de codificación coherente y a las mejores prácticas es crucial para mantener el código legible, mantenible y seguro. Esto incluye la correcta indentación, nombrar variables de manera significativa, y documentar el código a través de comentarios.
En cuanto a punteros, Todos los lenguajes los utilizan, JS, Python, Java, C#, Rust, Go, Todos. Simplemente que en C los tienes que apuntar y modificar tu, y en los demás, el lenguaje lo hace por nosotros, si desean conocer mas, busquen acerca de Estructuras de Datos. El curso de Diego de Granda Estructuras de Datos con JavaScript es muy bueno.

Por aquí quien programo microcontroladores en lenguaje assembler?