Está en la página 1de 111

1

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o I :I n s t al a ci o n y C o n fi gu r a ci o n. Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

EL presente escrito,creado para fines educacionales e investigaci n. Es de libre distrubucion, siempre que se conserve intacto el contenido y se precise derechos de autor

[RVLCN]

[ Introducci n ]
RVLCN te da la bienvenida al curso de programaci n con MASM32 usando el IDE RadAsm, aqu aprender s a crear y dise ar tus propias aplicaciones en forma f cil y r pida. MASM32 ofrece una buena alternativa si quieres aprender a programar en ensamblador, tiene una gran cantidad de constantes, estructuras, y librer as que usaras al momento de programar, esto nos ahorra mucho tiempo al escribir nuestra aplicaci n, adem s que su sintaxis es agradable a comparaci n de otros compiladores en ensamblador. Este curso es 100% practico, cada capitulo contiene videos donde se puede observar como se programa, describiendo el proceso de programaci n, tambi n lo que no ha quedado claro o no esta descrito en el video se puede aclararlo en el documento respectivo de cada capitulo. Si tienes dudas, preguntas podr s hacerla en la lista MASm+Radasm, para que no quede nada inconcluso.

[ Agradecimientos ]
Gracias a hutch que constantemente actualiza y da soporte a MASM32, y tambi n ha kelitO por programar el mejor IDE (RadASM) para Assembler que nos facilita y nos ayuda al momento de programar nuestras aplicaciones.

[ Materiales ]
1.- Necesitamos el compilador MASM32 v9.0 o superior: Pagina Oficial: http://www.masm32.com/ Descargar compilador: http://website.assemblercode.com/masm32/m32v9r.zip Version 9. 2.- Necesitamos tambi n el IDE RADASM v 2.2.0 o superior: Pagina Oficial: http://www.radasm.com/ Descargar IDE : http://www.radasm.com/RadASM2000/RadASM.zip Descargar los Lenguajes de Programaci n: http://www.radasm.com/RadASM2000/Assembly.zip Descargar el idioma del IDE: http://www.radasm.com/RadASM2000/RadLNG.zip

3 3.-Necesitamos saber sobre las Funciones de Windows: Win32 Programmers Reference: http://www.rvlcnsecurity.com/clases/anexo/win32api.rar

[RVLCN]

4.- Para descomprimir los archivos puedes usar el WinZip o el Winrar: Winrar: http://www.rarlab.com/rar/wrar36b5.exe

[Instalaci n de Nuestro Compilador]


Descomprimimos nuestro archivo m32v9r.zip que hemos descargado y abrimos el instalador install.exe y muestra lo siguiente:

Fig.1 Elegimos en que disco duro queremos instalar, luego presionamos el bot n Start, para continuar la instalaci n y aparece el siguiente mensaje:

Fig. 2 Instala masm32 en la unidad C:\?, presionamos el bot n Si y muestra el siguiente mensaje:

Fig. 3

[RVLCN]

Esta instalaci n no esta hecha para correr sin supervisi n o en el background, realiza intensivas operaciones de procesador para construir las librer as y puede que no funcione correctamente o no cree las librer as si no es supervisada en baja prioridad. Presionamos el bot n Aceptar, y aparece la ventana para extraer los archivos:

Fig. 4 Procedemos a presionar el bot n Extract, y empieza la extracci n de los archivos:

Fig. 5 Una vez terminada la extracci n de sus archivos muestra una ventana en DOS:

Fig. 6 Presionamos la tecla ENTER y observamos como crea las librer as de las APIS de Windows necesarios para crear nuestros programas, despu s de que termina muestra la siguiente ventana:

[RVLCN]

Fig. 7 Volvemos a presionar la tecla ENTER, para continuar con la creaci n de librer as:

Fig.8 Listo se termino de crear todas las librer as, volvemos a presionar la tecla ENTER:

[RVLCN]

Fig. 9 Instalaci n Exitosa , volvemos a presionar la tecla ENTER para que termine la instalaci n:

Fig. 10 SI se desea aceptamos el mensaje, sirve para instalar el qeditor.exe que para nosotros es obsoleto. Ya tenemos el compilador Instalado y listo para programar, pero para ello vamos a instalar el IDE RadAsm.

[ Instalaci n del IDE RADASM ]


Extraemos el archivo RadASM.zip presionando el clic derecho del Mouse:

[RVLCN]

Fig. 11

Fig. 12 Seleccionamos el disco duro donde queremos extraer los archivos en mi caso he elegido C:\. Damos clic al bot n Aceptar. Luego debemos extraer el paquete de lenguajes de programaci n Assembly.zip y tambi n extraemos el paquete de Idioma RadLNG.zip en la misma carpeta donde tenemos el RadAsm en mi caso es C:\RadAsm:

[RVLCN]

Fig.13 Como se observa en la Fig.13 estamos en el directorio assembly donde debemos copiar el archivo masm.ini y la carpeta \MASM, para pegarlo en el directorio de RadAsm como muestra la siguiente figura:

Fig. 14 Luego abrimos el RadASM.exe, para configurar el idioma y agregar el lenguaje de programaci n: Para agregar el Lenguaje de programaci n debemos ir al Option/Programming Languages, como muestra la siguiente imagen: men

Fig. 15 Damos Clic y sale una ventana para agregar el lenguaje de programaci n:

[RVLCN]

Fig. 16 Damos clic en el bot n marcado con rojo y sale una ventana para abrir solo archivos con extensi n *.ini y seleccionamos el archivo masm.ini:

Fig.17 Damos clic en el bot n Abrir y observamos que se ha habilitado el bot n add (Agregar Fig.16) y como ultimo paso presionamos el bot n OK (Fig.16). Para cambiar a nuestro idioma espa ol, nos vamos al men Option/language, como muestra la imagen siguiente:

10

[RVLCN]

Fig. 18 Damos clic y muestra la ventana de idiomas as que seleccionamos el espa ol como muestra la imagen siguiente:

Fig. 19 Presionamos el bot n Apply (Aplicar), y luego el bot n OK. Si Usted ha instalado el Masm32 en otra Unidad por ejemplo la D:\ debemos configurar la ruta, para que pueda compilar los programas que escribimos, para ello nos dirigimos al men Opciones/Fijar Rutas:

Fig. 20

11

[RVLCN]

Al hacer clic en esa opci n aparecer una ventana para configurar la carpeta donde esta instalado el compilador, si tenemos el Masm32 en la unidad D:\ debemos configurar de esta manera:

Fig. 21 Luego damos clic en el bot n Aplicar y luego el bot n Ok Ya terminamos de instalar y configurar todo, ya estamos listo para empezar a aprender programaci n en MASM32+RadAsm.

[ Optimizando Instalaci n ]
Para una instalaci n mucho m s r pida que la anterior te recomiendo el [RVLCN]_InstRApiMAsm_RadASm.rar lo puedes descargar de:
http://www.rvlcnsecurity.com/clases/anexo/RVLCN_InstRApiMAsm_RadASm.rar

Una vez descargado descomprimimos el archivo y damos doble clic en [RVLCN]-InstRApiMAsmRad.exe y muestra lo siguiente:

12

[RVLCN]

Fig. 22 Si quieres instalar en otra unidad presionamos el bot n marcado con azul, y si deseamos instalar el RadAsm activaremos la casilla marcada con negro, luego damos clic en el bot n Instalar (marcado con amarillo). Radasm Se instala en la misma carpeta donde hemos instalado masm32, por ejemplo:

Ya no es necesario configurar el RadAsm, ya esta listo para trabajar con el.

[ Recordatorio ]
Si tienes Dudas, sugerencias, otros, hacerlas en lista.

13

[RVLCN]

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com http://RVLCNsecurity.com http://beam.to/RVLCN http://beam.to/REVOLUCION
Julio-2006

Copyright(c) 2005-2006 RVLCN

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o I I :N u e str a Pr i me r a A p l i c ac i o n. Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

El presente escrito, creado para fines educacionales e investigacion. Es de libre distribucion, siempre que se conserve intacto el contenido y se precise derechos de autor.

[RVLCN]

[ Estructura de nuestros Programas]


Para crear un programa en MASM32 se debe seguir una estructura que pueda entender nuestro compilador por ejemplo: .386 .model flat, stdcall option casemap:none include windows.inc include kernel32.inc includelib kernel32.lib .data .code Prog001: invoke ExitProcess,0 end Prog001 Con ese c digo ya hemos creado un programa que pueda entender nuestro compilador y as crear nuestra aplicaci n, ahora explicare para que sirve cada una de las secciones del c digo: .386.- Esta directiva sirve para establecer el tipo de procesador y sus instrucciones con lo que se va a trabajar, en esta caso 80386. .model flat, stdcall.- Aquestablecemos el modelo de memoria requerido para nuestros programas de 32 bits. option casemap:none.- Esta opci n hace sensible las may sculas de las min sculas es decir que por ejemplo Z es diferente a z. Include y Includelib.- MASM32 incluye archivos y librer as para manejar un gran numero de funciones que existen en Windows, a estas funciones se les llama APi, como por ejemplo la API ExitProcess que esta en nuestro c digo. El include se utiliza para agregar archivos con extensi n .inc y .asm El includelib se utiliza para agregar librer as con extensi n .lib MASM32 tambi n incluye el archivo window.inc donde encontramos un gran numero de constantes y estructuras usadas por las funciones de Windows (API). .data.- Existen dos tipos de informaci n, la informaci n inicializada y la no inicializada (.data?).

[RVLCN]

1.- Informaci n Inicializada (.data).- En esta secci n declararemos los datos que conocemos con los que inicia nuestro programa por ejemplo: .data Etiqueta MsgTexto Valor_1 Tipo de variable db dd Datos inicializados BiENVENIDO AL CURSO DE MASM + RADASM,0 7

2.- Informaci n No Inicializada (.data?).- En esta Secci n declararemos los datos que no conocemos o que vamos a escribir cuando el programa se ejecute usualmente lo utilizamos para almacenar datos, por ejemplo: .data? Etiqueta Buffer Valor_1 Tipo de variable db dd Datos No inicializados 128 dup (?) ?

.code.- Despu s de la secci n de datos debes indicar a MASM32 donde empieza el c digo del programa y tambi n donde termina, para ello he puesto la etiqueta Prog001 seguido de :, para indicarle que abajo empieza el c digo de nuestro programa, y al terminar el c digo del programa se escribe end mas la etiqueta que hemos declarado quedando de esta manera: end Prog001.

[ Programando en RadAsm]
1.- A nuestro c digo anterior implementaremos una nueva funci n para que muestre una ventana que nos de la bienvenida, para ello abrimos el RadAsm.exe, y comencemos programar como muestra el video:

Prog001.exe

[RVLCN]

[ Explicando el video Prog001.exe]


En nuestro programa que hemos desarrollado se ha utilizado 2 funciones: MessageBox ExitProcess Si abrimos nuestra documentaci n de las Apis de Windows (Win32 programmer s Reference) y buscamos la funci n MessageBox encontramos lo siguiente: int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType ); HWND.- Este parmetro sirve para identificar el manejador de la ventana padre, nuestro caso colocamos NULL 0 por que no tiene manejador (handle). LpText.- Aqucolocamos la direcci n donde se encuentra nuestro mensaje. LpCaption.- En este parmetro funciona igual que lpText la diferencia que este es el titulo del mensaje uType.- Este parmetro es muy til al momento de crear nuestra ventana sirve para personalizar nuestro mensaje. Podemos especificar que tipo de botones deseamos y tambi n el icono, por ejemplo en nuestro programa se ha puesto las siguientes constantes: Botones Icono Estas constantes estn declaradas en el archivo window.inc MB_OK MB_ICONINFORMATION Para saber ms sobre esta funci n le sugiero que revise la documentaci n que mencione anteriormente. Todo programa que escribimos en MASM32 debemos colocarle la siguiente funci n: VOID ExitProcess( UINT uExitCode );

[RVLCN]

Con esta funci n cerramos nuestro programa, en el parmetro uExitCode se especifica el c digo de salida, en nuestro caso se ha puesto 0. invoke.- MASM32 tambi n tiene un sintaxis de alto nivel, que nos facilita llamar a nuestras funciones de forma correcta, es decir que al momento de compilar MASM32 comprobara si los parmetros de nuestra funci n son los correctos y se emplea de esta manera: INVOKE FUNCION, Argumentos FUNCION.- Es aqudonde escribiremos el nombre de la funci n que se va ah utilizar. Argumentos.- Los argumentos son los parmetros de las funciones y estn separadas por comas ,. 1.-Operadores en el archivo prog001.asm: addr.- Este operador sirve para pasar la direcci n de nuestra etiqueta hacia nuestra funci n por ejemplo las etiquetas MsgTexto y MsgTitulo. offset.- Es similar al addr pero con algunas diferencias como muestra el siguiente cuadro. addr No puede ser utilizado con instrucciones mnemonic Trabaja Solo con referencias que est n delante del c digo. Puede operar con estructuras. 2.-Operadores en el archivo prog001.inc: Windows tiene una gran cantidad de APi en nuestro sistema que son empleados por todos los programas de Windows, y estas APi o funciones la encontramos en las librer as de enlace dinmico (dynamic-linked libraries DLL), como por ejemplo: user32.DLL, kernel32.DLL, shell32.DLL, y nosotros para poder usar las funciones en nuestros programas necesitamos agregar 2 archivos para cada librer a: user32.inc y kernel.inc.- En estos archivos encontramos todas las funciones declaradas que pertenecen a user32.dll y kernel32.dll respectivamente, esto nos ahorra tiempo al momento de programar por que nos evita estar declarando las funciones que vamos a emplear, pero observemos su contenido para ver que contiene, para ello debemos abrimos los archivos .inc: Para abrir el archivo se alamos el nombre del archivo .inc que queremos abrir y presionamos el bot n derecho del Mouse, se despliega un men contextual donde hacemos clic a la opci n Abrir, como muestra la siguiente imagen: offset Se utiliza con instrucciones mnemonic Trabaja con referencias que est n delante y atrs del c digo. No puede operar con estructuras.

