11 - Ensamblador VII

[editar]
Curso gratis creado por Wintermute.
22 de Febrero de 2006
Introducción al coprocesador matemático

Conceptos básicos

El coprocesador matemático o FPU (Floating-Point Unit) utiliza números tanto reales como enteros, y se maneja mediante instrucciones integradas en el grupo común que utilizamos; es decir, que simplemente tiene sus instrucciones específicas que él va a utilizar.

Los números se representan normalizados, con 1 bit de signo, exponente y mantisa. Me gustaría poder explicar esto al detalle pero necesitaría demasiado espacio y no creo que resulte tan útil... tan sólo destacar que este es el tipo de formato que se usa para representar números reales, y se basa en que el primer bit del registro indica el signo (0 es positivo, 1 negativo), otros cuantos bits (en este caso 13) representan un exponente, y otros cuantos (64 esta vez) una mantisa. Es decir, que por decirlo de una forma algo burda, para obtener el número real deberíamos coger la mantisa y elevarla a este exponente.

Así, podemos ver que son 80 los bits que tiene cada registro de la FPU. Estos registros son ocho en total, y sus nombres consisten en una R seguida de un número, yendo desde R0 a R7.

La pila del coprocesador

La forma de acceder a los registros no es como en la CPU. Por decirlo de alguna manera, se forma una pila de registros con estos ocho registros de datos, operándose con el primero en esta pila (que llamamos ST(0)) y con varias instrucciones para mover los propios registros del copro con este objetivo.

Para referenciar en ensamblador a estos registros se hará a traves de la mencionada pila. Lo más alto de la pila será ese ST(0) - o simplemente, ST - , y podemos hacer operaciones como la siguiente:

FADD ST, ST(2)

Por supuesto, el resultado de esta suma entre el primer y tercer valor de la pila del coprocesador, almacenará el resultado en esta parte superior de la pila (ST), desplazando al resto en una posición hacia abajo (el anterior ST será ahora ST(1), y el ST(2) será ahora ST(3)). El sistema puede resultar - y de hecho es - algo lioso, pero todo se aclara si se utiliza un buen debugger y se comprueba a mano lo que estoy diciendo, y cómo la FPU administra sus registros.

Ejemplo de una multiplicación con la FPU

Como no me quiero entretener mucho con esto - que probablemente nadie vaya a usar -, pasaré directamente a utilizar un ejemplo bastante ilustrativo de lo que sucede cuando estamos utilizando la FPU.

Pretendemos, en el ejemplo siguiente, llevar a cabo la operación (10 x 15) + (17 x 21):

fld 10 ; Cargamos en ST(0) el valor 10 fmul 15 ; Ahora 10 x 15 se almacena en ST(0) fld 17 ; ST(0) vale 17, y OJO, el resultado de 10x15 (150) estará en ST(1) fmul 21 ; ST(0) pasa a valer 21 x 17, es decir, 191. Tenemos pues que ;ST(0)=21x17=191 y ST(1)=10x15=150 fadd ST(1) ; Con esta instrucción añadimos a ST(0)(operando por defecto) ST(1), luego ;acabamos teniendo ST(0) = (21x17)+(10x15) = 341, resultado final.

Una referencia completa de las instrucciones utilizadas por la FPU (que son muchas y permiten coger o guardar en memoria, transferir a un formato que entiendan los registros del procesador y viceversa y unas cuantas operaciones como incluso senos y cosenos), recomiendo echarle un vistazo a los manuales de Intel - aunque son medianamente oscuros con el tema.




Utilidades para la Programación

En este capítulo tomaremos un punto de vista eminentemente práctico de cara a la programación de virus; se trata, de una introducción a ciertas utilidades que vamos a necesitar de cara a programar virus, y que hay que saber manejar al menos un mínimo.

Sé que las utilidades que he escogido no serán del gusto de todos por diversos motivos; los dos compiladores de los que hablo (TASM y NASM, para Windows y Linux) creo que son de lo mejorcito que se puede encontrar

-bien, podría haber hablado del GAS, GNU Assembler, en Linux, pero sinceramente odio el formato At&t de ensamblador, y lo interesante es que de programar en el formato que acepta TASM a hacerlo en el que acepta NASM hay muy pocas diferencias, con lo que lo que se aprende para uno puede servir bastante para el otro. El NASM sin embargo tiene algún problema incomprensible (por ejemplo, no compila la instrucción RDTSC pero tampoco indica que hayan errores).

