Resultados 1 al 2 de 2

Tutorial Windows asm 16 y 32 bits

  1. #1 Tutorial Windows asm 16 y 32 bits 
    Avanzado
    Fecha de ingreso
    Oct 2010
    Mensajes
    401
    Descargas
    24
    Uploads
    0
    Introduccion:

    Esta es la primera parte de una serie de papers, en la que tratare de explicar la programación ensamblador para Windows 32 bits y su sistema dos 16 bits, el porque de elegir windows, es porque es el sistema mas utilizando y seguramente muchos de ustedes tengan un interés (oscuro) en este sistema, si hablamos de la ingeniería inversa, sus métodos no se explicaran en esta serie de papers, pero esta claro que le sera muy útil, aunque no solo ….... vive el hombre, también podrá utilizar para depurar sus programas y ver realmente como el sistema ejecuta las instrucciones de un programa, así usted llegara a conseguir una visión real, no la superficialidad de los lenguajes de alto nivel como visual basic........

    En este tutorial me saltare muchos tecnicismos y la explicación de conversión entre hexadecimal, decimal ….... para todo esto utilice la calculadora científica de Windows.

    Por cierto me presento soy Chewarrior xd.


    Tema 1:



    1-Registros de segmento

    2-Registros de uso general

    3-Funcionamiento de la Pila [Parte 1]

    4-Puntero de Instrucción








    Los registros de segmento


    Los registros de segmento son direcciones temporales que se almacenan en la memoria, el ordenador los divide en varias secciones (segmentos), dependiendo de la función a realizar.


    Por ejemplo el segmento DS, de datos seria donde nuestro programa guarda las variables, CS segmento de código seria el que contendría el código a ejecutar y SS el segmento de pila, este segmento se utiliza para sacar o introducir instrucciones y datos normalmente es utilizado por las funciones.

    También tenemos un segmento libre ES para funciones adicionales.

    DS segmento de datos

    CS segmento de código

    SS segmento de pila

    ES segmento adicional


    Ahora para poder llegar a comprender lo mejor veremos este código en C, para explicar donde se situaría cada segmento
    Código:
    #include <asm.h>
    
    char caracter=”A”;  // Esto estaría en DS segmento de datos
    
    int main(){ //  Diagamos que con la funcion main empieza nuestro sg CS
    
    printf(“%s”,caracter); // Nuestra querida funcion printf se carga en la pila
    
     SS, despues entraremos mas en profundidad con la pila.
    
    
    
    
    
    
    Return 0;  
    }
    ¡Ya! esta usted aburrido, pues no queda mucho mas para hacer nuestro Hola mundo dos 16 bits y 32 bits, pero no se desanime solo intente asimilar estos conceptos, seguramente tenga que leerlo mas de una vez, no se preocupe es lo mas normal.


    Registros de uso general

    Son registros internos del procesador usados para almacenar datos y hacer desplazamientos.

    AX, EAX;

    A (Acumulador) Optimizado para las operaciones aritméticas, aunque se puede usar para cualquier otra cosa.


    BX, EBX;


    B (Base), Utilizado para hacer desplazamientos, aunque se puede usar para cualquier otra cosa.


    CX,ECX;

    C (Counter), Este registro es utilizado por algunas instrucciones de bucle como loop, aunque se puede usar para cualquier otra cosa.


    DX,EDX;

    D(data), es usada conjuntamente con otros registros para almacenar datos, aunque se puede usar para cualquier otra cosa.

    SI,ESI Y DI,EDI;

    Es similar a los punteros en los lenguajes de alto nivel, SI contendrá la dirección de los datos de origen y DI la dirección de destino.


    SP,ESP Y BP, EBP;

    Estos registros trabajan con la pila, SP contiene la dirrecion de incio de pila SS:SP y BP es un puntero base a las estructura de la pila SS:BP.




    Pues sabes que te digo, que me has dejado flojo xd ¿?, que me quieres vender venga dimelo ya.

    Tranquilo mi ansioso lector ….........


    Ahora respiremos un poco xd.


    El tamaño de los registros puede ser de 16 o 32 bits en caso de ser 32 bits se le añade una E a el registro de 16.

    Ejemplo:

    AX 16 bit = EAX 32 bits

    Los registros de 16 bits se pueden dividir, se quitaría la X y se añadiría una H para los bits mas significativos AH 8 bits y se quitaría la X añadiendo la L para los 7 bits menos significativos AL.

    AH AL == AX



    La Pila;

    Voy a intentar explicar como se manejan la Pila, Digamos que este es un espacio en el que se pueden insertar datos y cuando los insertas el primero en meter es el ultimo en salir YA LA EMOS LIADO XD, esto utilizando tecnicismos se llama LIFO (Last in First Out), o utilizando el ingles tambien xd, bueno como se que no te has lee ido para que sirve el registro SP y BP (Vago!!!).

    SS:SP Apunta al principio de los datos, cuando introduces un dato SP se resta, eso significa que SP se encuentra detrás de la ultima variable introducida(Last in First Out) por eso es el principio xd.

    Ejemplo:
    -var -var -var
    VAR1,VAR2,VAR3 [ESP o SP] se resta tantos datos como contenga la variable.

    Ahora vamos a introducir otro dato como quedaría:

    VAR1,VAR2,VAR3,VAR4 [ESP o SP]

    Ahora quiero sacar una variable: SOPRESA SORPRESA SP + TANTOS bits como tenga el dato

    Vaya morro que tengo si entre la ultima<-------------VAR4

    VAR1,VAR2,VAR3 <---+ [ESP o SP]


    vamos a meter otra var

    VAR1,VAR2,VAR3,VAR5 [ESP o SP]

    yA Basta ¡No! esto parece alicia en el país de las maravillas xd.

    Y a todo esto donde estaba ebp, tomándose un café con el hombre de paja ¿?, y esto no va con segundas mal pensados xd.


    BP o EBP: esta apunta a la base de pila ummm vaya si ESP es el principio la base estara ummm dejame que piense (Se hace un largo vacio y se abre el telon)

    [EBP] VAR1,VAR2,VAR3 [ESP] oooo precioso a que si.

    Un ejemplo de como incializan la pila todas las funciones, aunque no lo entiendas lo puedes usar en una futura referencia:

    puhs EBP // push[mete en la pila EBP] ya tenemos la base, pero falta esp
    mov ebp,esp // mov[copia esp a ebp bien ya podemos insertar datos]

    Aclaracion:
    Ahora ebp y esp tienen la misma dirrecion de memoria, al insertar datos esp se restara y ebp segira donde esta.



    Puntero de instrucción;


    Esto es algo importante y claro lo explicare antes de que nos pille el toro, IP o Instruction Pointer, es un registro que junto al segmento CS indica la próxima instrucción a ejecutar CS:IP aplica un desplazamiento en la dirección base de CS, su valor se incrementa con cada nueva instrucción.


    Ejemplo:


    CS:1450:0000:IP MOV CX, DX

    CS:1450:0002:IP MOV AX, BX


    Lo veremos mas claro cuando utlilizemos el debug.





    Bueno aquí esta todo el tema 1, ya es vastante por hoy e intentado explicarlo como me hubiese gustado que me lo explicaran a mi la primera vez que me puse a informarme sobre asm.




    Aqui dejo la version odt y pdf
    http://www.mediafire.com/download.php?zsp0t37xx2j7caj



    Tema2:


    En este tema aprenderemos nuestra primera instrucción en ensamblador, esto son solo simples palabras mnemotecnias que al ser ensambladas desaparecen y quedan en lenguaje maquina, explicaremos estos pasos y el ensamblado y linkeo en masm 16 bits y 32 bits, aprenderemos varios de los modos de direccionamiento que nos permite la instrucción MOV.


    Indice


    1-Modos de direccionamiento

    2-Hola mundo en 16 bits

    3-Hola mundo en 32 bits


    Modos de direccionamiento:



    Si te leíste el tema anterior ya deberías saber lo que son los registros de uso general y sus segmentos, bien pues la finalidad de la instrucción mov es transferir los datos de la memoria a los registros de la cpu o viceversa.


    Direccionamiento por registro:


    Su nombre lo dice todo es la transferencia de un registro a otro, esto se hace dentro de la propia la cpu, es una transferencia rápida ya que no tiene que comunicarse con la memoria ram o otras.

    MOV AX, DX

    MOV Destino, Origen


    La información de DX se copia en AX esta pierde cualquier dato que tuviera anteriormente


    Forma incorrecta de Direccionamiento:



    MOV AX, EAX

    No se pueden intercambiar datos entre registros de diferentes tamaños en este caso AX es de 16 bits y EAX de 32 bits.


    MOV CS, DS

    No es posible el movimiento directo entre segmentos, para hacer algo así seria como el ejemplo que voy a poner a continuación.

    MOV AX, CS

    MOV DS, AX




    Direccionamiento inmediato:


    En este tipo de direccionamiento el operando de origen se encuentra en el propio código.


    MOV AH, 20h


    Atención esa h que hace hay ? Significa que este es un numero hexadecimal, si por ejemplo fuera binario se le añadiría una b detrás y claro no podría ser 20h seria
    100000b aunque dije que no entraba en este tema tengo que indicar la sintaxis:

    MOV AH, 100000b // binario 32

    MOV AH, 20h // hexadecimal 32

    MOV AH, 32 // decimal




    Direccionamiento directo:


    El origen y el destino es una dirección de memoria, en esta normalmente hay alguna dato por ejemplo una variable, normalmente se usan etiquetas para acceder a nuestra variable es una de las ventajas del ensamblador, que traduce esa etiqueta o nombre o como se quiera decir, a una dirección en el segmento DS en la que se puede escribir y leer.


    MOV AX, Variable

    Ahora si por ejemplo pongamos que esta variable esta en la dirección 1190h podríamos acceder a sus datos así:

    MOV AX, [1190h]

    Los corchetes son necesarios para indicar que es una dirección de memoria no un dato inmediato como el anterior, ahora ya podemos escribir o leer los datos de Variable.


    Direccionamiento indirecto:



    Es igual que el anterior pero no se indica la dirección directamente o mediante una etiqueta, si no que esta se almacena en un registro:


    MOV AX, [BX]

    Ahora vamos a poner que tenemos la dirección DS:1190h tenemos una estructura de datos aplicando un desplazamiento podríamos acceder a esos datos.

    MOV AX, [BX+4]


    DS:1190=desplazamiento=datos

    BX nos puede servir como puntero.




    Nuestro hola mundo en masm 16 bits:

    dseg segment

    Saludos db "Hola$"

    dseg ends

    sseg segment stack

    db 100h dup(?)

    sseg ends

    ; code
    cseg segment

    assume cs:cseg, ds:dseg, ss:sseg
    start:
    ; ... put your code here ...
    mov ax,seg dseg
    mov ds,ax
    mov dx,offset Saludos
    mov ah,9
    int 33

    ; exit to DOS
    mov ax, 4C00h
    int 21h

    cseg ends





    end start
    Vamos por partes, nuesto primer segmento DS:

    dseg segment

    Saludos db "Hola$"

    dseg ends

    Inicializa el segmento de datos con la palabra segment, (dseg) es solo un nombre de etiqueta, para incializar las variables es algo muy parecido a lenguajes de alto nivel se le da el nombre primero, en este caso seria Saludos, y se indica el tamaño de dato db los tipos de datos son:


    DB| WORD |Es una palabra 16 bits|

    DW| DWORD |Doble palabra 32 bits|

    DD| QWORD |Cuádruple palabra 64 bits|




    Bueno esto es variable depende que registros de datos estemos utilizando, por ejemplo un DB en un programa de 16 bits (como este) serian 4 bits de datos un DW serian 8 y un DD 16 bits.


    Ya para terminar introducimos la cadena Hola entre comillas y acabada en el símbolo del dólar, esto es así por sintaxis especifica de masm, ya tenemos nuestra variable ahora solo queda indicar el final del segmento de datos con ends.


    Vamos por partes, el segmento de Pila SS:



    sseg segment stack

    db 100h dup(?)

    sseg ends

    Aquí definimos el segmento de pila si se acuerdan era SS se reserva espacio para ella masm se encarga de incializar la pila el mismo, esto con otros ensambladores 16 bits no ocurre por lo cual masm es algo mas aconsejable para comenzar con este lenguaje, ya explique algo sobre la pila en el primer tutorial en siguientes capítulos profundizaremos mas, de momento vasta con saber que la pila es necesaria para que las interrupciones del dos se carguen.


    Vamos por partes, empezando con el segmento de codigo CS:


    cseg segment

    assume cs:cseg, ds:dseg, ss:sseg
    start:

    Empieza al segmento de código y con la directiva assume le dejemos el muerto a masm para que se maneje con los segmentos, con start empieza el verdadero código del programa es así como un main en C/C++, no lo dije antes pero es muy recomendable tener algún conocimiento sobre C/C++ para comprender ensamblador y sacarle verdadero partido, yo no me podría ni imaginar lo difícil que hubiese sido para mi, aprender ensamblador sin antes tener algún conocimiento sobre la programación en alto nivel.


    Vamos por partes, análisis de nuestro primer algoritmo en ensamblador:


    mov ax,seg dseg
    mov ds,ax
    mov dx,offset Saludos
    mov ah,9
    int 33

    ; exit to DOS
    mov ax, 4C00h
    int 21h

    cseg ends





    end start
    Para empezar vemos que tenemos que indicarle al segmento DS donde esta el segmento que contiene la variable saludo:

    mov ax,seg dseg
    mov ds,ax


    Basicamente incializamos el segmento DS donde le corresponde.

    Después guardamos en DX la dirección que dentro del segmento DS contiene la variable Saludo, esto es asi porque esta interrupción necesita que en DX estén los datos a imprimir, ya que es el registro que la interrupción utiliza.

    mov dx,offset Saludos



    offset significa desplazamiento le decimos que nos vamos a DS:Saludos.

    Llamamos a la interrupción y le indicamos que escogemos la opción 9 imprimir cadena de la interrupción 33 o 21h en hexadecimal:

    mov ah,9
    int 33


    Por ultimo devolvemos el control al sistema:

    mov ax, 4C00h
    int 21h


    Y terminamos el CS y la etiqueta start con ends.



    Ensamblado y linkeo:


    Bien todavía no sabemos como va esto, primero ensamblamos con un ensamblador obviamente xd, este crea un archivo obj el cual tiene una serie de directivas para el procesador que indica digamos como se debe crear y distribuir el código maquina, después con un linker o enlazador convertimos todo eso en código ejecutable.

    Bueno a ello vamos entramos mediante consola en la carpeta de utilidades suministrada por este menda y vamos a masm\bin escribimos ml /c ola.asm, ahora se generar un codigo .obj que se llamara ola, con /c le indicamos que no se autoenlaze con ningun linker, bueno ahora ya tenemos nuestro ola.obj, introducimos en consola DOSLNK, Objetc Modules [.obj]: ola.obj, pulsamos varias veces enter y ya tenemos nuestro ola.exe.....................


    Los 32 bits

    Las diferencias entre 32 bits el llamado modo protegido es que se ejecuta en un espacio de dirección plano, eso significa que no esta segmentado como los 16 bits, tambien que es mucho mas facil programar en el y mas rapido ya que no se tiene que segmentar la memoria.




    Hola mundo en 32 bits:

    .386
    .model flat,stdcall

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc

    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib

    .data

    Titulo db "Mi titulo",0
    Texto db "¡Hola Ventana!",0

    .code
    Main:

    invoke MessageBox, 0, offset Texto, offset Titulo, MB_OK
    invoke ExitProcess, 0

    end Main


    Vamos por partes:


    .386

    .model flat,stdcall
    Primero indicamos que vamos a utilizar el las el conjunto de instruciones del procesador en este caso es 368, con model flat indicamos el modelo de memoria flat plana es la unica que existe xd, y con stdcall indicamos el orden con el que se deven de manejar los paremetros de las funciones con la llamada call (esto lo veremos en capitulos proximos)



    Vamos por partes los Includes:


    include \masm32\include\windows.inc


    Lo que hace es incluir una serie de estructuras y datos para poder ejecutar las funciones de windows apis, utilizaremos include con nuestras propias funciones cuando entremos en el tema de la estructura de codigo.....


    includelib \masm32\lib\kernel32.lib



    Indica las librerías que se devén importar para utilizar las funciones de windows, se pueden indicar manualmente pero es tedioso xd.



    Vamos por partes, datos datos:


    .data

    Titulo db "Mi titulo",0
    Texto db "¡Hola Ventana!",0


    Estas son las directivas para dividir el código, como habrás deducido si leíste anteriormente esta es la sección de datos incializados, lo demás es pura sintaxis, también esta la directiva .DATA ? y .CONST xd me parece que toca tablita xd.

    |.DATA| Aquí se incializan tus datos variables xd.|

    |.DATA ?| En esta sección estan tus datos sin inicializar. Lo que es una variable con espacio vació para escribir.|

    |.CONST| Es una zona de memoria que no se puede modificar, vamos lo que es una constante de toda la vida.|

    |.CODE| Aquí incluimos nuestro algoritmo|



    Vamos por partes, EL CODIGO:



    .code
    Main:

    invoke MessageBox, 0, offset Texto, offset Titulo, MB_OK
    invoke ExitProcess, 0

    end Main




    Aquí tenemos a la instrucción invoke llamando y ejecutando las funciones de windows , ahora mismo no entenderéis muy bien esto, pero esta instrucción facilita mucho la llamada a las funciones ya que no se tiene que utilizar la pila, lo hace automáticamente no como call, todo esto ya lo veremos mas adelante, como ves se llama a la función y se le pasan los parámetros, típicos de una función de windows, terminando con exitProcess que devuelve el control a windows.




    Ey y el exe:



    ml /c /Cp /coff Mihola32.asm

    /c no queremos que se autoenlaze /Cp le decimos que respete las mayúsculas, /coff el tipo de sistema de archivos para windows.


    Link Mihola32.obj /SUBSYSTEM:WINDOWS

    /SUBSYSTEM:WINDOWS para utilizar la api.

    Pues ya tenemos nuestro exe BIEN.
    Y esto es todo por hoy
    by Chewarrior



    Aqui el Link con las utilidades y el 2 tutorial: Descarga Tuto 2 AQUI
    Última edición por chewarrior; 04-10-2011 a las 23:35
    René Pérez Joglar: Pa' tener a un listo que no dice nada prefiero a un idiota que hable mucho.
    Citar  
     

  2. #2  
    Co-Admin HackHispano.com Avatar de clarinetista
    Fecha de ingreso
    Jan 2004
    Ubicación
    HackHispano/SM
    Mensajes
    7.773
    Descargas
    31
    Uploads
    8
    No necesitabas presentacion, pero buen trabajo por el tuto.
    Citar  
     

Temas similares

  1. Respuestas: 5
    Último mensaje: 09-11-2011, 00:20
  2. Windows 7 32 bits o 64?
    Por Lemos en el foro WINDOWS
    Respuestas: 13
    Último mensaje: 02-11-2009, 14:59
  3. Respuestas: 7
    Último mensaje: 01-07-2009, 21:06
  4. Windows Subsistema 16 Bits. Ayuda!
    Por So_auron en el foro WINDOWS
    Respuestas: 2
    Último mensaje: 11-12-2005, 14:51
  5. Respuestas: 0
    Último mensaje: 23-09-2003, 21:08

Marcadores

Marcadores