[RVLCN]

Fig. 1 Luego se abre una nueva ventanita en el RadAsm mostrando lo siguiente:

Fig. 2

[RVLCN]

Buscaremos nuestra API MessageBox presionando las teclas CTRL + F y escribimos la funci n que vamos a buscar, como muestra la siguiente imagen:

Fig. 3 Luego damos clic en el bot n hallar y encontramos lo siguiente:

Fig. 4 Ya hemos encontrado nuestra funci n y comprobado que esta API esta declarado en el user32.inc, si buscamos la otra API que hemos utilizado ExitProcess no lo encontraremos por que esa API esta en Kernel.inc. user32.lib y kernel.lib.- Para que nuestro programa se pueda enlazar a las librer as de uso dinmico de Windows, necesita informaciones como el nombre de la funci n y la direcci n donde se encuentra, para que al momento de ejecutar nuestro programa cargue la Liberia inmediatamente. Esta informaci n que he mencionado se encuentra en los archivos .lib.

[ Variables ]
Tipo BYTE WORD DWORD FWORD REAL4 QWORD REAL8 TBYTE REAL10 Tipos de Variables Abreviatura Espacio DB 1 byte 8 bits DW 2 bytes 16 bits DD 4 bytes o 32 bits DF 6 bytes o 48 bits DQ 8 bytes o 64 bits DT 10 bytes o 80 bits Descripci n Cadenas de texto y caracteres Valor entero en el rango: -32, 786 a +65, 535 Valor entero en el rango: -2gb a +4gb 48 bit con punto flotante 64 bit con punto flotante 80 bit con punto flotante

[RVLCN]

Veamos unos ejemplos de c mo se debe declarar las variables ( en la secci n .data y en .data?): EJEMPLO EN DATOS INICIALIZADOS .data Cadena db Valor dd Punto df .data Cadena Valor Punto BiENVENIDO AL CURSO DE MASM + RADASM,0 77 4.575 Que viene hacer lo mismo : BiENVENIDO AL CURSO DE MASM + RADASM,0 77 4.575

BYTE DWORD REAL4

EJEMPLO EN DATOS NO INICIALIZADOS .data? Acumulador db Contador dd FlotanteP df .data? Acumulador Contador FlotanteP ? ? ? Que viene hacer lo mismo : BYTE DWORD REAL4 ? ? ?

[ Creando plantilla en RaDAsm ]


El programador de Radasm ah pensado en todo y para no volver a escribir toda la estructura de nuestros programas cada vez que queremos programar, crearemos una plantilla como lo hago en el siguiente video:

[RVLCN]

Creando Plantilla.exe Si queremos ir a la carpeta donde esta nuestro c digo fuente abrimos el men Proyecto/Explorar Path como muestra la imagen:

Fig. 4 Y abre la carpeta donde tenemos nuestro c digo fuente:

10

[RVLCN]

Fig.5 2.- En el ejercicio anterior se ha utilizado los datos inicializados, ahora falta crear un ejemplo utilizando los datos no inicializados:

Prog001a.exe Se ha utilizado en el ejemplo Prog001a la funci n GetModuleFileName y se declara de la siguiente manera: Librer a Kernel32.lib

GetModuleFileName,NULL,addr Buffer,225
Esta funci n extrae el directorio ms el nombre de la aplicaci n, y la devolver en la variable Buffer, si ya fue ocupada la modificara y pondr nuevos caracteres, el valor 225 significa la longitud mxima de caracteres que va a devolver. Buffer cumple la funci n de almacenador de datos, donde almacenara la cadena de texto devuelta por la funci n que sea utilizado.

11

[RVLCN]

3.- Hagamos nuestro programa ms grande y un poco ms complejo para el siguiente ejemplo, para ello utilizaremos la librer a masm32.lib. Masm32 tiene su propia librer a donde podemos encontrar muchas funciones tiles que muchas veces necesitamos y no la tomamos en cuenta, en el siguiente video utilizaremos algunas de estas funciones, para ello Vamos a Crear un programa que muestre el directorio en un mensaje y en otro mensaje el nombre de la aplicaci n que se esta ejecutando:

prog002.exe

[ Funciones Utilizadas video prog002.exe ]


Librer a MAsm32.lib

GetAppPath,addr Buffer
Esta funci n devuelve el directorio de la aplicaci n y lo ara en la variable que hemos puesto en este caso Buffer y se quedara almacenado hasta que otra funci n remplace el dato que contiene la variable. Librer a MAsm32.lib

NameFromPath,addr Buffer,addr NombreApp


Como sabemos Buffer contiene el nombre mas el directorio de la aplicaci n por que ya fue utilizada por la API GetModuleFileName , y la funci n NameFromPath extraer solo el nombre y la almacenara en la variable NombreApp.

12

[RVLCN]

Operador DUP.- significa duplicaci n, se utiliza para separar espacios en la memoria y su sintaxis es de esta manera: Sintaxis: Contador dup (valor inicial) En contador escribimos el tama o que vamos a duplicar, y el valor inicial lo escribimos dentro del par ntesis si se pone el signo ? significa que es un valor indefinido. En nuestro c digo se ha declarado de la siguiente manera: Etiqueta Buffer NombreApp Variable db db Contador 225 50 DUP dup dup Valor Inicial (?) (?)

Y significa lo siguiente: En la variable Buffer se ha separado 225 bytes en la memoria y en la Variable NombreApp se ha separado 50 bytes en la memoria. Recomiendo que si se va ha utilizar una variable para almacenar todo tipo de cadenas de texto devueltas por las funciones, las variables declaradas tengan un espacio considerable a lo que se va obtener. Te preguntaras por que se hace esto, pues cuando utilices ms variables en tu c digo, si no le has separado un espacio considerable en la memoria a dicha variable que vas ha utilizar, la cadena de texto devuelta muchas veces invade las otras variables y esto te puede ocasionar problemas.

[ Ejercicio ]
Utilizando la ayuda Win32 programmer s Reference, para saber el uso y parmetros que corresponden a las funciones haga estos ejercicios: 1.- Crear nuevos mensajes, utilizando la API MessageBox, ejemplo prog001a:

Fig.6 2.- En el programa anterior agr gale la API MessageBeep, en el lugar donde usted quiera.

13

[RVLCN]

3.- Cree un programa que muestre el directorio de Windows en un mensaje y


despu s debe mostrar el directorio del sistema en otro mensaje, utilice las funciones: GetWindowsDirectory y GetSystemDirectory

[ Vocabulario ]
API (Application Programming Interface).- Interfaz de Programaci n de Aplicaciones, son funciones de uso general que se encuentran en nuestro sistema Windows, y estn almacenadas en librer as como por ejemplo user32.dll y kernel32.dll. Sintaxis.- Es una forma de combinaci n de las palabras seg n las reglas establecidas por el lenguaje de programaci n. Mnemonic (Nem nico).- En el lenguaje ensamblador, las instrucciones se representan por nem nicos o combinaciones de las letras que recuerdan el significado de la instrucci n en ingles.

[ Recordatorio ]
No olvidar preguntar en la lista MASM32-RadASM, las soluciones de estos ejercicios sern enviados a la lista dentro de una semana, tambi n puedes enviar tus propias soluciones. Si tienes Dudas, sugerencias, otros, tambi n hacerlas en lista.

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com http://RVLCNsecurity.com http://beam.to/RVLCN http://beam.to/REVOLUCION

Julio-2006
Copyright(c) 2005-2006 RVLCN

[RVLCN]

C l a ses de P r o gr a m a c iO n C O N M A SM + Ra da sm
C a pi tu l o I I I :R e g i s tro s de lM i c ro Pro c e s a do r Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

El presente escrito, creado para fines educacionales e investigacion. Es de libre distribucion, siempre que se conserve intacto el contenido y se precise derechos de autor.

[RVLCN]

[ Registros del Microprocesador ]


Nuestro procesador necesita registros para almacenar datos, y pueden ser utilizados libremente. Entre los principales registros tenemos: Registros de Prop sitos generales. Son 4 registros EAX, EBX, EDX, ECX y se emplea para uso general, y se subdividen en: EAX, EBX, ECX,EDX (32 bits ) AX, BX, CX, DX (16 bits) AH, BH, CH, DH (8 bit, H = Hight ). AL, BL, CL, DL (8 bit L = Low).

Ejemplo EAX = 12345678 AX = 5678 AH = 56 AL = 78 El procesador 80368 permite el uso de estos registros: EAX, EBX, ECX, EDX que son de 32 bits. Registros de uso general EAX (Acumulador) Descripci n

Es utilizado para operaciones aritmticas (suma, resta, divisi n, multiplicaci n). Algunas Funciones despus de ser utilizadas devuelven un valor a EAX. EBX (Base) Se utiliza para direccionar el acceso a datos, situados en la memoria, tambin se puede utilizar para operaciones aritmticas. ECX (Contador) Se utiliza como contador por algunas instrucciones, tambin es utilizado para operaciones aritmticas. EDX (Datos) Algunas operaciones de entrada/salida requieren su uso, y las operaciones de multiplicaci n y divisi n con cifras grandes suponen al EDX y al EAX trabajando juntos. Puede usar los registros de prop sitos para suma y resta de cifras de 8, 16, 32 bits. Registros de Indice Descripci n ESI El registro ndice de 16 bits es requerido por algunas operaciones con cadenas (de caracteres). EDI El registro ndice destino tambin es requerido por algunas operaciones con cadenas de caracteres. Registro de banderas Descripci n Se usa para registrar la informaci n de estado y de control de las operaciones del microprocesador, y son 9, CF, OF, ZF, SF, PF, AF, DF, IF, TF.

[RVLCN]

[ Instrucciones del Microprocesador ]


Las instrucciones son secuencias de bits (unos y ceros), e indican que operaci n debe hacer y con que dato se debe realizar la operaci n, por ahora veremos 11 instrucciones: MOV (Mover) Destino Fuente

Esta instrucci n MOV significa mover y se encarga de pasar el contenido del operando Fuente al de Destino. En la programaci n debemos respetar las siguientes reglas: Destino.- Puede ser variables y registros de 8, 16 y 32 bits. Fuente.- Puede ser variables, registros de Windows y valores enteros. ADD (Suma) Destino Fuente

La instrucci n ADD significa Suma. Suma el contenido de los dos oper ndos y el resultado es remplazado en el operando Destino. Destino.- Puede ser variables y registros de 8, 16 y 32 bits. Fuente.- Puede ser variables, registros de Windows y valores enteros. SUB (Resta) Destino Fuente

La instrucci n SUB significa Resta. Resta el contenido del operando Fuente con la de Destino y el resultado es almacenado en el operando Destino. Destino.- Puede ser variables y registros de de 8, 16 y 32 bits Fuente.- Puede ser variables, registros de Windows y valores enteros. INC (Incrementa 1) DEC (Decrementa 1) Destino Destino

Estas instrucciones incrementas y decrementan respectivamente el valor contenido en el operando Destino. Destino.- Puede ser variables y registros de 8, 16 y 32 bits. PUSH (Guarda) Fuente

PUSH se encarga de guardar el contenido del operando Fuente, en la Pila. Fuente.- Puede ser variables, valores enteros y registros de 16 y 32 bits.

[RVLCN]

POP (Recupera)

Destino