El mismo motivo ha hecho que de cara a debuggers, detalle para Linux el ALD en lugar del GDB; bien que GDB es un debugger mucho más potente, pero ALD es mucho más sencillo de utilizar (entre otras cosas porque es parecido al Debug del Dos, y porque no usa el formato At&t). Esta razón de sencillez de uso es la que también hace que hable del Turbo Debugger 32 en Windows y no del Softice. Aunque Softice es la verdadera herramienta para trabajar en Windows, Turbo Debugger es mucho más sencillo y se puede aprender en diez minutos (para el Softice habría que dedicar un capítulo entero, aunque es cierto que merecería la pena).

TASM (Windows/Ms-Dos)

Introducción

La utilidad TASM es el clásico de los compiladores de ensamblador para Ms-Dos y Windows. Lo que hace es sencillamente convertir el texto que nosotros hemos escrito en un fichero de texto con las instrucciones en ensamblador de nuestro programa, en un ejecutable que podemos utilizar. Aquí quien no haya visto aún la potencia del lenguaje ASM se dará cuenta; lo que escribimos no se modifica, es decir, si tenemos una órden "ADD EAX,EBX", en el programa compilado se va a codificar así y de ninguna otra manera. ¿Que por qué digo esto? Pues en comparación con lenguajes de alto nivel; por ejemplo si escribimos un Print ("Hola"); el compilador va a traducirlo a lenguaje ensamblador primero, llamando a funciones del sistema operativo para imprimir por pantalla.

En los lenguajes de alto nivel no tenemos control sobre las instrucciones en ensamblador que se están generando, pero en ASM dado que estamos escribiendo en el lenguaje de la propia máquina, tenemos el dominio total sobre la situación.

Aunque el paquete con el que viene TASM ocupe comprimido el equivalente a 5 diskettes y tenga unas cuantas cosas, hay dos ficheros en particular que son los que vamos a utilizar con mayor frecuencia. TASM viene con unas cuantas utilidades incorporadas, como el propio Turbo Debugger, un extractor de listados de APIs para utilizar en nuestros programas y alguna cosilla más, pero en principio nos vamos a reducir a dos,

TASM32.EXE y TLINK32.EXE

TASM32.EXE

El primer paso al compilar nuestro listado va a ser ejecutar esta utilidad, que va a realizar el compilado del fichero. La forma de utilización básica es "Tasm32 ", aunque vamos a necesitar indicarle algunos parámetros, como por ejemplo:

-m#: Aquí el # es un número que indica cuantos "repasos" para resolver llamadas y referencias se van a dar. Es importante delimitarlo, puesto que si pegamos una o dos pasadas (m1, m2), muchas veces nos van a dar fallos que no deberían. Personalmente suelo ponerlo a 5 pasadas.

-ml/mu: Sensibilidad para mayúsculas/minúsculas. Si ponemos "-ml", el ensamblador interpretará por ejemplo que "Etiqueta" es diferente a "etiqueta". la opción "-mu" indicaría que no se hace caso de este hecho

-q: Supresión de partes no necesarias para el linkado (la segunda fase, que explicaremos más adelante).

-zn/zd/zi: Información para debugging. Para ciertos programas de debuggeo, es interesante activar esta opción. Zn indica que no se guarda ninguna información, zd que se guardan los números de línea, y zi guarda toda la información.

-i: Indica el path para los ficheros que incluyamos con la directiva "include" en el propio código.

Esto sólo son algunos ejemplos de parámetros que se indican al compilador; por suerte si escribimos simplemente "tasm32", se nos mostrará la lista de parámetros con una pequeña explicación de lo que hace cada uno. Personalmente, suelo utilizar para compilar una línea tipo "tasm32 -ml -m5 -q -zn nombrevirus.asm"

Por supuesto, si algo está mal escrito en nuestro código, el compilador nos indicará amablemente en qué número de línea hemos metido la zarpa y a ser posible el tipo de fallo que ha habido.

TLINK32.EXE

