Análisis de malware
Desmontaje 101
agosto 13, por Richard Azú
Introducción
Este artículo explora brevemente temas relacionados con conceptos básicos de ensamblaje, registros, operandos, instrucciones, instrucciones aritméticas, instrucciones lógicas, instrucciones de pila, condicionales e instrucciones de salto. Concluiremos con una razón por la cual el lenguaje ensamblador sigue siendo relevante a pesar de la evolución de los lenguajes de alto nivel.
Este artículo ha sido diseñado para profesionales, estudiantes o autodidactas que quieran aprender los aspectos clave de la programación ensambladora. Este artículo le ayudará a comprender mejor la programación en ensamblador.
Lenguaje de programación informática
El lenguaje de programación de computadoras es cualquiera de los varios lenguajes utilizados para expresar un conjunto de instrucciones detalladas para una computadora digital. Los lenguajes de programación se clasifican ampliamente en tres categorías: lenguajes de máquina, ensambladores y de alto nivel.
Lenguaje de máquina
El lenguaje de máquina también se conoce como código de máquina. Es una secuencia de patrones de bits que se utiliza para proporcionar instrucciones al procesador de una computadora. Estas secuencias de dígitos binarios no son legibles por humanos.
lenguaje ensamblador
El lenguaje ensamblador envía códigos o instrucciones a la computadora mediante abreviaturas mnemotécnicas simples. Dado que la computadora no entiende directamente los códigos en lenguaje ensamblador, se requiere un traductor para convertir las instrucciones al lenguaje de máquina.
El programa de utilidad que convierte programas de código fuente de lenguaje ensamblador a lenguaje de máquina, para que la Unidad Central de Procesamiento (CPU) pueda entenderlo, se conoce como ensamblador. La conversión inversa del lenguaje de máquina al lenguaje ensamblador la ejecuta un traductor llamado desensamblador.
lenguaje de alto nivel
Los lenguajes de alto nivel envían códigos o instrucciones a la computadora utilizando palabras simples en inglés y símbolos matemáticos. Este tipo de instrucciones a veces se denominan lenguajes humanos porque están más alejados del lenguaje de máquina. Los traductores que convierten el lenguaje de alto nivel en lenguaje de máquina se denominan compiladores e intérpretes.
Conceptos básicos de montaje
Estructura de un sistema informático.
La estructura básica de un sistema informático está formada por la CPU, la memoria principal y los periféricos de entrada/salida. La CPU también se compone de registros, unidades de control y unidad aritmética y lógica (ALU).
Registros
La CPU de una computadora ejecuta todas sus tareas y operaciones. Para hacer esto de manera efectiva, necesita almacenamiento para procesar las operaciones y conservar temporalmente las instrucciones recibidas. Este almacenamiento se llama registro. Un registro puede almacenar códigos o conjuntos de instrucciones, una dirección de almacenamiento de otra ubicación o cualquier tipo de dato como el binario de un carácter.
Instrucciones
Las instrucciones en lenguaje ensamblador se dividen en dos partes: el código operativo (opcode) y los datos sobre los que se operará, el operando. Un código típico en lenguaje ensamblador tiene dos operandos, el operando de destino y el operando de origen. El operando de destino normalmente es la dirección de un registro, mientras que el operando de origen representa un valor.
Ejemplo de código ensamblador
MOV AL, 4Dh ; cargar registro AL con 77 decimales (4D hexadecimal)
Código binario equivalente
1011 0 000 01001101
1011 un código binario (código de operación) de la instrucción ‘MOV’
0 especifica si los datos son bytes («0») o tamaño completo 16/32 bits
000 un identificador binario para un registro ‘AL’
01001101 es la representación binaria del decimal 77
Instrucciones aritméticas
A continuación se muestran ejemplos de instrucciones aritméticas que realiza el lenguaje ensamblador.
- INC AL ; Incrementa el valor en el registro de bytes bajo del registro AL del acumulador primario en 1
- DEC AL ; Disminuye el valor en el registro de bytes bajo del registro AL del acumulador primario en 1
- AÑADIR AX, BX; Sume los valores almacenados en el acumulador primario AX y el registro base BX y luego almacene la suma en el acumulador AX
Instrucciones lógicas
Las instrucciones lógicas en lenguaje ensamblador funcionan bit a bit; por lo tanto, no se genera ningún bit de desbordamiento o acarreo. Las operaciones lógicas típicas incluyen lógica y (Y), lógica o (O),
complemento lógico (NOT) y exclusivo lógico o (XOR). La operación AND se puede utilizar para borrar uno o más bits en un registro.
Instrucciones de pila
La pila de lenguaje ensamblador son estructuras de arriba hacia abajo en la memoria que almacenan datos de tal manera que los últimos datos almacenados son los primeros en recuperarse. El único acceso para agregar o eliminar datos de la pila es a través de la parte superior de la pila. Las instrucciones de pila más comunes son PUSH y POP. PUSH coloca los datos nuevos en la parte superior de la pila, mientras que POP elimina los siguientes datos de la parte superior de la pila.
Condicionales
Las declaraciones condicionales en lenguaje ensamblador controlan el flujo de ejecución del programa. Las declaraciones condicionales se dividen en dos partes: salto incondicional y salto condicional.
El salto incondicional lo realiza la instrucción JMP. La instrucción CMP compara dos operandos y establece el indicador apropiado, según el resultado. Las instrucciones de salto condicional reciben información de los indicadores establecidos en función de la salida de la instrucción CMP.
salto incondicional
- MOV HACHA, 10 ; Inicializando AX a 2
- MOV BX, 11; Inicializando BX a 3
- MOV CX, 00 ; Inicializando CX a 0
- L17:
- AÑADIR HACHA, 01; Incremento AX
- AÑADIR BX, AX ; Agregar AX a BX
- JMPL17; repite las declaraciones
- AÑADIR BX, AX ; Agregue AX a BX (este código de línea nunca se ejecutará debido a la instrucción de salto incondicional JMP L17)
salto condicional
- CMP DX, 01 ; Compare el valor DX con uno
- JE L17 ; En caso afirmativo, salte a la etiqueta L7 (este es un salto condicional que omite las dos instrucciones siguientes solo si el valor en el registro DX es uno)
- AÑADIR HACHA, 01 ; Incremento AX
- AÑADIR BX, AX ; Agregar AX a BX
- L17:
- AÑADIR HACHA, 11 ; Incremento AX
- AÑADIR BX, AX ; Agregar AX a BX
Conclusión
La capacidad de leer y escribir códigos o conjuntos de instrucciones en lenguaje ensamblador de bajo nivel es una gran habilidad a pesar de la evolución de los lenguajes de alto nivel. Los códigos en lenguaje ensamblador se utilizan en la codificación de controladores de dispositivos, sistemas en tiempo real y sistemas integrados de bajo nivel. Estos códigos también ayudan en los procesos de ingeniería inversa utilizados para establecer las vulnerabilidades o flujos lógicos de los programas informáticos en un entorno de ejecución del mundo real.
¡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
- Lenguaje de programación informática , Enciclopedia Británica
- Cuadro comparativo de la diferencia entre lenguaje de máquina y lenguaje ensamblador , STechies