Al contrario de PUSH, esta instrucci n recupera el contenido guardado en la pila. Destino.- Puede ser variables y registros de 16 y 32 bits. Cuando se guarda varios valores con la instrucci n PUSH y si se quiere recuperar se utiliza la instrucci n POP, respetando la siguiente regla: Ultimo en guardar y primero en recuperar fica) para Instrucciones L gicas: Utiliza la calculadora de Windows (modo cient pasar en los sistema decimal, hexadecimal y binario las cantidades expresadas. AND Destino Fuente

Realiza la operaci n L gica AND entre los oper ndos Fuente y Destino de bit a bit, y el resultado es remplazado en el operando Destino. TABLA DE VERDAD AND A B Resultado 0 0 0 0 1 0 1 0 0 1 1 1 Ejemplo: 1110 (14 en decimal o E hexadecimal). 1101 (13 en decimal o D hexadecimal). 1100 (12 en decimal o C hexadecimal). OR Destino Fuente

Realiza la operaci n l gica OR inclusiva entre los oper ndos de bit a bit, y el resultado es remplazado en el operando Destino. TABLA DE VERDAD OR A B Resultado 0 0 0 0 1 1 1 0 1 1 1 1

5 Ejemplo: 1110 (14 en decimal o E hexadecimal). 1101 (13 en decimal o D hexadecimal). 1111 (15 en decimal o F hexadecimal). NOT Destino

[RVLCN]

La instrucci n NOT invierte los bits en el operando Destino. TABLA DE VERDAD NOT A Resultado 1 0 0 1 Ejemplo: 1101 (13 en decimal o D hexadecimal). 0010 (2 en decimal). XOR Destino Fuente

Realiza la operaci n l gica XOR exclusiva entre los oper ndos bit a bit, y el resultado es remplazado en el operando Destino. TABLA DE VERDAD XOR A B Resultado 0 0 0 0 1 1 1 0 1 1 1 0

Ejemplo:

1110 (14 en decimal o E hexadecimal). 1101 (13 en decimal o D hexadecimal). 0011 (3 en decimal).

Todas las operaciones l gicas que hemos visto tienen la siguiente regla: Fuente.- Puede ser variables, valores y registros de 16 y 32 bits Destino.- Puede ser variables y registros de 16 y 32 bits.

[ Ejercicios Con Instrucciones]


Abrimos el archivo prog002a con nuestro IDE RadAsm donde encontramos lo siguiente: En el archivo .INC hemos declarado la variable Valor_1 tipo DD

6 prog002a: ;##################[Operaciones Aritm ticas]################ MOV EAX,444 ; EAX = 444 ADD EAX,333 ; EAX = 444 + 333 = 777 MOV Valor_1,EAX ; Movemos el Resultado en la ; variable Valor_1 = EAX = 777 MOV EBX,15Dh ; EBX = 15Dh MOV EAX,20Ch ; EAX = 20Ch ADD EAX,EBX ; EAX = 20Ch + EBX = 15Dh = 369h PUSH EBX ; Guardamos el contenido del Registro EBX = 15Dh ; en la Pila. DEC EAX ; Decrementamos 1 a EAX = 369h - 1 = 368h INC EBX ; Incrementamos 1 a EBX = 15Dh + 1 = 15Eh SUB EAX, EBX ; Restamos EAX = 368h - EBX = 15Eh = 20Ah POP EBX ; Recuperamos el contenido de la Pila al ; registro EBX SUB EBX,10 ; Restamos EBX = 15Dh - 10 =153

[RVLCN]

Cuando se quiere declarar n meros en Hexadecimal debemos escribir el car cter h al final del valor, si no hay ning n car cter al final significa que es decimal. ;##################[Operaciones L gicas]################ MOV EAX,12 ;12 = 1100b MOV EBX,11 ;11 = 1011b AND EAX,5 ; EAX=12 (1100b) And 5(0101b) = 4 (0100b) OR EAX,EBX ; EAX= 4(0100b) OR EBX 11(1011b) = F(1111b) OR EBX,1101b ;EBX = 11(1011b) OR 13(1101b) = F(1111b) XOR EAX, EBX ;EAX = F(1111b) XOR EBX = F(1111b) = 00000 PUSH -2 ; Guardamos en la Pila el valor -2 POP EBX ; Recuperamos el Valor Guardado en la pila ; En el registro EBX NOT EBX ; NOT EBX = -2 = 1 Cuando se quiere declarar n meros binarios debemos escribir el car cter b al final del valor entero. En Las Operaciones l gicas si desean comprobar los resultados pueden verificar la tabla de verdad correspondiente a cada operaci n. 1.- En el programa anterior es solo un ejemplo de usar apropiadamente las instrucciones, ahora debemos darle sentido a nuestro programita: Tenemos 5 valores enteros: 1.- 1Ah 2.- 500 3.- 1C2h 4.- 13h 5.- 200

7 Haremos un programa que haga la siguiente operaci n: 1Ah + 500 = X El resultado X restamos 1C2h: X 1C2 = Y

[RVLCN]

Guardamos el resultado Y en la pila o en una variable, y luego sumaremos las cantidades que todav a no utilizamos de esta manera: 13h + 200 = Z Recuperamos el resultado Y, y lo restamos con la cantidad del resultado Z, el resultado final debe ser almacenado en el registro EAX. Soluci n 1 prog002b.- En el archivo .inc declaramos la variable Y tipo DD. prog002b: mov eax,1Ah ; EAX = 1AH add eax,500 ; EAX = 1Ah + 500 = 526 sub eax,1C2h ;EAX = 526 1C2 = 76 mov Y, eax ;Y (variable) = EAX = 76 mov eax, 13h ; EAX = 13H add eax,200 ; EAX = 13H + 200 = 219 sub eax ,Y ; EAX = 219 - Y (76) = 143 El resultado final es EAX =143. Soluci n 2 prog002c.- todas las cantidades est n declaradas en el archivo .inc de nuestro programa donde: Valor_1 DD 1Ah Valor_2 DD 500 Valor_3 DD 1C2h Valor_4 DD 13h Valor_5 DD 200 prog002c: mov eax,Valor_1 ; EAX = 1Ah add eax,Valor_2 ; EAX = 1Ah + 500 = 526 sub eax,Valor_3 ;EAX = 526 1C2 = 76 push eax ; Guardamos en la pila el contenido de EAX = 76 mov eax,Valor_4 ; EAX = 13H add eax,Valor_5 ; EAX = 13H + 200 = 219 pop ebx ; Recuperamos el contenido de EAX en EBX = 76 sub eax,ebx ; EAX = 219 - Y (76) = 143 Hay muchas soluciones no solo son estas dos, usted si quiere aprender mas debe desarrollar su propia soluci n.

[RVLCN]

[ Mostrando Resultados ]
En nuestro c digo anterior no mostramos el resultado de la operaci n aritmtica, para ello debemos saber las siguientes funciones de conversiones del masm32.lib Librer a MAsm32.lib

atodw,addr Numero_decimal
Esta funci n convierte cadenas de texto (cantidades decimales), a su valor entero, la cantidad convertida ser devuelta en EAX. Ejemplo: .data Numero_decimal db 10,0 .code Invoke atodw,addr Numero_decimal mov ebx, eax ;EAX contiene el valor entero 10 o Ah Librer a MAsm32.lib

htodw,addr Numero_Hexadecimal
Esta funci n es similar a atodw pero trabaja con cantidades hexadecimales, y la convierte a su valor entero, la cantidad convertida ser devuelta en EAX. Librer a MAsm32.lib

dwtoa,Cantidad,addr Numero_Convertido_decimal
Esta funci n convierte valores enteros en cadenas de texto decimal, seria lo contrario de la funci n atodw.

Cantidad.- En este par metro se puede utilizar variables, valores enteros y


registros de Windows. Ejemplo: Caso1.- valor entero:

Invoke dwtoa,12, addr Numero_Convertido_decimal


Caso2.- Variables tipo DD: Invoke dwtoa, Valor_1, addr Numero_Convertido_decimal Caso2.- Registros de Windows: Invoke dwtoa, EAX, addr Numero_Convertido_decimal

9 Librer a MAsm32.lib

[RVLCN]

dw2hex, Cantidad,addr Numero_Convertido_Hex


Esta funci n contiene los mismos par metros de la funci n dwtoa, con la diferencia que el resultado es una cantidad de texto hexadecimal, viene hacer lo contrario de la funci n htodw. En los siguientes ejemplos utilizaremos todas las funciones mencionadas, presta mucha atenci n cada detalle. 1.- En el ejercicio anterior mostraremos el resultado en decimal y Hexadecimal en un mensaje:

2.- Haremos un programa que sume cadenas de texto con cantidades decimal y hexadecimal, al final debe mostrar el resultado:

prog003.exe

10

[RVLCN]

En el ejemplo (prog003.exe), observamos que tenemos cantidades en decimal y hexadecimal (cadenas de texto), y luego para sumar dichas cantidades convertimos a valores enteros con las funciones atodw y htodw para que podamos operar con las instrucciones de procesador como la de sumar (ADD) y mover (MOV), luego para mostrar el resultado debemos convertir los valores enteros a cadenas de texto con las funciones dwtoa y dw2hex respectivamente: Esquema de trabajo:

Veamos otro ejemplo de conversiones, recuerda siempre estar atento a cada detalle del video:

prog003a.exe

Se ha trabajado directamente con valores enteros declarados en nuestro archivo .inc, cuyas cantidades hemos sumado, luego para mostrar el resultado hemos convertido en cadenas de texto dwtoa y dw2hex, respectivamente.

11 Esquema de trabajo:

[RVLCN]

Eso tenemos en cuento a conversiones de valores enteros a cadenas y viceversa Nota: Nunca podemos mostrar valores enteros, para hacerlo debemos convertir a cadenas de texto.

[ Creando Tus propias Funciones ]


1.- Ahora crearemos una funci n que muestre un mensaje, esta funci n tendr un par metro donde ira la direcci n de la etiqueta del mensaje, dentro de la funci n que vamos a crear se encontrara la APi MessageBox que ser el encargado de mostrar el mensaje.

prog004.exe

12

[RVLCN]

Como observamos en el video primero declaramos la funci n que vamos a utilizar: Funcion PROC MsgT:DWORD invoke MessageBox,NULL,MsgT,addr MsgTitulo, \ MB_OK + MB_ICONINFORMATION RET Funcion endp PROC.- Esta directiva sirve para definir un procedimiento o llamado que se va ha utilizar y su sintaxis es as : Nombre_Funcion PROC Argumento/s (si lo hubiera) RET Nombre_Funcion endp Si nuestra funci n necesita un par metro su sintaxis seria as : Nombre_Funcion PROC Parametro01: Tipo de variable RET Nombre_Funcion endp Si en nuestra funci n necesitamos m s de 1 par metro, es necesario separar por , (comas) cada par metro de esta manera: Nombre_Funcion PROC Prmtr01: Tipo de variable, Prmtr02: Tipo de variable, etc RET Nombre_Funcion endp Tipo de variable.- Aqu declaramos la longitud de bytes que se necesita ya sea DWORD, WORD, BYTE, por lo general siempre se declara la variable que tenga mayor longitud como DWORD. Nombre_Funcion.- Aquescribimos nuestra etiqueta para el nombre de la funci n, recuerda que esta etiqueta no debe repetirse y la etiqueta de los par metros no deben ser declaradas en otra parte del c digo. RET (retorno) N Bytes

Con esta Instrucci n regresamos del procedimiento que hemos llamado tambin lo utilizamos para separar nuestros c digos, como en el primer RET

13

[RVLCN]

que esta debajo de la funci n ExitProcess, en el operando N Bytes opcional ah se especifica cuantos bytes debe retornar.

es

Otro punto importante es que si utilizamos algunos de las variables que hemos declarado en los par metros del procedimiento de la funci n como por ejemplo MsgT ya no es necesario utilizar addr u offset, como por ejemplo la variable que he utilizado en el 3er par metro de la Api MessageBox: invoke MessageBox,NULL,MsgT,addr MsgTitulo, \ MB_OK + MB_ICONINFORMATION Ya hemos creando nuestra funci n, y si queremos utilizarla con la directiva invoke como lo hicimos en el video: invoke Funcion,addr MsgTexto Es necesario declarar los prototipos con la directiva PROTO. PROTO.- Sirve para definir los prototipos de las funciones para que se pueda usar el invoke, tambin informa a MASM el n mero de argumentos y el tipo de variable que debe emplearse al momento de llamar a la funci n, su sintaxis es de esta manera: Nombre_Funcion PROTO Argumento/s (si lo hubiera) Es similar a la directiva PROC y es por que trabajan juntos pero la diferencia es que solo se declara tipo de variables, el n mero de variables que declaramos depende de los par metros de la funci n por ejemplo: invoke Funcion,addr MsgTexto Solo contiene un par metro y lo definimos de esta manera: Funcion PROTO :DWORD Si nuestra funci n tuviera m s de un par metro se declara las variables separados por , (coma) por ejemplo la funci n MessageBoxA que esta en el archivo user32.inc cuando nosotros la utilizamos nos damos cuenta que tiene 4 par metros: MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD Nota.-No olvides que se debe respetar las may sculas y las min sculas cuando nos referimos a la cualquier variable o l nombre de la funci n, por que si no lo haces al momento de compilar masm32 nos devolvererror.

14

[RVLCN]

2.- Crearemos una funci n que reste 2 cantidades, y adem s al regresar de la funci n el resultado debe ser devuelto al registro EAX y al final debe mostrar el resultado en decimal.

Prog004a.exe Dentro de nuestra funci n Resta, hemos puesto 2 instrucciones para poder restar dichas cantidades, nosotros ya sabemos como se utiliza estas instrucciones por lo cual esta de mas explicarlo, luego el resultado es almacenado en EAX y al retornar de la funci n convertimos el valor entero a cadenas de texto (recuerda que la funci n de conversi n esta en la librer a masm32.lib), para poder mostrar el resultado con la APi MessageBox. Nota.- En la funci n que hemos creado no solo se puede usar valores, tambi n variables y registros de 8, 16, 32 bits por que todo eso abarca en DWORD.

[ Ejercicios ]
1.- Tenemos 3 cantidades 800, 400, 100 (decimales), en cadenas de texto y queremos un programa que haga la siguiente operaci n: 800 450 = X Y el resultado X debe ser restado100 resultando Y, este resultado debe ser mostrado. 2.- Crear un programa que sume 5 cantidades y la sumatoria de dichas cantidades ser restado por 225 en decimal, las 5 cantidades se puede usar cualquier valor entero que se te ocurra ya sea en decimal o hexadecimal, si deseas mostrar el resultado hazlo.

15

[RVLCN]

3.- Crear una funci n que tenga 2 par metros para que muestre un mensaje por lo tanto: El primer par metro.- Aqu se colocara la direcci n de la etiqueta del Mensaje que se va mostrar. El segundo par metro.- Se colocara la direcci n de la etiqueta del titulo del mensaje.

[ Vocabulario ]
Pila o stack.- La pila viene hacer un rango de memoria la cual puede ser utilizada para el almacenamiento temporal de datos, solo 2 instrucciones trabajan con la pila y son el PUSH (guarda) y POP (recupera).

[ Recordatorio ]
No olvidar preguntar en lista MASM32-RadASM y enviar sus ejemplos del ejercicio que se ha dejado para subirlas al Site RVLCN, la duraci n en este caso es de 2 semana la tercera semana empiezan los desaf os de programaci n.

Dudas, sugerencias, otros, hacerlas en lista.

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com www: http://RVLCNsecurity.com www: http://beam.to/RVLCN http://beam.to/REVOLUCION

Julio-2006

16 Copyright(c) 2005-2006 RVLCN

[RVLCN]

c l a ses de P r o gr a m a c iO n C O N M A SM + Ra da sm
C a pi tu l o I V : C o n di ci o n es y bl u c es. Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

DOCUMENTO ESCRiTO PARA FiNES DE EDUCACiON/iNVESTiGACION

Masm32 tambi n puede utilizar el bloque .if (condicin) y tambi n .while, .repeat/.until (bluces) aprenderemos 2 formas de c mo utilizarlas, la primera serutilizando bloques y la otra es usando instrucciones CMP y JXX.

[ Condiciones ]
Usando el bloque .IF.- MASM puede hacer comparaciones simples y complejas en forma f cil y su sintaxis es de esta manera: Una comparacin simple seria de esta manera: Simple .if Condicion ; Si cumple la condicin ara algo ac . .endif Simple mas .else .if Condicion ; Si cumple la condicin ara algo ac . .else ; Si no cumple la condicin ara algo ac . .endif Si deseas hacer comparaciones secuenciales: Secuencial .if Condicion ; Si cumple la condicin ara algo ac .elseif Condicion ; Si cumple la condicin ara algo mas. .endif Secuencial mas .else .if Condicion ; Si cumple la condicin ara algo ac .elseif Condicion ; Si cumple la condicin ara algo mas .else ; Si no cumple con ninguna condicin ara algo ac . .endif Antes de entrar con los ejercicios observemos la siguiente tabla de operadores para las comparaciones: Operadores de comparacin == != > >= < <= && igual No igual Mayor Mayor o igual Menor Menor o igual Operadores de Multi - comparacin Lgico AND Y

||

Lgico OR Operador para verificar el estado de las banderas (flags) del procesador CARRY? Carry bit set OVERFLOW? Overflow bit set PARITY? Parity bit set SIGN? Sign bit set ZERO? Zero bit set

En el siguiente ejercicio haremos una serie de comparaciones, pare ello utilizaremos la librera rvlcnrand.lib para generar valores enteros aleatorios, los algoritmos de generado fue creado por Randall hyde desarrollador del compilador HLA (high Level Assembly) y pasado a masm por mi persona.

Funcin randzime

random

Librera rvlcnrand.lib Descripcin Con esta funcin creamos un punto al azar o semilla para que puedan ser utilizado por las 4 funciones siguientes: random, range, uniform, urange. De esta manera siempre podrgenerar en forma aleatoria. Genera nmeros al azar uniformemente distribuido utilizando un algoritmo lineal, el resultado es devuelto en EAX. Invoke random Genera un nmero al azar usando la funcin random, teniendo en cuenta el rango establecido, el resultado es devuelto en EAX. Invoke range, inicio, final Esta funcin genera un nuevo nmero al azar en cada llamada uniformemente distribuido, el resultado es devuelto en EAX. Invoke uniform Genera un nmero al azar usando la funcin urange, teniendo en cuenta el rango establecido, el resultado es devuelto en EAX. Invoke urange, inicio, final

range

uniform

urange

Ejemplo:

prog005_ha_c.exe Analizando prog005.- Como ya habamos visto en la ayuda win32programmers Referenced la funcin Messagebox una vez ejecutado devuelve a EAX el valor del botn que hemos presionado, para recordar:

Fig.01 invoke MessageBox . .if eax==IDYES ;Compara si EAX es igual a la Constante IDYES invoke MessageBox . .endif Lo que hace es comparar si hemos presionado el botn Yes o Si en espa ol, y si cumple la condicin mostrara el mensaje que hemos puesto.

Analizando prog005a.- Este programa es id ntico al ejercicio anterior, solo hemos agregado el bloque .else en caso que la condicin no se cumpliera. invoke MessageBox .if eax==IDYES ;Compara si EAX es igual a la Constante IDYES invoke MessageBox . .else ;Si no cumple con la condici n: invoke MessageBox .. .endif Si nuestra primera condicin no se cumple mostrara el otro mensaje que esta debajo del bloque .else. Analizando prog005b.- En este ejercicio hemos utilizado el bloque .elseif, para realizar varias comparaciones, por que la funcin Messagebox contiene 3 botones diferentes y EAX puede tomar cualquiera de esos 3 valores. invoke MessageBox .. .if eax==IDYES ;Compara si EAX es igual a la Constante IDYES invoke MessageBox .. .elseif eax==IDNO ;Compara si EAX es igual a la Constante IDNO invoke MessageBox .. .endif El botn Cancel no lo hemos tomado en cuenta en este ejercicio, pero si deseas lo puedes agregar. Analizando prog005c.- En este ejercicio hemos utilizado la librera rvlcnrand.lib, pare crear una serie de comprobaciones utilizando la mayora de operadores que hemos visto: invoke randzime invoke range,1,20 .if eax > 10 && eax <=15 ;Compara si EAX es mayor a 10 y si EAX es menor ;igual a 15 invoke MessageBox, . . .elseif eax < 5 ;Compara si EAX es menor a 5 invoke MessageBox,.. .elseif eax == 15 || eax == 16 ;Compara si EAX es igual a 10 o EAX es igual a ;16 invoke MessageBox, . .elseif eax >= 19 ;Compara si EAX es mayor o igual a 19. invoke MessageBox, . .else ;Si no cumple con ninguna condici n ara lo siguiente: invoke MessageBox, . .endif

En el primer bloque .if eax > 10 && eax <=15 Si el valor de EAX es mayor a 10 y si es menor igual a 15 mostrara el mensaje, fjate que el operador && es un enlazador para otra comparacin y significa y, entonces para que pueda mostrar el mensaje debe cumplir con las 2 condiciones. En el 3er bloque: .elseif eax == 15 || eax == 16 Si el valor de EAX es igual a 15 o si EAX es igual a 16 mostrara el mensaje, tambi n hay otro operador enlazador ||, y significa , entonces para que pueda mostrar el mensaje debe cumplir con cualquiera de las 2 condiciones. Tambi n podemos hacer comparaciones utilizando dos instrucciones: CMP (Compara) Destino Fuente

Destino.- Puede ser variables y registros de 8,16,32 bits Fuente.- puede ser variables, registros y valores enteros Esta instruccin compara los dos oper ndos, a su vez modifica las banderas el microprocesador AF, CF, OF, PF, SF, ZF. jxx (salta) Etiqueta

Esta instruccin salta hacia una direccin, veamos la tabla de algunos saltos y significados: Instruccin JA JAE JB JBE JE JG JGE JL JLE JMP JNA JNAE JNB JNBE JNE JNG Descripcin Salta si esta sobre Salta si esta sobre o igual Salta si esta debajo Salta si esta debajo o igual Salta si es igual Salta si es mayor Salta si no es mayor Salta si es menor Salta si es menor o igual Salta directamente Salta si no esta sobre Salta si no esta sobre o igual Salta si no esta debajo Salta si no esta debajo o igual Salta si no es igual Salta si no es mayor Estado de Bandera CF=0 y ZF=0 CF=0 CF=1 CF=1 ZF=1 ZF=1 ZF=0 SF=OF SF=OF SF != OF ZF=1 SF != OF CF=1 ZF=1 CF=1 CF=0 CF=0 y ZF=0 ZF=0 ZF=1 SF != OF

JNGE JNL JNLE

Salta si no es mayor o igual Salta si no es menor Salta si no es menor o igual

SF != OF SF=OF ZF=0 y SF=OF

Te preguntaras que sirve el estado de bandera o Flag, cada instruccin de salto se ejecuta si cumple la condicion por ejemplo: JA se ejecutara cuando la bandera CF sea igual a 0 y ZF tambi n sea igual a cero. JBE se ejecutara cuando bandera CF sea igual a 1 ZF sea igual a 1 SI te has fijado que Jmp no tiene condicion, eso significa que esa instruccin no necesita ninguna condicion para ejecutarse. Es por eso que la instruccin CMP modifica esas banderas para ejecutar el salto que le hemos puesto en la siguiente lnea. Luego analicemos prog006 donde encontraremos lo siguiente: .code prog006: invoke MessageBox ....... cmp eax, IDYES ; Compara EAX con la constante IDYES jne Fin ; Salta a Fin si no son iguales.

invoke MessageBox,NULL,addr MsgIDYES,addr MsgTitulo,MB_OK Fin: invoke ExitProcess,0 end prog006 Primero utilizamos CMP para comparar EAX con la constante IDYES, si no son iguales saltara a la etiqueta Fin, si coinciden mostrara el mensaje. Este ejercicio seria lo mismo que el prog005 la diferencia es que no hemos utilizado el bloque .if, hagamos lo mismo con el prog005b con instrucciones: .code prog006a: invoke MessageBox,....... cmp eax, IDYES ; Compara EAX con la constante IDYES jne _ElseIF ; Salta a _ElseIF si no son iguales.

invoke MessageBox,NULL,addr MsgIDYES,addr MsgTitulo,MB_OK _ElseIF: cmp eax,IDNO ;Compara EAX con la constante IDNO jne Fin ; Salta a Fin si no son iguales. invoke MessageBox,NULL,addr MsgIDNO,addr MsgTitulo,MB_OK Fin: invoke ExitProcess,0 end prog006a Para hacer comparaciones con instrucciones debemos saber cada significado de los saltos. Ahora utilizaremos las libreras rvlcnrand.lib para generar un valor aleatorio y la librera masm.lib por que se usara la funcin dwtoa para mostrar el resultado. .code prog006b: invoke randzime invoke urange,1,15 cmp eax,5 ; Compara EAX con 5 jg Mayor ; Salta si es Mayor invoke MessageBox... jmp Fin ; salta directamente Mayor: cmp eax,10 ; Compara EAX con 10 Jl Menor ; Salta si es menor

invoke MessageBox........ jmp Fin ; salta directamente Menor: invoke dwtoa,eax,addr Cmp_03 invoke MessageBox,...... Fin: invoke ExitProcess,0 end prog006b Cuando Mostrara el Mensaje ? Mostrara el Mensaje cuando EAX sea menor 5 Mostrara el Mensaje cuando EAX sea mayor 10

Mostrara el valor cuando no cumplan con ninguna condicion.

[ Bluces ]
En bluces estudiaremos los bloques .while y el .repeat/.until, para crear lazos que se repita hasta que se cumpla o no la condicin que hemos determinado. .while .- Este bloque creara un lazo o bluce siempre y cuando cumpla la condicin, si en caso no se cumpla terminara el lazo y su sintaxis es as: .while condicion ; codigo .endw Ejemplo: Mov eax,6 .while eax > 1 sub eax, 1 .endw Este lazo se repetir siempre y cuando eax sea mayor que 1, si no la cumple el lazo se romper , si no queremos hacerlo con bloques tambi n podemos hacer con puras instrucciones de esta manera: Mov eax,6 jmp comprueba bluce: sub eax, 1 ; restamos 1 al contenido de EAX comprueba: cmp eax, 1 ja bluce Como apreciamos el bloque .while se produce un salto directamente a la instruccin cmp, luego esta el salto JA (salta si esta sobre), en este caso salta si eax esta sobre 1, este lazo se rompercuando eax sea 0. .repeat/ .until.- Este lazo funciona al contrario de .while, en este caso el lazo terminara cuando cumpla la condicin y su sintaxis es as: .repeat ;codigo .until condicion

Ejemplo: mov eax,0 .repeat add eax, 1 ; sumamos 1 al contenido de eax .until eax > 6 El lazo se romperhasta que eax sea mayor a 6, como en el bloque .while tambi n podemos hacerlo con instrucciones de esta manera: mov eax,0 bluce: add eax, 1 cmp eax, 6 jnb bluce Veamos el siguiente video con ejemplos de bluces:

prog007_ha_b.exe Analizando el prog007: Creando bluce con el bloque .while: Librera User32.lib

FindWindow,NULL,addr Titulo_ventana

Fig.02 Esta funcin busca el titulo de la ventana o tambi n la clase de la ventana, y si lo encuentra devuelve el handle de la ventana al registro de EAX, para m s informacin revisen la documentacin Win32Programmer Referenced Fig.02.

Lnea 9.- Buscamos el titulo de la ventana, si la encuentra devolverel handle a EAX. Linea10.- Creamos un bluce con el bloque .while, si EAX es mayor a 1 el bluce se realizara siempre y cuando EAX sea mayor a 1, es por eso que se ha puesto nuevamente la funcin Findwindow antes de .endw en la l nea 12 para que siga el bluce hasta que ya no encuentra el titulo de la ventana, si no la encuentra EAX sera 0 y el bluce se romper .

Analizando el prog007a: Creando bluce con el bloque .repeat/.until:

Lnea 9.- Creamos un punto al azar o semilla para que pueda crear valores al azar la funcin range. Lnea 10.- La funcin range devuelve a EAX un valor comprendido desde 0 hasta 100. Este bluce se repetirhasta que el contenido de EBX sea mayor que EAX, es por eso que se suma 1 a EBX desde 0, como se sabe el valor de EAX se desconoce ese valor es determinado por la funcin range.

Librera kernel32.lib wsprintf

wsprintf,addr buffer,addr Msgtexto, ebx


Con esta funcin nosotros pasamos el contenido de ebx a formato ACSII, pero ese no es el nico formato al cual podemos pasar. Veamos el siguiente ejemplo:

Ahora mostraremos 2 valores en decimal y hexadecimal, otra cosa importante la funcin wsprintf solo tiene 2 par metros fijos los otros son opcionales solo podemos agregarlos cuando queremos pasar de un formato a otro como por ejemplo estos:

%d para formato decimal %x para formato hexadecimal Nuestra cadena contiene 2 formatos: MsgTexto db "Decimal: %d ; hexadecimal: %x" ,0 Por eso es necesario colocar 2 par metros mas a nuestra funcin en este caso es eax y ebx, veamos como se alinean cada registro con su formato:

En el siguiente ejemplo agregaremos un icono a nuestra aplicacin:

[ Agregando un icono ]
Nosotros en algunos aplicaciones en nuestra pc hemos visto que tienen sus propios iconos, nosotros tambi n personalizaremos nuestro programa con su propio icono lo que debemos hacer es poner nuestro icono en un recurso. Y lo hacemos de esta manera:

Prog008.exe Nota.- Es importante que nuestro icono este dentro de la carpeta de nuestro proyecto.

[ Agregando una herramienta ]


Alguna vez te has preguntado como saber que funciones pertenecen a cada librera?. Pues a nuestro RADASM le agregaremos un programa para buscar la funcin y nos muestre que librera agregar.

Add_tools.exe

[ Ejercicios ]
1.- Crea un bluce que se repita 1000 veces con .while y .repeat/.until: 3.- Crea un bluce para que muestre un mensaje 5 veces. 2.- Utilizando la funcin wsprintf y generando un valor aleatorio, crea un programa muestra un mensaje mostrado el valor en decimal y en hexadecimal:

[ Vocabulario ]
handle.- Es el manejador de la ventana, cada ventana de nuestro sistema tiene un handle diferente, es una valor para identificar cada ventana.

[ Recordatorio ]
No olvidar preguntar en lista MASM32-RadASM y enviar sus ejemplos del ejercicio que se ha dejado para subirlas al Site RVLCN, en esta semana se estarenviando las soluciones de los ejercicios anteriores

Dudas, sugerencias, otros, hacerlas en lista.

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM ( Redh@wk ) http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com www: http://RVLCNsecurity.com www: http://beam.to/RVLCN http://beam.to/REVOLUCION

Septiembre-2006
Copyright(c) 2005-2006 RVLCN

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o V :N u e str a p r i me r a V e nta na . Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

EL presente escrito,creado para fines educacionales e investigaci n. Es de libre distrubucion, siempre que se conserve intacto el contenido y se precise derechos de autor

[RVLCN]

[ Nuestra Primera Ventana ]


Llego el momento de crear aplicaciones con ventanas y agregarle botones, im genes y otros controles. Primero crearemos una ventana hecha con puras APIs como muestra el video presta mucha atencin:

Prog009.exe Librer a kernel32.lib

GetModuleHandle, NULL
Esta funcin devuelve el handle del modulo o instancia del programa, todos los programas que utilizan ventanas utilizan esta funcin, as que el valor devuelto a EAX lo guardamos en una variable en este caso llame Hinstance: mov Hinstance,eax Luego necesitamos utilizar la estructura WNDCLASSEX que contiene toda la informacin requerida para crear nuestra ventana, esa informacin nosotros la ponemos con la instruccin MOV, para utilizarla declaramos la etiqueta wc como WNDCLASSEX de esta manera: wc WNDCLASSEX <> Si observamos la ayuda Win32 Programmer s Referenced, para saber sobre cada miembro de la estructura mostrara lo siguiente:

[RVLCN]

typedef struct _WNDCLASSEX { UINT cbSize; UINT style; WNDPROC lpfnWndProc; int cbClsExtra; int cbWndExtra; HANDLE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCTSTR lpszMenuName; LPCTSTR lpszClassName; HICON hIconSm; } WNDCLASSEX;

// wc

1.- cbSize es aqu donde especificamos el tama o de la estructura cuando no la sabemos el tama o utilizamos el operador SIZEOF: mov wc.cbSize, SIZEOF WNDCLASSEX 2.- style especificamos el estilo de nuestra ventana hay varios tipos (mirar la ayuda antes mencionada), como por ejemplo utilizamos CS_HREDRAW y CS_VREDRAW si quieres combinarlas podemos utilizar la instruccin OR: mov wc.style, CS_HREDRAW or CS_VREDRAW 3.- lpfnWndProc definimos la direccin de la etiqueta de los procedimientos: mov wc.lpfnWndProc, offset WinProC 4.- cbClsExtra especificamos el n mero de bytes extra, para ubicar la siguiente estructura de la ventana, pero nosotros no la utilizamos y movemos el valor cero o NULL: mov wc.cbClsExtra,NULL 5.- cbClsExtra especificamos el n mero de bytes extra, para ubicar la instancia de la ventana, igualmente que en el anterior no lo necesitamos y movemos el valor cero. mov wc.cbWndExtra,NULL 6.- hInstance especificamos el manejador (handle) de la instancia del modulo: push Hinstance pop wc.hInstance

[RVLCN]

7.- hIcon especificamos el manejador del icono, para ello hemos utilizado la funcion LoadIcon: invoke LoadIcon,Hinstance,IDI_APPLICATION mov wc.hIcon,eax 8.- hCursor especificamos el manejador del cursor, para ello hemos utilizado la funcion LoadCursor: invoke LoadCursor,NULL,IDC_ARROW mov wc.hCursor,eax 9.- hbrBackground especificamos el color del fondo de nuestra ventana: mov wc.hbrBackground, COLOR_BTNFACE + 1 10.- lpszMenuName especificamos el manejador del Men . mov wc.lpszMenuName,NULL 11.- lpszClassName definimos la direccin de la etiqueta donde se encuentra el nombre (ACSII), de clase de la ventana. mov wc.lpszClassName,offset Classname 12.- hIconSm especificamos el manejador del icono peque o. Esto nos ha servido para personalizar nuestra ventanita que vamos a crear, ahora falta registrar su clase, para ello necesitamos la funcin RegisterClassEx: invoke RegisterClassEx,addr wc Al poner wc registramos todo los cambios que hemos hecho en los miembros de la estructura, esto es muy importante por que si no hacemos esto nuestra ventana no saldr . Ya le hemos puesto las caracter sticas de nuestra ventana y adem s su clase esta registrado, ahora falta crear la ventana y lo hacemos con la siguiente funcin: Librer a kernel32.lib CreateWindowEx, NULL, addr Classname, addr Appname, \ WS_OVERLAPPEDWINDOW, 150,210,300,200,NULL,NULL,Hinstance,NULL Esta API es la encargada de crear nuestra ventana y devuelve el manejador al registro EAX es recomendable guardarlo en una variable para cuando queremos referirnos a ella lo identifiquemos por medio de dicha variable, esta funcin no solo sirve para eso, tambi n puede crear controles de ventanas

[RVLCN]

llamadas hijas como botones, edit, static, listbox, etc, es por eso que vamos a analizar que rol cumple cada par metro de esta funcin: HWND CreateWindowEx( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam ); 1.- dwExStyle Especificamos el estilo extra de nuestra ventana extendida, como por ejemplo: WS_EX_TOPMOST .- Crea una ventana por encima de todas. WS_EX_TRANSPARENT .- Crea una ventana transparente. WS_EX_TOOLWINDOW .- crea una ventana en herramienta. Si quieren comprobar pueden poner esos estilos en el primer par metro y la funcin quedar a de esta manera: Invoke CreateWindowEx, WS_EX_TOPMOST, addr Classname..... Si quieres saber mas estilos vea Win32 Programmers Referenced. 2.- lpClassName definimos la direccin de la etiqueta donde se encuentra el nombre (ACSII) de clase de la ventana. 3.- lpWindowName definimos la direccin de la etiqueta donde se encuentra el nombre de la ventana si no la tiene se puede usar el NULL. 4.-dwStyle En este par metro especificamos la apariencia de la ventana, nosotros hemos puesto WS_OVERLAPPEDWINDOW, por que combina varios estilos de apariencia como: WS_OVERLAPPED, WS_CAPTION, WS_SYSMENU, WS_THICKFRAME, WS_MINIMIZEBOX y WS_MAXIMIZEBOX Si nosotros queremos una ventana que solo tenga el botn maximizar habilitado nuestra funcin quedar a as :

[RVLCN]

CreateWindowEx, NULL, addr Classname, addr Appname, WS_SYSMENU or WS_MAXIMIZEBOX,...... No olvidar que si queremos combinar estilos usamos la instruccin OR. 5.- X especifica la coordenada de la posicin horizontal de la ventana cliente. 6.- Y especifica la coordenada de la posicin vertical de la ventana cliente. Para que quede m s observemos las im genes:

Fig.1 Cuando creemos controles de ventana hija como por ejemplo un botn el rango de las coordenadas estar dentro de la ventana padre:

Fig .2

[RVLCN]

7.- nWidth especificamos el ancho del control que hemos creado. 8.- nHeight especificamos el alto del control que hemos creado.

Fig.3 9.- hWndParent Identificamos la ventana padre si lo hubiera, cuando creamos controles de ventanas hijas este par metro es utilizado, por ejemplo si quieres crear un botn sobre la ventana padre Fig.3, debemos especificar el manejador de nuestra ventana y como recordamos nosotros lo guardamos en la variable hwnd. 10.- hMenu especificamos el manejador del men , este par metros solo la utilizamos con controles (ventanas hijas), por ejemplo si le quieres meter un men al botn de la fig.3 empleamos este par metro, mas no cuando creamos ventanas tipo WNDCLASSEX por que tiene un miembro especifico que hace eso. 11.- hInstance especificamos la instancia del modulo asociado a la ventana. 12.- lpParam este puntero la usamos cuando creamos ventanas MDI, si no la utilizamos colocamos el valor NULL. .while TRUE invoke GetMessage,addr msg,NULL,NULL,NULL .break .if !eax invoke TranslateMessage,addr msg invoke DispatchMessage,addr msg .endw Como lo explique en el video este bluce siempre se esta ejecutando hasta que se cierre la ventana, en esta parte del cdigo hemos visto un nuevo bloque el

[RVLCN]

.break este bloque es de interrupcin al bluce sirve para terminar el bluce si cumple la condicin su sintaxis es as : .break condicion ;si cumple la condici n saldr del bluce. En nuestro programa la condicin es .if !EAX que quiere decir compara si EAX es igual a cero, es equivalente si colocamos .if EAX == 0. Otro punto importante del bluce es que siempre esta cogiendo los mensajes del programa, cuando nosotros cerremos la ventana la funci n GetMessage devolver a EAX el valor 0 y saldr del bluce para terminar el programa. Luego esta el procedimiento de la ventana, es ahdonde empleamos los mensajes para ponerle funciones: WinProC proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .if uMsg == WM_DESTROY invoke PostQuitMessage,NULL .else invoke DefWindowProc,hWnd,uMsg,wParam,lParam ret .endif xor eax,eax ret ret WinProC endp Todo lo que queramos que nuestro programa haga lo hacemos aqu , como dije en el video este es el cerebro del programa, el responsable de ponerle diferentes funciones a nuestra ventana, el par metro uMsg es quien contiene el valor de los mensajes, la funcin DefWindowProc recicla todos lo mensajes que no utilizamos. WM_DESTROY.- Este mensaje se env a cuando la ventana es destruida o cuando se desaparece del escritorio. Haremos unos ejemplos sobre ventanas, pero primero crearemos una nueva planilla a partir de la que hay en el RadAsm y la modificaremos para que se vea mejor:

[RVLCN]

Plantilla02.exe

Si nos damos cuenta en la planilla que hemos visto sea creado una funcin, con el fin de llenar los miembros de la estructura wc: invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT No tiene nada de nuevo, eso ya lo hemos visto en el capitulo III cuando creamos funciones nosotros llen bamos los par metros de las APIS, en este caso esta llenando los miembros de la estructura. Lo que es nuevo en el cdigo son como se declara las variables locales, este tipo de variables solo puede ser usado desde en inicio del procedimiento hasta el final de el, como muestra la siguiente imagen:

Fig.3 Su sintaxis es de esta manera:

10 LOCAL Etiqueta : tipo de Variable/Estructura Otra cosa importante que observamos son estos tipos de variables: HWND UINT WPARAM LPARAM HINSTANCE LPSTR

[RVLCN]

Pues no vayan a creer que son nuevas variables, estas tienen diferente nombre pero son del mismo tipo y son DWORD, si quieres comprobar buscan en el archivo Window.inc y encontrar algo as : HWND EQU DWORD El operador EQU significa equivalente o igualdad, en otras palabras HWND es igual a DWORD. Ya hemos analizado todo el cdigo para crear nuestra ventana, ahora crearemos un par de ventanas con botones y edit. Adem s le agregaremos funciones al botones. Para empezar haremos esta ventana:

Fig. 4 Luego esta:

Fig.5

11

[RVLCN]

Solucin Fig.4:

prog010.exe En el video encontramos el mensaje WM_CREATE, este mensaje se env a antes de que muestre la ventana y como su nombre indica sirve para crear nuevas ventanas hijas pero tambi n puedes usarlo con otros fines. .ELSEIF uMsg==WM_CREATE invoke CreateWindowEx,NULL,addr Class_boton,addr Texto_boton01,\ WS_CHILD or WS_VISIBLE or BS_DEFPUSHBUTTON,\ 10,75,100,25,hWnd,NULL,hInstance,NULL mov hwnd_boton01,eax Nosotros ya sabemos para que sirve cada par metro de esta funcin, lo nuevo que encontramos una nueva clase de ventana hija y que tambi n hemos llenado el 9no par metro. La clase nueva de la ventana hija es: Class_boton db "button",0 Con esta clase se crea un boton. El 9no par metro lo hemos puesto hWnd, por que contiene el handle de la ventana padre y sirve para crear otros controles (ventanas hijas) sobre la ventana principal. Si vamos a crear varios botones solo declaramos una sola vez la clase de ventana, otra cosa importante es que cuando crea el control si vamos hacer algo con el, es necesario guardar su handle, en una variable como en mi caso:

12 mov hwnd_boton01,eax

[RVLCN]

He movido el contenido del registro EAX ah hwnd_boton01, para que en el futuro pueda identificar y utilizarlo. Luego encontramos otro tipo de mensaje WM_COMMAND, este otro se env a cuando se toca o cuando pulsamos alg n tem o control, y el manejador del objeto tocado o pulsado se encuentra en lParam, tambi n existe wParam y ah se encuentra el ID mas el cdigo de notificacin eso lo veremos mas adelante cuando entremos a ventanas con dialog. .elseif uMsg== WM_COMMAND mov edx,lParam Entonces movemos el handle que contiene lParam ah EDX por que como se sabe no se puede comparar variables con variables. .if edx == hwnd_boton01 .elseif edx== hwnd_boton02 .endif En estas comprobaciones comparamos todos los manejadores de nuestros botones, para que cuando se presiona solo uno ser igual, luego ah esos botones le ponemos diferentes funciones. if edx == hwnd_boton01 invoke MessageBox,hWnd,........ . elseif edx== hwnd_boton02 invoke DestroyWindow,hWnd .endif Aqu le dimos a cada botn una funcin, en este caso el botn 01 mostrara un mensaje y el botn 02 cerrara el programa. Nota: si vas agregar un nuevo mensaje lo haces con .elseif uMsg== MI_MENSAJE. Librer a kernel32.lib DestroyWindow,hWnd Con esta funcin destruimos la ventana padre.

13 Seguimos con el programa de la figura 5.

[RVLCN]

prog011.exe Hemos encontrado 2 APIs nuevas: Librer a kernel32.lib GetWindowText, hwnd_edit01,addr buffer,100 Esta funcin coje el texto de las ventanas tiene 3 par metros y son las siguientes: hWnd.- Identificamos la ventana colocando el manejador del control. lpString.- Direccin de la memoria donde se almacenara el texto. nMaxCount.- Numero m ximo de caracteres que se va ha cojer. Librer a kernel32.lib SetWindowText, hwnd_edit02,addr buffer Con esta funcin enviamos el texto a las ventanas, contiene 2 par metros. hWnd.- Identificamos la ventana colocando el manejador del control. Lpsz.- Direccin de la memoria donde se encuentra el texto.

14

[RVLCN]

En ambos programas hemos puesto diferente icono a nuestras ventanas, la seccin .const sirve para colocar constantes y es solo de lectura, cuando declaramos un objeto que esta en el recurso es importante colocar el mismo ID del recurso que hemos puesto por ejemplo: Sintaxis: Etiqueta equ valor app equ 100 ;programa fig4 Icono equ 100 ;programa fig5 Nos damos cuenta que la etiqueta no importa lo que en verdad sirve es el valor 100 que es el ID de nuestro icono en el recurso. Utilizando el mensaje WM_CLOSE: Fuente \prog012 Vamos ah crear una ventana, que cuando nosotros le demos clic en muestre este mensaje: ,

Fig.06 Con la condicin que si presionamos el botn Si para cerrar y No para no cerrar la ventana, en la planilla que tenemos debemos agregar este mensaje: WM_CLOSE Este mensaje se env a cuando la ventana esta por terminar pero todav a muestra la ventana en el escritorio, despu s de este mensaje sigue: WM_DESTROY, Para que muestre el mensaje de la figura Fig.06, llamamos a la funcin MessageBox de esta manera: invoke MessageBox,hWnd,addr MsgSalir,addr TitSalir, MB_YESNO+ MB_ICONINFORMATION Luego para comparar que botn se ha presionado llamamos al bloque .if y nuestro cdigo quedara as :

15 .elseif uMsg == WM_CLOSE invoke MessageBox,hWnd,addr MsgSalir,addr TitSalir, MB_YESNO+ MB_ICONINFORMATION .if eax == IDYES invoke DestroyWindow,hWnd .endif Con eso comprobamos el botn que se ha presionado.

[RVLCN]

[ Ejercicios ]
1.- Cree una ventana del tama o de tu escritorio. 2.- Cree una ventana con 5 botones, cada botn debe mostrar diferentes mensajes. 3.- Cree un programa igual ha este:

Nota: al presionar el botn Enviar debe enviar el titulo de la ventana, no olvides determinar el handle de nuestra ventana padre a la Funci n SetwindowText, el icono puede elegirlo usted.

[ Recordatorio ]
No olvidar preguntar en lista MASM32-RadASM y enviar sus ejemplos del ejercicio que se ha dejado para subirlas al Site RVLCN, en esta semana se estar enviando las soluciones de los ejercicios anteriores, se adjunta 3 funciones traducidas al espa ol gracias ah desacatado por postear en la lista: http://winapi.conclase.net/curso/index.php?tab=Funciones Dudas, sugerencias, otros, hacerlas en lista.

16

[RVLCN]

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM ( Redh@wk ) http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com www: http://RVLCNsecurity.com www: http://beam.to/RVLCN http://beam.to/REVOLUCION
Noviembre-2006

Copyright(c) 2005-2006 RVLCN

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o V I: C a j a s D e di al o g. Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

EL presente escrito,creado para fines educacionales e investigaci n. Es de libre distrubucion, siempre que se conserve intacto el contenido y se precise derechos de autor

[RVLCN]

[ Cajas de Dialog ]
Esta es otra manera de crear ventanas, utilizando el editor de recursos que viene con el RadASM se puede crear en forma f cil y r pida veamos el siguiente video:

Prog13.exe Como observamos el video el cdigo para mostrar una ventana simple utilizando las cajas de dialog es m s sencillo que cuando lo hacemos con puras APIS, veamos el cdigo en el archivo prog13.inc: Librer a user32.lib

DialogBoxParam, hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL


Esta funcin es la principal en nuestro programa, por que es la causante de mostrar la ventana que esta en el recurso y adem s ubicar la direccin donde se encuentra los procesos de ella, veamos para que sirva cada uno de los par metros:

hInstance.- Especificamos el manejador de la instancia del modulo.


lpTemplate.- Especificamos el ID de nuestra caja de dialog, ese ID nosotros la podemos determinar en las propiedades de la caja:

[RVLCN]

Fig.1 El ID de nuestra caja es 101 y el nombre es IDD_DIALOG1, con esos datos debemos declarar en nuestro archivo INC en la seccin const:

Fig.2 hWndParent.- Definimos el handle de donde pertenece la ventana, aqu ponemos NULL por ser nuestra ventana principal, si en caso fuera la segunda ventana especificaremos el handle de la primera ventana (padre). lpDialogFunc.- Definimos la direccin de la etiqueta donde se encuentra los procedimientos: DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM Mov eax,uMsg .if eax==WM_INITDIALOG .elseif eax==WM_COMMAND .elseif eax==WM_CLOSE invoke EndDialog,hWin,0 .else Mov eax,FALSE ; movemos a EAX el valor 0 para reciclar los mensajes que no ; utilizamos si no hacemos esto, no ser compatible con window Xp y NT ret .endif Mov eax,TRUE ret DlgProc endp

[RVLCN]

Como observamos este procedimientos nos resulta familiar a los procesos de la ventanas a puras APiS que hemos creado en el capitulo anterior, por que toda ventana maneja los mismo mensajes con excepcin de algunos que son solo para Dialog como por ejemplo WM_INITDIALOG, este mensaje se env a antes de mostrar la caja de dialog en el escritorio, como se diferenciamos que mensajes son solo para cajas de di logos, pues es simple y lo hacemos por la palabra DIALOG al final del mensaje. dwInitParam.- Definimos con que valor queremos que tenga al inicio el par metro lParam, esto no se usara en nuestro programa y colocaremos el valor NULL. Seguimos practicando y esta vez crearemos una ventana con 2 botones y tendr n diferentes funciones, el primer botn ser para mostrar un mensaje y el segundo ser para salir.

prog14.exe Nosotros ya sabemos por el capitulo V en que momento se env a el Mensaje WM_COMMAND si no lo has le do el concepto esta en la pagina 12, cuando trabajamos con cajas de dialog y sus controles ( tems), siempre lo identificamos con un ID, si nosotros queremos trabajar con un control especifico lo identificamos con ID, la constante que tiene todos los ID de control en el proceso de la ventana es wParam, adem s de contiene el cdigo de notificacin, para que quede mas claro f jense en el siguiente cuadro:

[RVLCN]

CONTROLES (botones, edit,static, etc.) Men

wParam HIGH Contiene el Cdigo de notificacin Sin Utilidad

lParam LOW Contiene el ID Contiene el manejador de la ventana hija (handle). Sin Utilidad

Ejemplo supongamos que wParam contenga el valor 12345678 entonces: El cdigo de notificacin: 1234 El ID del control: 5678 Este es un ejemplo de cmo extraer el cdigo de notificacin: mov eax,wParam mov edx,eax shr edx,16 .IF dx==BN_CLICKED .if ax == boton01 .elseif ax == boton02 .endif .endif SHR (Cambio de puesto a la derecha) Destino Contador

Esta instruccin SHR cambia de puestos hacia la derecha, los bits mas significativos desaparecen y las posiciones que se crearon a la izquierda se llenan de 0. Para no enredarnos con esta instruccin es igual que dividir por 2 elevado por el Contador ejemplo: mov eax,12345678 shr eax,16 Equivale ah: Contador = 16 12345678h : 2 12345678h : 10000h = 00001234 EAX = 00001234 De esa manera podemos sacar el cdigo de notificacin, si se va a trabajar con ello.

[RVLCN]

BN_CLICKED este cdigo de notificacin se env a cuando pulsamos cualquier botn, yo no lo utilizo por que este valor de notificacin es 0 a la izquierda. Por ejemplo el ID del boton01 es 1001 en decimal (3E9 en hex.), cuando nosotros pulsamos el boton01 el valor de wParam ser igual a 00003E9h donde: El cdigo de notificacin: 0000 igual BN_CLICKED. El ID del control: 03E9. mov eax,wParam ; EAX = 00003E9h mov edx,eax ; Movemos el contenido de EAX a EDX = 00003E9h shr edx,16 ; EDX = 00000000 .IF DX==BN_CLICKED ; Compara si DX es igual a CERO .endif Comparamos si el valor del cdigo de notificacin es igual a 0, es por eso que yo me ahorro todo ese cdigo y de frente comparo los ID por que se que el cdigo de notificacin cuando pulsamos es 0 y esta a la izquierda de nuestro valor total, como dicen cero a la izquierda no sirve. Excepto si en nuestro programa queremos utilizar el c digo de notificaci n y colocarles una funci n a todos los botones cuando lo pulsamos. A continuacin vamos ha trabajar con algunos campos editables:

Prog15.exe

7 Librer a user32.lib

[RVLCN]

GetDlgItemText, hWin,edit01,addr buffer,225


Esta funcin trabaja con cajas de dialog, esta funcin es igual GetWindowText pero la diferencia es que para coger el texto del control necesitamos el manejador de nuestra caja de dialog y el ID del control que queremos coger el texto. Par metros: hDlg.- Identificamos el manejador de nuestra caja de dialog. nIDDlgItem.-Identificamos el ID de nuestro Control. lpString.- Direccin de la memoria donde se almacena el texto. nMaxCount.- N mero m ximo de caracteres que se va a coger. Librer a user32.lib

SetDlgItemText, hWin,edit01,addr buffer


Al igual que la funcin SetWindowtext coge texto, pero con la diferencia que identificamos el ID del control. Par metros: hwndDlg.- Identificamos el manejador de nuestra caja de dialog. idControl.- Identificamos el ID de nuestro Control. lpsz.- Direccin de la memoria donde se encuentra el texto.

[ Agregando Icono ]
Ahora agregaremos un icono a nuestra aplicaci n:

Prog16.exe

8 Librer a user32.lib

[RVLCN]

SendMessage, hWin,edit01,addr buffer


Esta funcin env a mensajes espec ficos a nuestras ventanas siempre y cuando tengamos el manejador de la ventana. Par metros: hwnd.- Identificamos el manejador de la ventana que enviaremos el mensaje. uMsg.- Especificamos el mensaje que se va enviar. wParam.- especificamos informacin adicional del mensaje. lParam.- especificamos informacin adicional del mensaje. Por ejemplo si queremos enviar un icono a nuestra ventana especificamos el manejador de la ventana, el tipo de mensaje, el tama o del icono, y el manejador del icono. De esta manera declaramos la funcin SendMessage para enviar un icono a nuestro programa: SendMessage, hWin.- Manejador de la ventana. WM_SETICON.- Tipo de mensaje. ICON_BIG.- Tama o del Icono. h_icono.- handle del icono. Si nosotros queremos cerrar nuestra ventana principal uno de tantos m todos seria enviamos el mensaje WM_CLOSE ejemplo: SendMessage.hWin.- Manejador de la ventana. WM_CLOSE.- Tipo de mensaje. 0.- No especificamos. 0.- No especificamos. Haremos un ejemplo mas con esta funcin, para ello creamos un programa igual al de la imagen:

Fig.2

[RVLCN]

Estos dos botones cierran la ventana, y su funcionamiento es lo siguiente: el primer botn env a un mensaje a la ventana para que se ejecute la funcin del botn 2 y a su vez env a un mensaje para cerrar el programa. Te preguntaras como se hace eso y lo hacemos con el siguiente cdigo: .elseif eax==WM_COMMAND mov edx,wParam .if edx == boton01 invoke SendMessage,hWin,WM_COMMAND,boton02,0 .elseif edx == boton02 invoke SendMessage,hWin,WM_CLOSE,0,0 .endif .elseif eax==WM_CLOSE invoke EndDialog,hWin,0 En el boton01 colocamos la funcin SendMenssage donde se declaro de la siguiente manera: hWin.- Manejador de la ventana. WM_COMMAND.- Este tipo de mensaje es donde se producen las funciones de lo botones. boton02.- Especificamos el valor que debe tener wParam cuando enviamos el mensaje. 0.- No especificamos nada. Este ejemplo es muy sencillo y esta adjunto en este documento.

[ Ejercicios ]
1.- Cree un programa que cuando presione el botn enviar muestre un mensaje con el texto que pusimos en el campo edit como muestra la imagen:

10

[RVLCN]

2.- Cree una calculadora que sume 2 cantidades, debe tener 3 campo edit donde: El primer y segundo campo edit.- se ingresara los valores que se va a sumar. El tercer campo edit.- mostrara el resultado. Adem s debe tener 3 botones con las siguientes funciones: El primer botn.- Debe hacer la suma. El segundo botn.- Debe borrar todo los campos edit. El tercer botn.- cerrar la ventana. Para desarrollar este programa es necesario usar lo siguiente: 1.- la funciones atodw y dwtoa descritas en el capitulo III. 2.- Debes usar la instruccin add (suma). Se pide el resultado en decimales, la idea es algo parecido a esta:

3.- Desarrolle un programa que convierta n meros decimales a hexadecimales. Pude usar combinando las funciones del masm atodw , dwtoa y dw2hex o usando una sola funcin que es la wsprintf.

11

[RVLCN]

[ Recordatorio ]
No olvidar preguntar en lista MASM32-RadASM y enviar sus ejemplos del ejercicio en un archivo comprimido mas el nick para poder identificar, en esta semana se estar enviando las soluciones de los http://winapi.conclase.net/curso/index.php?tab=Funciones Dudas, sugerencias, otros, hacerlas en lista.

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com http://RVLCNsecurity.com http://beam.to/RVLCN http://beam.to/REVOLUCION
Julio-2006

Copyright(c) 2005-2006 RVLCN

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o V I:M a ne jo de C a de na s . M ac ro s . Escrito por: ^A|An M0r3N0^
Consejero: RedH@wk
DESCARGO LEGAL

EL presente escrito,creado para fines educacionales e investigaci n. Es de libre distrubucion, siempre que se conserve intacto el contenido y se precise derechos de autor

[RVLCN]

[Cadenas de texto]
Llego la hora de trabajar con cadenas de texto nuestra primera tarea ser concatenar, copiar y comparar, utilizando las APIS de Windows despus utilizando la funciones de masm32 y por ultimo con instrucciones. 1.- Utilizando las funciones de Windows.- para trabajar con cadenas de texto podemos emplear 4 funciones espec ficas y son las siguientes: Librer a kernel32.lib

lstrcat, addr Cadena01, addr Cadena02


Esta funci n se encarga de concatenar (unir) las cadenas y formar una sola, el resultado de la uni n se almacena en el primer par metro ejemplo: .data CadTexto01 db "Yo programo en",0 CadTexto02 db " masm + radasm",0 MsgTitulo db " RVLCN - 2006",0 .code invoke lstrcat,addr CadTexto01 ,addr CadTexto02 invoke MessageBox,NULL,addr CadTexto01,addr MsgTitulo,MB_OK + \ MB_ICONINFORMATION invoke ExitProcess,0 .end El mensaje que muestra nuestro programa es el resultado de la uni n:

Fig.01 Vea la fuente del programa prog.18.

3 Librer a kernel32.lib lstrcmp, addr CadTexto01, addr CadTexto02

[RVLCN]

Esta funci n compara las cadenas de texto entre sus dos par metros, si las cadenas no son iguales el valor devuelto a EAX ser 1 por ejemplo: .data CadTexto01 db "HOLA",0 CadTexto02 db "hola",0 MsgTexto db "Las 2 cadenas comparadas son diferentes",0 MsgTitulo db " RVLCN - 2006",0 .code invoke lstrcmp,addr CadTexto01,addr CadTexto02 .if eax==1 invoke MessageBox,NULL,addr MsgTexto,addr MsgTitulo,MB_OK + \ MB_ICONINFORMATION .endif invoke ExitProcess,0 end Como podemos darnos cuenta no diferencia mayscula ni minscula al momento de comparar, pero hay una funci n derivada de esta que si omite las maysculas y lo que debemos hacer es agregarle una i al final del nombre de la funci n dando como resultado lstrcmpi si hacemos esto ya no mostrara el mensaje dando como resultado igualdad entre cadenas. Vea la fuente del programa prog.19. Librer a kernel32.lib

lstrcpy, addr buffer, addr CadTexto01


Esta funci n copia todo la cadena de texto que se encuentra en la direcci n del segundo par metro CadTexto01 hacia el primero buffer. .data CadTexto01 db "BiENVENiDO AL CURSO DE MASM + RADASM",0 MsgTitulo db " RVLCN - 2006",0 .data? buffer db 100 dup (?)

4 .code invoke lstrcpy,addr buffer,addr CadTexto01 invoke MessageBox,NULL,addr buffer,addr MsgTitulo,MB_OK + \ MB_ICONINFORMATION invoke ExitProcess,0 end

[RVLCN]

El mensaje que muestra nuestro programa es el contenido del buffer que anteriormente le copiamos la cadena de texto.

Fig.2 Si deseamos copiar solo una parte de nuestra cadena de texto por decir solo la palabra BiENVENiDO le agregamos la letra n al final del nombre de la funci n de esta manera lstrcpyn, y se abre un 3 par metro que es para colocar la longitud que quieres copiar por ejemplo: invoke lstrcpy,addr buffer,addr CadTexto01, 9 Solo se copiaran 9 caracteres. Vea la fuente del programa prog.20.

Librer a kernel32.lib

lstrlen ,addr MsgTexto


Esta funci n devuelve a EAX la longitud de nuestra cadena .data MsgTexto db "BiENVENiDO AL CURSO DE MASM + RADASM",0 MsgTitulo db " RVLCN - 2006",0 fmo db "la longitud de nuestra cadena es %d caracteres",0 .data? buffer db 100 dup (?)

5 .code invoke lstrlen,addr MsgTexto invoke wsprintf,addr buffer,addr fmo,eax invoke MessageBox,NULL,addr buffer,addr MsgTitulo,MB_OK + \ MB_ICONINFORMATION invoke ExitProcess,0 end

[RVLCN]

Utilizamos la funci n wsprintf para convertir el valor de EAX ha decimales y mostrar el resultado:

Fig.3 Vea la fuente del programa prog.21. 2.- Utilizando las funciones de masm32.- Estas funciones de masm32 hacen lo mismo que las funciones de Windows, pero son diferentes al momento de utilizarlas. Vamos a crear un programa que utilice las 4 funciones similares a las anteriores.

Prog22.exe

6 En este ejercicio se ha utilizado las siguientes funciones: Librer a masm32.lib

[RVLCN]

szCmp, addr CadTexto01, addr CadTexto02


Esta funci n la utilizamos para comparar las 2 cadenas de texto que indicamos en sus par metros si son diferentes el resultado de EAX ser igual a CERO por ejemplo: invoke szCmp,addr CadTexto01,addr CadTexto02 .if eax == FALSE invoke MessageBox,.... (Mensaje de desigualdad) .else invoke MessageBox,... (Mensaje de igualdad) .endif Comparamos si el valor de EAX es igual a Cero (FALSE), si fuera as mostrara el mensaje de desigualdad de lo contrario mostrara el mensaje de igualdad Librer a masm32.lib

szLen, addr CadTexto01


Con esta funci n obtendremos la longitud de nuestra cadena de texto, despus de ser invocada EAX ser quien contenga el nmero de caracteres de nuestra cadena. Librer a masm32.lib

szCopy, addr CadTexto01, addr buffer


Esta funci n es utilizada para copiar nuestra cadena de texto CadTexto01 hacia la direcci n de la etiqueta del segundo par metro buffer, los par metros de esta funci n est n invertidos con respecto a la funci n de Windows lstrcpy Librer a masm32.lib

szCatStr, addr buffer, addr CadTexto01


Con esta funci n uniremos (concatenar), la cadena de texto que esta en el segundo par metro CadTexto01 hacia el primer buffer. Veamos otro ejercicio para que quede mas claro sobre estas funciones:

[RVLCN]

Prog23.exe La mayor parte del c digo ya sabemos lo que es nuevo es lo siguiente: invoke GetWindowText,hwndEdit1,addr CadTexto01,50 push eax invoke GetWindowText,hwndEdit2,addr CadTexto02,50 pop ebx La funci n GetWindowText como explique en el capitulo V coje el texto y adem s devuelve la longitud de la cadena a EAX. Te preguntaras que diferencia hay en usar las funciones de Windows con las funciones de masm32, solo hay una diferencia y es que cuando usamos las funciones de masm32 se agrega c digo a nuestro programa y esto puede variar en cuanto al tamao del ejecutable. 3.- Utilizando las instrucciones.- Esta parte de las clases es un poco complicado por que vamos a trabajar de byte en byte, pero are lo mas simple y entendible posible. Nosotros conocemos los c digos ACSII ( American Standard Code For Information Interchange) en castellano Americano Estandarizado para el Intercambio de Informaci n, si no sabes mucho sobre esto no importa, solo tienes que saber lo siguiente: cada letra, numero, s mbolo es representado por un c digo ACSII para su identificaci n, estos c digos est n representados por valores numricos.

[RVLCN]

Nuestro IDE RADASM contiene una tabla ACSII con algunos s mbolos, letras y nmeros. Para usar esta herramienta debemos ir al men herramientas/acsii table, si damos clic en la letra A aparece abajo su valor ACSII en hexadecimal:

Para borrar el car cter seleccionado presionamos clic derecho. Eso es todo lo b sico que debemos saber en cuanto a los c digos acsii. Ahora, tenemos el texto MASM32 + RADASM Caracteres C digo ACSII en hexadecimal Posici n M 4D 0 A 41 1 S 53 2 M 4D 3 20 4 + 2B 5 20 6 R 52 7 A 41 8 D 44 9 A S M 41 53 4D 10 11 12

En el cuadro se puede observar los valores ACSII de cada letra nuestro texto incluyendo el espacio y adem s las posiciones de cada letra que empieza desde CERO, si nosotros queremos coger la primera letra de esa palabra debemos definir la posici n cero. Bueno vasta de un poco de teor a por que yo creo m s en la pr ctica que en la teor a y es hora de los ejercicios:

[RVLCN]

3.1 Copiar un texto hacia una variable.- vamos a copiar un texto que esta en una variable hacia otra. Para copiar del texto de un lugar a otro lo haremos de 2 maneras. a.- Crearemos un bluce donde mueva car cter por car cter hacia la variable buffer y colocaremos un contador que ser comparado con la longitud m xima de la cadena: .data CadTexto01 db "CLASES DE MASM + RADASM",0 MsgTitulo db " RVLCN - 2007",0 .data? buffer db sizeof CadTexto01 dup (?) .code invoke lstrlen,addr CadTexto01 mov ebx,eax xor ecx,ecx .repeat mov al, byte ptr [CadTexto01+ecx] mov byte ptr [buffer+ecx],al inc ecx .until ecx ==ebx Como observamos en el c digo, primero obtenemos la longitud de la cadena y lo guardamos en un registro en mi caso EBX, tambin podemos guardarlo en una variable, luego limpiamos el contenido del registro ECX igual a CERO por que lo utilizaremos como contador y ascoger desde el primer car cter de nuestra cadena. mov al, byte ptr [CadTexto01+ecx] Lo que hace es mover un byte de la variable CadTexto01 hacia AL, pero si queremos especificar que car cter queremos mover, debemos sumarle la posici n donde esta dicho car cter, como vamos a copiar todo el texto debemos empezar desde la posici n cero y ir sumando 1 o incrementado 1 a nuestro contador en mi caso es el registro ECX hasta que llegue a la longitud m xima del texto y as va cogiendo nuevos caracteres segn la posici n. mov byte ptr [buffer+ecx],al Aqui movemos el contenido de Al que debe ser un car cter de nuestro texto hacia el buffer, tambin debemos colocar la posici n donde se mover el car cter nuevo es por eso que agregamos ECX para que vaya posicionando cada car cter en su respectivo lugar. Vea la fuente del programa prog.24 y prog.24b.

10

[RVLCN]

b.- la diferencia de este mtodo es que no utilizamos la longitud m xima para terminar de copiar toda la cadena, emplearemos el m todo de comprobaci n de caracteres. Como sabes cada cadena de texto que declaramos en una variable termina en el valor 0, esto es lo que debemos comparar para que termine de copiar todo el texto. xor ecx,ecx xor eax,eax .repeat mov al,byte ptr [CadTexto01+ecx] mov byte ptr [buffer+ecx],al inc ecx .until byte ptr [CadTexto01+ecx] == 0 Podemos observar lo siguiente: byte ptr [CadTexto01+ecx] == 0 Aqui comparamos si el car cter es igual a 0 que significar a el final de la cadena de texto, si es igual terminar a de copiar todo el texto. Vea la fuente del programa prog.25 y prog.25b. 3.2 Mostrar la longitud de nuestra cadena.- Para saber la longitud de la cadena debemos colocar un contador que vaya increment ndose hasta que llegue al ultimo car cter. .data CadTexto01 db "ESTAMOS EN EL CAPITULO VII",0 MsgTitulo db " RVLCN - 2007",0 MsgTexto db "La longitud de la cadena es %d",0 .data? buffer db 50 dup (?) .code xor ecx,ecx .while byte ptr [CadTexto01 + ecx] != 0 inc ecx .endw invoke wsprintf,addr buffer,addr MsgTexto, ecx En este bluce va ir incrementado ECX siempre y cuando el car cter de nuestro texto sea diferente de cero. Vea la fuente del programa prog.26 y prog.26b.

11

[RVLCN]

3.3 Sumar todos los Caracteres de nuestro texto.- Aqui vamos a crear un programa que sume todo nuestro c digo acsii de un texto y mostrar el resultado.

Prog27.exe En este programa lo nico de nuevo es lo siguiente: .repeat mov al, byte ptr [CadTexto01+ ecx] add ebx,eax inc ecx .until byte ptr [CadTexto01+ ecx] == 0 Hemos agregado la instrucci n add para sumar cada valor acsii de nuestro texto que esta en el registro eax y luego es almacenado en el registro ebx. 3.4 Comprobar caracteres de un texto.- Para ello debemos ubicar las posiciones de cada car cter y luego compararlas, vamos a ver 2 tipos de comprobaci n la total y la parcial. a.- comprobaci n total.- Aqu comprobaremos todo los caracteres de una cadena de texto: .data CadTexto01 db "MASM + RADASM",0 CadTexto02 db "MASM + RADASM",0 MsgTexto db "Los caracteres son iguales",0 MsgTitulo db " RVLCN - 2007",0

12 .code xor ecx,ecx .repeat mov al,byte ptr [CadTexto01 + ecx] .break .if byte ptr [CadTexto02 + ecx]!=al inc ecx .until ecx == 14 .if ecx == 14 invoke MessageBox,NULL... .endif

[RVLCN]

Encontramos el bloque .break que sirve para provocar una interrupci n en el bluce si cumple su condici n. Su sintaxis es de esta manera: .break .if condicion No olvidemos que para utilizar el .break debe estar dentro del bluce. .break .if byte ptr [CadTexto02 + ecx]!=al Recordemos que AL contiene el valor acsii de uno de los caracteres de nuestro texto, y la comprobaremos con uno de los valores acsii de la otra cadena, si es diferente se saldr del bluce y el contenido de ECX ser la posici n del car cter que no coincide. .if ecx == 14 invoke MessageBox,NULL... .endif Si nuestro contador ECX contiene el valor m ximo de la cadena de texto que es 14 significa que todos los caracteres son iguales. Vea la fuente del programa prog.28 y prog.28b. b.- comprobaci n parcial.- En este tipo de comprobaci n comparamos algunos caracteres de nuestra cadena por ejemplo: .data CadTexto01 db "MASM + RADASM",0 MsgTexto db "Comprobado el 5to caracter es +",0 MsgTitulo db " RVLCN - 2007",0

13 .data .if byte ptr [CadTexto01+ 5 ]== '+' invoke MessageBox...... .endif

[RVLCN]

Como observamos en el c digo, primero escribimos donde se encuentra la cadena de texto y sumamos su posici n en mi caso es el car cter +. Vea la fuente del programa prog.29 y prog.29b.

[ MACROS ]
Las macros es un conjunto de funciones o instrucciones que pueden simplificar nuestro c digo y evitar que el programador vuelva a tener que repetir cierto c digo del programa. Si vamos a la carpeta donde tenemos el masm32 instalado observamos una carpeta llamada macro con un archivo macro.asm, al abrirlo podemos observar varios tipos de macro con diferentes funciones. Nuestra primera macro que vamos ah utiliza ser la que simplificar la funci n MessageBox, nosotros para utilizar esta funci n necesitamos declarar las variables y luego colocar esas variables en sus par metros de esta funcion. Podemos simplificar todo eso con una macro y colocar el texto y el titulo de la funci n MessageBox directamente en sus par metros por ejemplo: fn MessageBox,NULL,"BiENVENiDO AL CURSO DE MASM + RADASM", \ " RVLCN - 2007",MB_OK + MB_ICONINFORMATION Claramente podemos observar que ya no hemos utilizado el invoke sino la macro fn que dentro de ella esta el invoke, pero para que podamos utilizar las macros debemos declarar en nuestro c digo o si ya esta declarados en un archivo como en nuestro caso debemos incluirla: include \MASM32\macros\macros.asm Vea el programa prog30.rap. A medida que vamos avanzando en el curso vamos aprendiendo mas sobre las macros.

14

[RVLCN]

[ Ejercicio ]
1.- Crea un programa con 3 cajas editables: La primera caja edit es para escribir el nombre del usuario La segunda caja edit es para escribir el apellido del usuario La tercera caja debe mostrar la suma del c digo acsii del nombre de usuario seguido de un gui n -mas la suma del c digo acsii del apellido del usuario.

2.- Cree un programa que genere un c digo a partir del nombre del usuario y luego comparar ese c digo con el ingresado: Para genera un c digo a partir del nombre podemos sumar todo los valores acsii del nombre y luego el resultado multiplicar, sumar, dividir por otro valor. Si el c digo ingresado esta correcto debe mostrar un mensaje afirmativo y si es incorrecto debe mostrar un mensaje de negaci n.

3.- Cree un programa que encripte nuestra cadena de texto ingresada y la muestre en otra caja edit. Para pode encriptar la cadena de texto debemos encriptar cada car cter del texto, podemos utilizar la instrucci n xor por ejemplo:

15

[RVLCN]

Mov al, byte ptr [CadTexto + ECX] xor eax,55 El valor de eax movemos a un buffer para guardarlo:

Nota: lo que se muestra en las imgenes de los ejercicios es solo un ejemplo no significa que los resultados sean iguales.

[ Recordatorio ]
No olvidar preguntar en lista MASM32-RadASM no olvide de enviar sus ejemplos a los correos: alanstr@gmail.com redhawkxp@gmail.com Lista sobre funciones en espa ol: http://winapi.conclase.net/curso/index.php?tab=Funciones Dudas, sugerencias, otros, hacerlas en lista.

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com http://RVLCNsecurity.com http://beam.to/RVLCN http://beam.to/REVOLUCION

16

[RVLCN]

Febrero-2007

Copyright(c) 2005-2006 RVLCN

[RVLCN]

C L A SE S de P r og r a m a c i On C ON M A SM + Ra da sm
C a pi tu l o V III: L i br er i a s d e enl ac e Di na mi c o.
& Array

Escrito por: ^A|An M0r3N0^


Consejero: RedH@wk
DESCARGO LEGAL

EL presente escrito,creado para fines educacionales e investigaci n. Es de libre distrubucion, siempre que se conserve intacto el contenido y se precise derechos de autor

[RVLCN]

[ Librer as de enlace din mico DLL ]


En nuestro sistema operativo y otros programas que tenemos instalado en windows hemos visto libreras de enlace dinmico su extensi n es .dll Windows tiene su propia colecci n como por ejemplo user32.dll, kernel32.dll, gdi32.dll y como esas hay un mont n, cada una de ellas tiene funciones que utiliza windows y nosotros durante las clases de masm32 la hemos utilizado tambi n. Lo primero que vamos hacer es crear nuestra propia librera y luego mostrare 2 m todos para utilizar las funciones de nuestra DLL. 1.- Estructura de una DLL..386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .data .code Punto_de_Inicio proc hInstance: DWORD, reason:DWORD, rsrvd1:DWORD mov eax,TRUE ret Punto_de_Inicio Endp // Aqu se programara las funciones. End Punto_de_Inicio La estructura de la DLL es similar a un ejecutable, pero hay una diferencia, se trata de que toda librera necesite un punto de inicio o de entrada como lo dicen algunos, Es necesario darle un valor EAX como por ejemplo si es TRUE queremos decir que la DLL se ha cargado correctamente y si pusi ramos FALSE a EAX estaremos diciendo que se cargo incorrectamente. Otra cosa que observamos es que parmetros: la funci n Punto_de_Inicio tiene 3

3 hInstance.- Aqu encontramos el manejador de nuestra DLL (handle).

[RVLCN]

reason.- Este parmetro puede tomar 4 valores seg n la direcci n del proceso:
DLL_PROCESS_ATTACH.- Se recibe este valor cuando se carga la librera en el

proceso.
DLL_PROCESS_DETACH.- Se recibe este valor cuando se descarga la librera

en el proceso.
DLL_THREAD_ATTACH.- Se recibe este valor cuando se crea un hilo de

proceso.
DLL_THREAD_DETACH.- Se recibe este valor cuando se ha destruido el hilo del

proceso. rsrvd1.- Parmetro utilizado por windows, normalmente no se utiliza. Toda DLL necesita un archivo de modulo para definir el nombre de la librera y las funciones que se exportara a otros programas. EL Archivo tiene como extensi n .def donde su contenido es por ejemplo lo siguiente:
LIBRARY EXPORTS

Nombre_de_la_libreria Funcion_01 Funcion_02 Funcion_03

Eso es todo lo que debemos saber antes de programar nuestra primera DLL en masm32. Antes de seguir necesito que agregues la plantilla Libreria.tpl a nuestro IDE RadASM, solo debes copiar el archivo en donde tienes el RadASM, en su carpeta Masm\Templates por ejemplo: C: \RadASM\Masm\Templates Una vez hecho eso vea el siguiente video:

[RVLCN]

MI_DLL_01.exe Cuando se programa una DLL se hace de igual manera que un ejecutable se puede usar variables, funciones etc. la nica diferencia es en el proceso de ensamblado cuando se crea la DLL es necesario enlazar tambi n el archivo .def, adems al compilar se ha creado un archivo importante para llamar a las funciones de una DLL, este archivo es necesario para emplear el primer m todo del uso de una funci n que tenga una DLL, por eso es importante copiar el archivo que tiene la extensi n .LIB MI_DLL_01.lib , a la carpeta donde vamos a crear el programa ejecutable. El siguiente paso es crear un programa para llamar a nuestras funciones que esta en la DLL y les ense are dos m todos. 1 Metodo Utilizando el archivo .LIB .- Este m todo se basa en llamar a la funci n con el operador invoke para ello debemos agregar el archivo .lib y declarar las funciones exportadas que vamos a utilizar. He creado un video para que vean de qu se trata este m todo:

[RVLCN]

prog31.exe Es sencillo utilizar funciones de una DLL cuando se tiene el archivo .LIB, en el capitulo II explique para que servan ese tipo de archivos en un programa, pero si te haz olvidado, pues sirven para enlazar nuestra DLL con el ejecutable y adems contiene informaci n sobre el nombre y la direcci n donde se encuentra las funciones. Ahora, que pasara si no tienes el archivo .lib de una DLL, en este caso lo primordial es tener el nombre de la funci n y lo puedes saber utilizando alg n desamblador de programas como W32dasm o el de tu preferencia. Mas adelante te ense are a crear un archivo .lib de una DLL si en caso no lo tuvieras, pero eso no lo vamos ha ver en este capitulo. 2 Metodo Utilizando las Funciones LoadLibrary, GetProcAddress y Freelibrary .Con este m todo es un poco lioso pero tal vez alg n da te pueda servir, lo primero que debemos hace es cargar la librera con la funci n LoadLibrary y luego necesitamos la direcci n de la funci n para poder llamarla, para ello utilizamos la funci n GetPorcAdress. He preparo un video sobre este m todo espero que se pueda entender:

[RVLCN]

prog32.exe Librer a Kernel32.lib

LoadLibrary,addr Nombre_DLL
Con esta funci n cargamos la DLL, debemos especificar el nombre de la DLL en su primer parmetro, si la librera fue cargada correctamente devolver a EAX el manejador (Handle), luego lo almacenane en la variable handle_DLL, si no tu xito en cargar la DLL la funci n devolver 0 a EAX. mov handle_DLL,eax .if EAX== NULL invoke MessageBox, .else invoke GetProcAddress, .endif En esta parte del c digo comprobamos si EAX es igual a 0, si lo fuera as mostrara un mensaje para informar sobre este error, de lo contrario llamaremos a la funci n GetProcAddress.

[RVLCN]

Librer a kernel32.lib

GetProcAddress,addr handle_DLL ,addr Nombre_DLL


Con esta API podemos saber la direcci n en la memoria donde se encuentra dicha funci n para luego ser llamada con la instrucci n CALL. En esta funci n es importante indicar el manejador de la DLL y el nombre de la funci n. Si existe la funci n en la DLL devolver la direcci n a EAX para ser almacenado en la variable Direccion_Funcion, de lo contrario devolver 0. mov Direccion_Funcion,eax .if eax == NULL invoke MessageBox, .else Call Direccion_Funcion .endif Debemos comparar EAX si es igual a 0 para saber si la funci n realmente existe en dicha DLL si no existiera mostrara un mensaje de advertencia, de lo contrario llamara a la funci n: Call Direccion_Funcion Librer a Kernel32.lib

FreeLibrary,addr handle_DLL
Con esta funci n descargamos la librera de la memoria, eso lo hacemos cuando ya no la necesitemos o cuando terminamos el programa. En su parmetro es importante indicarle el manejador de la DLL que vas a descargar. En el siguiente ejemplo que presentare a continuaci n declararemos una funci n que tenga uno o mas parmetros, esto ya lo hemos hecho en el capitulo III - pagina 11 sobre como crear tus propias funciones, se hace igual forma que con una DLL.

[RVLCN]

prog33AyB.exe En el primer m todo que acabamos de ver en video no hay problema por que ya lo hemos explicado anteriormente. Con el segundo m todo, siempre que queremos definir alg n parmetro de la funci n necesitamos usar la instrucci n PUSH en forma ordena. Por ejemplo si nuestra funci n fuera de esta manera: Funcion01 PROC P1:DWORD, P2:DOWRD, P3:DWORD Si queremos definir sus parmetros al momento de usar esa funci n, el orden para hacerlo seria as: PUSH P3 PUSH P2 PUSH P1 CALL Funcion01 N tese que el primer PUSH es el ltimo de la funci n declara arriba, ese seria el orden correcto de hacerlo.

[RVLCN]

[ Array ]
Si alguna vez has escuchado array en programaci n sabrs de que se trata este tema, pero para los que no saben es un grupo de variables del mismo tipo con una etiqueta en com n. Cada array est en diferentes posiciones de la memoria contiguas, as que la direcci n ms baja corresponde al primer elemento.

prog34AyB.exe 1.- En el ejemplo prog34A hemos visto como hacemos para utilizar un sola variable para cambiar el texto del mensaje cada vez que presionamos el bot n del programa. Es importante saber que la posici n mas baja es cero, y es el primer mensaje que pusimos, no olvidemos que debemos multiplicar por 4: Posici n Variables 0 MsgTexto01 1 MsgTexto02 2 MsgTexto03 3 MsgTexto04

invoke MessageBox,NULL, Todo_MsgTexto[ebx * 4] El registro EBX es quien tiene las posiciones de los textos, es importante saber que ya no fue necesario agregar el operador addr.

10

[RVLCN]

2.- En el ejemplo prog34B, se ha elaborado un programa que al presionar cualquier bot n nos lleva a la misma funci n, comprobando cada uno de los botones desde una variable en com n. Aqu tambi n se determino en que posiciones estaban las ID de los botones de esta manera: .if (edx==Botones[0 * 4]) || (edx==Botones[1 * 4]) || (edx ==Botones[2 * 4]) || \ (edx==Botones[3 * 4]) || (edx==Botones[4 * 4]) Las posiciones de los botones estn marcadas con azul.

[ Ejercicios ]
1.- Tienes el archivo .inc y .lib de la librera de valores aleatorios: rvlcnrand.Inc rvlcnrand.lib Con 5 funciones randzime PROTO random PROTO uniform PROTO range PROTO :DWORD,:DWORD urange PROTO :DWORD,:DWORD Cree una DLL, para que se pueda exportar esas 5 funciones a cualquier programa de Windows. 2.- Utilice una variable tipo array con mas de 7 cadenas de texto, al presionar un bot n, el titulo de mi ventana debe ser cualquiera de las 7 cadenas de texto. Para cambiar el titulo de una ventana puede utilizar las siguientes funciones. SetWindowText para ventanas hechas con APis. SetDlgItemText para ventanas hechas con cajas de dialog.

11

[RVLCN]

[ El autor puede ser contactado ]


eMail: AlanStr@gmail.com Oberon@rvlcnsecurity.com Lista MASM32-RadASM http://groups.google.es/group/MASM32-RadASM www: http://RVLCN.com http://RVLCNsecurity.com http://beam.to/RVLCN http://beam.to/REVOLUCION
Julio-2007

Copyright(c) 2005-2007 RVLCN