Tras el proceso de ensamblado, toca la segunda parte, el linkado (traducido literalmente, "enlazado"). Un poco dicho a lo bestia, es como si al usar el compilador hubiera convertido lo que hemos escrito en un código ensamblador algo disperso, y con el linkador vamos a estructurarlo para que sea un ejecutable bueno y decente ;-). De nuevo, tenemos unas cuantas opciones, de las que detallo alguna:

-Txx: Indica el tipo de fichero que queremos generar. Si queremos hacer un ejecutable de Windows, pondremos -Tpe (PE es el formato de fichero en Windows95, 98 y NT). -Tpd indicaría que queremos hacer un .DLL

-v: Indica que queremos información para debugging.

-c: De nuevo el tema de mayusculas/minusculas (las tiene en cuenta).

-aa: Con esta opción indicamos que usamos la API de Windows, por defecto está bien ponerla y tal.

De nuevo, tenemos suerte y ejecutando Tlink32 sin parámetros nos va a explicar los que podemos utilizar. Un ejemplo típico de uso sería algo como "tlink32 -v -Tpe -c -x -aa nombrevirus,,, import32".

Hay un par de cosas a destacar en esta línea, aunque tampoco quiero profundizar (es de esas cosas que se pueden utilizar sin entender, al fin y al cabo xD). En primer lugar, que no escribimos el ".asm" al final del nombre del fichero origen, en segundo lugar que tenemos tres comas y algo llamado "import32" por ahí que de momento no sabemos lo que es.

El tema del import32, consiste en que hay un fichero bastante standard y bastante distribuído (creo yo que viene con la distribución del TASM, pero sino se puede encontrar fácilmente) llamado import32.lib, que por así decirlo nos facilita poder acceder a la API de Windows. Es decir, si yo quiero ejecutar alguna llamada a la API de Windoze, tengo que importar esa librería donde se hace referencia a estas APIs. En cualquier caso, si no la encontrais podéis fabricaros una utilizando el IMPLIB.EXE sobre las librerías que tenéis en windows\system.

Particularidades de TASM

A continuación, copio un pequeño listado improvisado donde paso a comentar lo que sucede, que me parece mejor que simplemente ir listando cosas. Puede que me deje alguna, pero en cualquier caso en la propia página tenéis un virus de windows que sirve de ejemplo bastante bien:

; ; Programa de prueba ; ;.486p

; modelo de procesador (486 modo protegido, conviene dejarlo así como standard)

.model flat

; lo mismo digo (esto hace referencia al modelo de memoria, flat) NULL EQU 00000000h MB_ICONEXCLAMATION EQU 00000030h ; Esto hace que cuando escribamos p.ej "NULL", el ensamblador ;lo vaya a interpretar como un 0. EQU es "equivale a", y es util ;usarlo para no tener que recordar valores absurdos (el ;MB_ICONEXCLAMATION es el valor que indica que una ventana pop-up ;muestre una exclamación) extrn ExitProcess: proc extrn MessageBoxA: proc extrn GetProcAddress: proc ; Esto son las APIs que estamos importando para utilizar en nuestro ;código. Para ello tenemos que escribir el nombre de la API antes de ;los : y el proc (sencillo, no?)

.data

; Sección de datos del ejecutable. La haremos de tamaño 1 byte (¿y por qué no? xD)

db ? .code ; Ahora viene la parte seria, la sección de código de nuestro programa Start: ; Esta primera etiqueta es algo que hay que recordar, porque luego ;la vamos a cerrar al final.

push MB_ICONEXCLAMATION

push offset Titulo

push offset Escribir

push NULL

call MessageBoxA ; ¿Recordáis la forma de llamar a la API de Windows? Estamos empujando ;a la pila el valor de una ventana con exclamación, el offset ;"Titulo" (titulo de la ventana, con un 0 al final), el offset de ;"Escribir" (texto de la ventana), y un valor NULL, llamando luego a ;la API "MessageBoxA", que saca una caja de estas con botón sólo de ;aceptar (indicado si no recuerdo mal por el NULL), para que le demos.

