curso radasm_cap i-viii

111
1 [RVLCN ] C LA SES de P r ogr a m a c iOn C ON M A SM +Ra da sm C a pitul o I:Ins ta l a ci o n y C o nfigura 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

Upload: grand-brother

Post on 13-Aug-2015

291 views

Category:

Documents


8 download

TRANSCRIPT

Page 1: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo I : I n s ta la cio n y C o nfigur a cio 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

Page 2: Curso Radasm_cap I-Viii

2 [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

Page 3: Curso Radasm_cap I-Viii

3 [RVLCN]

3.-Necesitamos saber sobre las Funciones de Windows: Win32 Programmer’s Reference: http://www.rvlcnsecurity.com/clases/anexo/win32api.rar 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

Page 4: Curso Radasm_cap I-Viii

4 [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:

Page 5: Curso Radasm_cap I-Viii

5 [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:

Page 6: Curso Radasm_cap I-Viii

6 [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:

Page 7: Curso Radasm_cap I-Viii

7 [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:

Page 8: Curso Radasm_cap I-Viii

8 [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 menú Option/Programming Languages, como muestra la siguiente imagen:

Fig. 15

Damos Clic y sale una ventana para agregar el lenguaje de programació n:

Page 9: Curso Radasm_cap I-Viii

9 [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:

Page 10: Curso Radasm_cap I-Viii

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

Page 11: Curso Radasm_cap I-Viii

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:

Page 12: Curso Radasm_cap I-Viii

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.

Page 13: Curso Radasm_cap I-Viii

13 [RVLCN]

[ El autor puede ser contactado ] eMail: [email protected] [email protected] 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

Page 14: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo I I : N ue str a Pr ime r a A p lica cio 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.

Page 15: Curso Radasm_cap I-Viii

2 [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.- Aquí establecemos 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?).

Page 16: Curso Radasm_cap I-Viii

3 [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 Tipo de variable Datos inicializados MsgTexto db “BiENVENIDO AL CURSO DE MASM + RADASM”,0 Valor_1 dd 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 Tipo de variable Datos No inicializados Buffer db 128 dup (?) Valor_1 dd ? .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

Page 17: Curso Radasm_cap I-Viii

4 [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 parámetro sirve para identificar el manejador de la ventana padre, nuestro caso colocamos NULL ó “0” por que no tiene manejador (handle). LpText.- Aquí colocamos la direcció n donde se encuentra nuestro mensaje. LpCaption.- En este parámetro funciona igual que lpText la diferencia que este es el titulo del mensaje uType.- Este parámetro 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 están declaradas en el archivo window.inc

MB_OK MB_ICONINFORMATION Para saber más 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 );

Page 18: Curso Radasm_cap I-Viii

5 [RVLCN]

Con esta funció n cerramos nuestro programa, en el parámetro 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 parámetros de nuestra funció n son los correctos y se emplea de esta manera: INVOKE FUNCION, Argumentos FUNCION.- Es aquí donde escribiremos el nombre de la funció n que se va ah utilizar. Argumentos.- Los argumentos son los parámetros de las funciones y están 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 offset No puede ser utilizado con instrucciones mnemonic

Se utiliza con instrucciones mnemonic

Trabaja Solo con referencias que esté n delante del có digo.

Trabaja con referencias que esté n delante y atrás del có digo.

Puede operar con estructuras. No 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 dinámico (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:

Page 19: Curso Radasm_cap I-Viii

6 [RVLCN]

Fig. 1

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

Fig. 2

Page 20: Curso Radasm_cap I-Viii

7 [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 dinámico 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 ]

Tipos de Variables Tipo Abreviatura Espacio Descripció n

BYTE DB 1 byte ó 8 bits Cadenas de texto y caracteres WORD DW 2 bytes ó 16

bits Valor entero en el rango: -32,

786 a +65, 535 DWORD DD 4 bytes o 32

bits Valor entero en el rango: -2gb a

+4gb FWORD ó

REAL4 DF 6 bytes o 48

bits 48 bit con punto flotante

QWORD ó REAL8

DQ 8 bytes o 64 bits

64 bit con punto flotante

TBYTE ó REAL10

DT 10 bytes o 80 bits

80 bit con punto flotante

Page 21: Curso Radasm_cap I-Viii

8 [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 “BiENVENIDO AL CURSO DE MASM + RADASM”,0 Valor dd 77 Punto df 4.575

Que viene hacer lo mismo : .data Cadena BYTE “BiENVENIDO AL CURSO DE MASM + RADASM”,0 Valor DWORD 77 Punto REAL4 4.575

EJEMPLO EN DATOS NO INICIALIZADOS .data? Acumulador db ? Contador dd ? FlotanteP df ?

Que viene hacer lo mismo : .data? Acumulador BYTE ? Contador DWORD ? FlotanteP 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:

Page 22: Curso Radasm_cap I-Viii

9 [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:

Page 23: Curso Radasm_cap I-Viii

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 más 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 máxima 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.

Page 24: Curso Radasm_cap I-Viii

11 [RVLCN]

3.- Hagamos nuestro programa más grande y un poco más 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.

Page 25: Curso Radasm_cap I-Viii

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 Variable Contador DUP Valor Inicial Buffer db 225 dup (?) NombreApp db 50 dup (?) 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 más 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 parámetros 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.

Page 26: Curso Radasm_cap I-Viii

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 están 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 serán 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: [email protected] [email protected] 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

Page 27: Curso Radasm_cap I-Viii

1 [RVLCN]

C l a ses de P r o gr a m a c iO n C O N M ASM +Ra da sm

C a p itulo I I I : R e gis tro s de l M icro Pro ce 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.

Page 28: Curso Radasm_cap I-Viii

2 [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

Descripció n

EAX (Acumulador) Es utilizado para operaciones aritméticas (suma, resta, divisió n, multiplicació n). Algunas Funciones después de ser utilizadas devuelven un valor a EAX.

EBX (Base) Se utiliza para direccionar el acceso a datos, situados en la memoria, también se puede utilizar para operaciones aritméticas.

ECX (Contador) Se utiliza como contador por algunas instrucciones, también es utilizado para operaciones aritméticas.

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 también 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.

Page 29: Curso Radasm_cap I-Viii

3 [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) Destino

DEC (Decrementa 1) 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.

Page 30: Curso Radasm_cap I-Viii

4 [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” Instrucciones Ló gicas: Utiliza la calculadora de Windows (modo científica) para 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

Page 31: Curso Radasm_cap I-Viii

5 [RVLCN]

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

NOT Destino 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

Page 32: Curso Radasm_cap I-Viii

6 [RVLCN]

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 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

Page 33: Curso Radasm_cap I-Viii

7 [RVLCN]

Haremos un programa que haga la siguiente operació n: 1Ah + 500 = X El resultado X restamos 1C2h: X – 1C2 = Y 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.

Page 34: Curso Radasm_cap I-Viii

8 [RVLCN]

[ Mostrando Resultados ] En nuestro có digo anterior no mostramos el resultado de la operació n aritmética, 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

Page 35: Curso Radasm_cap I-Viii

9 [RVLCN]

Librería MAsm32.lib 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

Page 36: Curso Radasm_cap I-Viii

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.

Page 37: Curso Radasm_cap I-Viii

11 [RVLCN]

Esquema de trabajo:

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

Page 38: Curso Radasm_cap I-Viii

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.- Aquí escribimos 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 también lo utilizamos para separar nuestros có digos, como en el primer RET

Page 39: Curso Radasm_cap I-Viii

13 [RVLCN]

que esta debajo de la funció n ExitProcess, en el operando Nº Bytes es opcional ahí se especifica cuantos bytes debe retornar. 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, también 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 devolverá error.

Page 40: Curso Radasm_cap I-Viii

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.

Page 41: Curso Radasm_cap I-Viii

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: [email protected] [email protected] 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

Page 42: Curso Radasm_cap I-Viii

16 [RVLCN]

Copyright(c) 2005-2006 RVLCN

Page 43: Curso Radasm_cap I-Viii

c l a ses de P r o gr a m a c iO n CO N M ASM +Ra da sm

C a p itulo I V: C o n dic io n es y bluc es.

Escrito por: ^A|An M0r3N0^

Consejero: RedH@wk

DESCARGO LEGAL

DOCUMENTO ESCRiTO PARA FiNES DE EDUCACiON/iNVESTiGACION

Page 44: Curso Radasm_cap I-Viii

Masm32 tambié n puede utilizar el bloque .if (condición) y tambié n .while, .repeat/.until (bluces) aprenderemos 2 formas de cómo utilizarlas, la primera será utilizando 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 comparación simple seria de esta manera:

Simple Simple mas .else .if Condicion ; Si cumple la condición ara algo acá. .endif

.if Condicion ; Si cumple la condición ara algo acá. .else ; Si no cumple la condición ara algo acá. .endif

Si deseas hacer comparaciones secuenciales:

Secuencial Secuencial mas .else .if Condicion ; Si cumple la condición ara algo acá .elseif Condicion ; Si cumple la condición ara algo mas. .endif

.if Condicion ; Si cumple la condición ara algo acá .elseif Condicion ; Si cumple la condición ara algo mas .else ; Si no cumple con ninguna condición ara algo acá. .endif

Antes de entrar con los ejercicios observemos la siguiente tabla de operadores para las comparaciones:

Operadores de comparación == igual != No igual > Mayor >= Mayor o igual < Menor <= Menor o igual

Operadores de Multi - comparación && Lógico AND “Y”

Page 45: Curso Radasm_cap I-Viii

|| Lógico 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 librería 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.

Librería rvlcnrand.lib Función Descripción

randzime Con esta función 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 podrá generar en forma aleatoria.

random Genera números al azar uniformemente distribuido utilizando un algoritmo lineal, el resultado es devuelto en EAX. Invoke random

range Genera un número al azar usando la función random, teniendo en cuenta el rango establecido, el resultado es devuelto en EAX. Invoke range, inicio, final

uniform Esta función genera un nuevo número al azar en cada llamada uniformemente distribuido, el resultado es devuelto en EAX. Invoke uniform

urange Genera un número al azar usando la función urange, teniendo en cuenta el rango establecido, el resultado es devuelto en EAX. Invoke urange, inicio, final

Page 46: Curso Radasm_cap I-Viii

Ejemplo:

prog005_ha_c.exe

Analizando prog005.- Como ya habíamos visto en la ayuda “win32programmer’s Referenced” la función Messagebox una vez ejecutado devuelve a EAX el valor del botón 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 botón Yes o Si en españ ol, y si cumple la condición mostrara el mensaje que hemos puesto.

Page 47: Curso Radasm_cap I-Viii

Analizando prog005a.- Este programa es idé ntico al ejercicio anterior, solo hemos agregado el bloque .else en caso que la condición 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 condición 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 función 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 botón Cancel no lo hemos tomado en cuenta en este ejercicio, pero si deseas lo puedes agregar. Analizando prog005c.- En este ejercicio hemos utilizado la librería rvlcnrand.lib, pare crear una serie de comprobaciones utilizando la mayoría 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

Page 48: Curso Radasm_cap I-Viii

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, fíjate que el operador && es un enlazador para otra comparación 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 instrucción compara los dos operándos, a su vez modifica las banderas el microprocesador AF, CF, OF, PF, SF, ZF.

jxx (salta) Etiqueta Esta instrucción salta hacia una dirección, veamos la tabla de algunos saltos y significados:

Instrucción Descripción Estado de Bandera JA Salta si esta sobre CF=0 y ZF=0

JAE Salta si esta sobre o igual CF=0 JB Salta si esta debajo CF=1

JBE Salta si esta debajo o igual CF=1ó ZF=1 JE Salta si es igual ZF=1 JG Salta si es mayor ZF=0 ó SF=OF

JGE Salta si no es mayor SF=OF JL Salta si es menor SF != OF

JLE Salta si es menor o igual ZF=1 ó SF != OF JMP Salta directamente - JNA Salta si no esta sobre CF=1 ó ZF=1

JNAE Salta si no esta sobre o igual CF=1 JNB Salta si no esta debajo CF=0

JNBE Salta si no esta debajo o igual CF=0 y ZF=0 JNE Salta si no es igual ZF=0 JNG Salta si no es mayor ZF=1 ó SF != OF

Page 49: Curso Radasm_cap I-Viii

JNGE Salta si no es mayor o igual SF != OF JNL Salta si no es menor SF=OF

JNLE Salta si no es menor o igual ZF=0 y SF=OF Te preguntaras que sirve el estado de bandera o Flag, cada instrucción 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 instrucción no necesita ninguna condicion para ejecutarse. Es por eso que la instrucción CMP modifica esas banderas para ejecutar el salto que le hemos puesto en la siguiente línea. 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.

Page 50: Curso Radasm_cap I-Viii

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 librerías rvlcnrand.lib para generar un valor aleatorio y la librería masm.lib por que se usara la función 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

Page 51: Curso Radasm_cap I-Viii

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 condición que hemos determinado. .while .- Este bloque creara un lazo o bluce siempre y cuando cumpla la condición, 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 instrucción cmp, luego esta el salto JA (salta si esta sobre), en este caso salta si eax esta sobre 1, este lazo se romperá cuando eax sea 0. .repeat/ .until.- Este lazo funciona al contrario de .while, en este caso el lazo terminara cuando cumpla la condición y su sintaxis es así: .repeat ;codigo .until condicion

Page 52: Curso Radasm_cap I-Viii

Ejemplo: mov eax,0 .repeat add eax, 1 ; sumamos 1 al contenido de eax .until eax > 6 El lazo se romperá hasta 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:

Librería User32.lib FindWindow,NULL,addr Titulo_ventana

Page 53: Curso Radasm_cap I-Viii

Fig.02

Esta función 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 información revisen la documentación Win32Programmer Referenced Fig.02.

Línea 9.- Buscamos el titulo de la ventana, si la encuentra devolverá el 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 función 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á.

Page 54: Curso Radasm_cap I-Viii

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

Línea 9.- Creamos un punto al azar o semilla para que pueda crear valores al azar la función range. Línea 10.- La función range devuelve a EAX un valor comprendido desde 0 hasta 100. Este bluce se repetirá hasta 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 función range.

Librería kernel32.lib wsprintf wsprintf,addr buffer,addr Msgtexto, ebx Con esta función 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 función 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:

Page 55: Curso Radasm_cap I-Viii

%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 función 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 aplicación: [ 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.

Page 56: Curso Radasm_cap I-Viii

[ Agregando una herramienta ] Alguna vez te has preguntado como saber que funciones pertenecen a cada librería?. Pues a nuestro RADASM le agregaremos un programa para buscar la función y nos muestre que librería 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 función wsprintf y generando un valor aleatorio, crea un programa muestra un mensaje mostrado el valor en decimal y en hexadecimal:

Page 57: Curso Radasm_cap I-Viii

[ 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 estará enviando las soluciones de los ejercicios anteriores Dudas, sugerencias, otros, hacerlas en lista. [ El autor puede ser contactado ] eMail: [email protected] [email protected] 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

Page 58: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo V : N ue str a p r ime 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

Page 59: Curso Radasm_cap I-Viii

2 [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 atención:

Prog009.exe

Librería kernel32.lib

GetModuleHandle, NULL Esta función devuelve el handle del modulo o instancia del programa, todos los programas que utilizan ventanas utilizan esta función, 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 información requerida para crear nuestra ventana, esa información nosotros la ponemos con la instrucción 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:

Page 60: Curso Radasm_cap I-Viii

3 [RVLCN]

typedef struct _WNDCLASSEX { // wc 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; 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 instrucción OR: mov wc.style, CS_HREDRAW or CS_VREDRAW 3.- lpfnWndProc definimos la dirección 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

Page 61: Curso Radasm_cap I-Viii

4 [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 dirección 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 función 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 función:

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 función no solo sirve para eso, tambié n puede crear controles de ventanas

Page 62: Curso Radasm_cap I-Viii

5 [RVLCN]

llamadas hijas como botones, edit, static, listbox, etc, es por eso que vamos a analizar que rol cumple cada pará metro de esta función: 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 función quedaría de esta manera: Invoke CreateWindowEx, WS_EX_TOPMOST, addr Classname..... Si quieres saber mas estilos vea Win32 Programmer’s Referenced. 2.- lpClassName definimos la dirección de la etiqueta donde se encuentra el nombre (ACSII) de clase de la ventana. 3.- lpWindowName definimos la dirección 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 botón maximizar habilitado nuestra función quedaría así:

Page 63: Curso Radasm_cap I-Viii

6 [RVLCN]

CreateWindowEx, NULL, addr Classname, addr Appname, WS_SYSMENU or WS_MAXIMIZEBOX,...... No olvidar que si queremos combinar estilos usamos la instrucción OR. 5.- X especifica la coordenada de la posición horizontal de la ventana cliente. 6.- Y especifica la coordenada de la posición 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 botón el rango de las coordenadas estará dentro de la ventana padre:

Fig .2

Page 64: Curso Radasm_cap I-Viii

7 [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 botón 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 botón 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 código hemos visto un nuevo bloque el

Page 65: Curso Radasm_cap I-Viii

8 [RVLCN]

.break este bloque es de interrupción al bluce sirve para terminar el bluce si cumple la condición su sintaxis es así: .break condicion ;si cumple la condició n saldrá del bluce. En nuestro programa la condición 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 ahí donde 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 función 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:

Page 66: Curso Radasm_cap I-Viii

9 [RVLCN]

Plantilla02.exe

Si nos damos cuenta en la planilla que hemos visto sea creado una función, 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 código 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:

Page 67: Curso Radasm_cap I-Viii

10 [RVLCN]

LOCAL Etiqueta : tipo de Variable/Estructura Otra cosa importante que observamos son estos tipos de variables: HWND UINT WPARAM LPARAM HINSTANCE LPSTR 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 código 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

Page 68: Curso Radasm_cap I-Viii

11 [RVLCN]

Solución 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 función, 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:

Page 69: Curso Radasm_cap I-Viii

12 [RVLCN]

mov hwnd_boton01,eax 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 código de notificación 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 botón una función, en este caso el botón 01 mostrara un mensaje y el botón 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 función destruimos la ventana padre.

Page 70: Curso Radasm_cap I-Viii

13 [RVLCN]

Seguimos con el programa de la figura 5.

prog011.exe

Hemos encontrado 2 APIs nuevas:

Librería kernel32.lib GetWindowText, hwnd_edit01,addr buffer,100 Esta función coje el texto de las ventanas tiene 3 pará metros y son las siguientes: hWnd.- Identificamos la ventana colocando el manejador del control. lpString.- Dirección 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 función enviamos el texto a las ventanas, contiene 2 pará metros. hWnd.- Identificamos la ventana colocando el manejador del control. Lpsz.- Dirección de la memoria donde se encuentra el texto.

Page 71: Curso Radasm_cap I-Viii

14 [RVLCN]

En ambos programas hemos puesto diferente icono a nuestras ventanas, la sección .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 condición que si presionamos el botón 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 función MessageBox de esta manera: invoke MessageBox,hWnd,addr MsgSalir,addr TitSalir, MB_YESNO+

MB_ICONINFORMATION

Luego para comparar que botón se ha presionado llamamos al bloque .if y nuestro código quedara así:

Page 72: Curso Radasm_cap I-Viii

15 [RVLCN]

.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 botón que se ha presionado. [ Ejercicios ] 1.- Cree una ventana del tamañ o de tu escritorio. 2.- Cree una ventana con 5 botones, cada botón debe mostrar diferentes mensajes. 3.- Cree un programa igual ha este:

Nota: al presionar el botón 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.

Page 73: Curso Radasm_cap I-Viii

16 [RVLCN]

[ El autor puede ser contactado ] eMail: [email protected] [email protected] 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

Page 74: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo V I: C a j a s D e dia lo 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

Page 75: Curso Radasm_cap I-Viii

2 [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 código para mostrar una ventana simple utilizando las cajas de dialog es má s sencillo que cuando lo hacemos con puras APIS, veamos el código en el archivo prog13.inc:

Librería user32.lib DialogBoxParam, hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL Esta función 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 dirección 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:

Page 76: Curso Radasm_cap I-Viii

3 [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 sección 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 dirección 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

Page 77: Curso Radasm_cap I-Viii

4 [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 excepción 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 botón 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 código de notificación, para que quede mas claro fíjense en el siguiente cuadro:

Page 78: Curso Radasm_cap I-Viii

5 [RVLCN]

wParam lParam HIGH LOW

CONTROLES (botones, edit,static, etc.)

Contiene el Código de notificación

Contiene el manejador de la ventana hija (handle).

Menú Sin Utilidad

Contiene el ID

Sin Utilidad Ejemplo supongamos que wParam contenga el valor 12345678 entonces: El código de notificación: 1234 El ID del control: 5678 Este es un ejemplo de cómo extraer el código de notificación: 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 instrucción 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 instrucción 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 código de notificación, si se va a trabajar con ello.

Page 79: Curso Radasm_cap I-Viii

6 [RVLCN]

BN_CLICKED este código de notificación se envía cuando pulsamos cualquier botón, yo no lo utilizo por que este valor de notificación 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 código de notificación: 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 código de notificación es igual a 0, es por eso que yo me ahorro todo ese código y de frente comparo los ID por que se que el código de notificación 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 continuación vamos ha trabajar con algunos campos editables:

Prog15.exe

Page 80: Curso Radasm_cap I-Viii

7 [RVLCN]

Librería user32.lib GetDlgItemText, hWin,edit01,addr buffer,225 Esta función trabaja con cajas de dialog, esta función 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.- Dirección 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 función 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.- Dirección de la memoria donde se encuentra el texto. [ Agregando Icono ] Ahora agregaremos un icono a nuestra aplicación:

Prog16.exe

Page 81: Curso Radasm_cap I-Viii

8 [RVLCN]

Librería user32.lib SendMessage, hWin,edit01,addr buffer Esta función 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 información adicional del mensaje. lParam.- especificamos información 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 función 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 función, para ello creamos un programa igual al de la imagen:

Fig.2

Page 82: Curso Radasm_cap I-Viii

9 [RVLCN]

Estos dos botones cierran la ventana, y su funcionamiento es lo siguiente: el primer botón envía un mensaje a la ventana para que se ejecute la función del botón 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 código: .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 función 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 botón “enviar” muestre un mensaje con el texto que pusimos en el campo edit como muestra la imagen:

Page 83: Curso Radasm_cap I-Viii

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 botón.- Debe hacer la suma. El segundo botón.- Debe borrar todo los campos edit. El tercer botón.- 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 instrucción 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 función que es la wsprintf.

Page 84: Curso Radasm_cap I-Viii

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: [email protected] [email protected] 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

Page 85: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo V I: M a n e jo de C a de n a s .

M a cro 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

Page 86: Curso Radasm_cap I-Viii

2 [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 después 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”.

Page 87: Curso Radasm_cap I-Viii

3 [RVLCN]

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

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 mayúscula ni minúscula al momento de comparar, pero hay una funció n derivada de esta que si omite las mayúsculas 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 (?)

Page 88: Curso Radasm_cap I-Viii

4 [RVLCN]

.code invoke lstrcpy,addr buffer,addr CadTexto01 invoke MessageBox,NULL,addr buffer,addr MsgTitulo,MB_OK + \ MB_ICONINFORMATION invoke ExitProcess,0 end 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 (?)

Page 89: Curso Radasm_cap I-Viii

5 [RVLCN]

.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 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

Page 90: Curso Radasm_cap I-Viii

6 [RVLCN]

En este ejercicio se ha utilizado las siguientes funciones:

Librería masm32.lib 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, después de ser invocada EAX será quien contenga el número 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:

Page 91: Curso Radasm_cap I-Viii

7 [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 tamaño 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 numéricos.

Page 92: Curso Radasm_cap I-Viii

8 [RVLCN]

Nuestro IDE RADASM contiene una tabla ACSII con algunos símbolos, letras y números. 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 M A S M + R A D A S M Có digo ACSII en hexadecimal

4D 41 53 4D 20 2B 20 52 41 44 41 53 4D

Posició n 0 1 2 3 4 5 6 7 8 9 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:

Page 93: Curso Radasm_cap I-Viii

9 [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, también podemos guardarlo en una variable, luego limpiamos el contenido del registro ECX igual a CERO por que lo utilizaremos como contador y así coger 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 según 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, también 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”.

Page 94: Curso Radasm_cap I-Viii

10 [RVLCN]

b.- la diferencia de este método 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”.

Page 95: Curso Radasm_cap I-Viii

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

Page 96: Curso Radasm_cap I-Viii

12 [RVLCN]

.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 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

Page 97: Curso Radasm_cap I-Viii

13 [RVLCN]

.data .if byte ptr [CadTexto01+ 5 ]== '+' invoke MessageBox...... .endif 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.

Page 98: Curso Radasm_cap I-Viii

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:

Page 99: Curso Radasm_cap I-Viii

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 imágenes 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: [email protected] [email protected] 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: [email protected] [email protected] 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

Page 100: Curso Radasm_cap I-Viii

16 [RVLCN]

Febrero-2007

Copyright(c) 2005-2006 RVLCN

Page 101: Curso Radasm_cap I-Viii

1 [RVLCN]

C L A SES de P r og r a m a c iOn C ON M A SM +Ra da sm

C a p itulo V III: L ibr er ia s d e enla ce Dina mico .

& 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

Page 102: Curso Radasm_cap I-Viii

2 [RVLCN]

[ Librerías de enlace dinámico “ DLL” ] En nuestro sistema operativo y otros programas que tenemos instalado en windows hemos visto librerías de enlace dinámico 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 librería 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 librería 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 la función Punto_de_Inicio tiene 3 parámetros:

Page 103: Curso Radasm_cap I-Viii

3 [RVLCN]

hInstance.- Aquí encontramos el manejador de nuestra DLL (handle). reason.- Este parámetro puede tomar 4 valores segú n la dirección del proceso: DLL_PROCESS_ATTACH.- Se recibe este valor cuando se carga la librería en el proceso. DLL_PROCESS_DETACH.- Se recibe este valor cuando se descarga la librería 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.- Parámetro utilizado por windows, normalmente no se utiliza. Toda DLL necesita un archivo de modulo para definir el nombre de la librería 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 Nombre_de_la_libreria EXPORTS 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:

Page 104: Curso Radasm_cap I-Viii

4 [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, además 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:

Page 105: Curso Radasm_cap I-Viii

5 [RVLCN]

prog31.exe

Es sencillo utilizar funciones de una DLL cuando se tiene el archivo .LIB, en el capitulo II explique para que servían ese tipo de archivos en un programa, pero si te haz olvidado, pues sirven para enlazar nuestra DLL con el ejecutable y además contiene información sobre el nombre y la dirección donde se encuentra las funciones. Ahora, que pasaría 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 día te pueda servir, lo primero que debemos hace es cargar la librería 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:

Page 106: Curso Radasm_cap I-Viii

6 [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 parámetro, si la librería 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.

Page 107: Curso Radasm_cap I-Viii

7 [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 librería de la memoria, eso lo hacemos cuando ya no la necesitemos o cuando terminamos el programa. En su parámetro 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 parámetros, 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.

Page 108: Curso Radasm_cap I-Viii

8 [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 parámetro 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 parámetros 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.

Page 109: Curso Radasm_cap I-Viii

9 [RVLCN]

[ Array ] Si alguna vez has escuchado array en programación sabrás 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 más 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 0 1 2 3 Variables MsgTexto01 MsgTexto02 MsgTexto03 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.

Page 110: Curso Radasm_cap I-Viii

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 están marcadas con azul. [ Ejercicios ] 1.- Tienes el archivo .inc y .lib de la librería 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.

Page 111: Curso Radasm_cap I-Viii

11 [RVLCN]

[ El autor puede ser contactado ] eMail: [email protected] [email protected] 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