call ExitProcess Titulo: db 'Titulo de la ventana',0 Escribir: db 'Esto es el contenido de la ventana',0 include algo.incinclude algo2.asm; Los includes son algo bastante útil cuando tenemos un buen pedazo ;de programa. En cierto modo es como cuando hacemos un include en C, ;sólo que no necesitamos ficheros de definición ni nada así. Por ;decirlo claro, con un include estamos diciendo "aquí, tu actúa como ;si todo fuera un gran fichero donde justo en esta parte está lo que ;haya en el fichero incluído (vamos, que el fichero algo2.asm puede ;ser sencillamente una linea de texto que ponga "push ax", y lo que ;hará es sustituirlo).

end Start

;Esto es el final del código, y se indica con "end" seguido de ;la etiqueta que pusimos al principio del código.

Supongo que me dejaré unas cuantas cosas, pero al menos con esto tenéis una idea del aspecto que ha de tener un fichero en ensamblador de cara a ser compilado con TASM, y las pequeñas chorraditas que hay que meter para que funcione.

Personalmente, suelo utilizar un fichero .BAT para que me haga la compilación; un detalle, si tenéis datos metidos en la sección de código, al compilar el programa la sección de código no va a ser escribible (normalmente no se modifican las secciones de código). Para ello os recomiendo que os hagáis con una utilidad llamada pewrsec de Jacky Qwerty (facilita de encontrar). A lo que iba, este es un ejemplo de un fichero BAT para compilar un programa:

tasm32 -ml -m5 -q -zn viruz.asm tlink32 -v -Tpe -c -x -aa viruz,,, import32 pewrsec viruz.exe

No viene nada mal no tener que estar escribiendo líneas enteras de memoria y tal, ya sabéis xD. Haceos algo como esto y olvidaos lo antes posible de tener que cambiar algo de cara al TASM, así os podéis centrar en programar que es al fin y al cabo lo que todos queremos hacer, ¿no?.

¿Y de dónde me lo bajo?

Esta pregunta es sencilla de resolver; vete a http://www.oninet.es/usuarios/darknode y en "other interesting virus related stuff" busca el enlace al TASM.
[editar]

110 opiniones

q buena

pues tios les digo q lo aprendan por que por ejemplo si hacen un viruz pero lo hacen con lo que es ensamblador pues asi el tio formatee su pc seguira infectado ademas es recomendado si piensan en conocimiento i en aprender mas de esto


salu2
Duda.

Sacado de: "2 - estructura de computadores"
"dado que los ejemplos nunca sobran, veamos una instrucción como cmp ac, 12. Una vez llegue tras la fase de fetch a la unidad de control, de nuevo se utilizará la alu; en esta ocasión se la indicará mediante señales de control que realice la operación de resta (sub), metiendo por un lado el 12 y por otro el registro ac"

¿por qué hará la operación sub? ¿no sería menos costoso hacer la operacion xor?
¿si el resultado de aplicar dos oprendos a xor da 0 implica que son el mismo número, no?

un saludo!.
Falta pewrsec.

Probe ensamblar el codigo del primer ejemplo pero no encuentra las referencias a las funciones de las apis no existe mas la web donde estan los recursos http://www.oninet.es/usuarios/darknode

me parece muy bueno el curso. Es imposible encontrar algo de ensamlador de 32 bits en español. Entiendo ingles pero ya me produce nauseas tener que leer en ese idioma todo la informacion sobre programacion. Lo unico que le falta es que el autor le de una actualizacion (revision).
Buenisimo.

En realidad me encanto el curso,a demas entendible. Y eso que apenas yo estoy aprendiendo sobre estos temas, pero vaya esta muy claro. Muchas gracias por su ayuda.
Virus.

Pues aqui hay un virus:
abres block de notas y pones lo siguiente:
@echo off
echo... :adcc
msg * adcc=windows_live_447@hotmail.com
goto adcc
se guarda en. Bat
ej: hola. Bat.
1 2 3 4 5 6 7 ... 22 | siguiente >

Cursos gratis relacionados con 'Curso de programación de virus'

La meta de este curso es el aprendizaje de métodos en programación, tanto en teoría... Más »
Completo curso acerca de los virus informáticos, historia, clasificación, protección...
Completo curso de lenguaje ensamblador.
En este glosario, lo primero que se ha de definir es la palabra HACKER ya... Más »
Curso de introducción al Comercio Electrónico.

Autor y licencia de 'Curso de programación de virus'


Curso gratis de Wintermute. Extraido de: CopyLeft
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.