Curso de ingeniería inversa - Conocimientos básicos de ensamblador (Assembler)

4 - Conocimientos básicos de ensamblador (Assembler)


Curso gratis creado por Maniac Pc . Extraido de: http://www.publispain.com/supertutoriales
24 Agosto 2005
< anterior | 1 .. 2 3 4 5 6 .. 11 | siguiente >
Primero : ¿ Por que digo desensamblar o depurar? .. cuando un programa está hecho en otros lenguajes de programación (p.e. C - C++, Visual Basic, Delphi, Pascal) y lo 'compilas'.. o sea, lo dejas en ejecutable(.EXE, .COM) primero, ¿Qué es compilar?, hablemos superficialmente de aquello.. imaginemos que tenemos un código fuente de un programa (supongo que sabes que es eso), y el programa tiene la función de hacer lo siguiente ... Muestrame Un mensaje, el mensaje dice 'Hola a todos', y cuando lo muestres, que suene un pitído, al mismo tiempo, pinta las letras de color verde. Este es un pequeño programa que puede ser hecho en varios lenguajes, pero .. ¿El computador puede entender estas letras humanas y este lenguaje que nosotros entendemos? NO!, para eso necesitaremos un compilador, este transforma este código en un lenguaje llamado 'máquina', que  convierte nuestro programita en un .EXE que el procesador sabrá ejecutar, y entonces, tendremos un programa. Al mismo tiempo estamos protegiendo nuestro código, ¿Por que?, por que si le damos el código a cualquiera, pueden modificarlo ¿o no?.. por ejemplo si tengo el código de arriba puedo modificarlo para que sea así:

Muestrame Un mensaje, el mensaje dice 'MUERANSE TODOS!', y cuando lo muestres, que suenen dos pitídos, al mismo tiempo, pinta las letras de color azul.

Claro que ahora están saliendo descompiladores. que revierten el ejecutable a el código fuentee. Para variar me volví a desviar, quedamos en qué era un desensamblador, bueno, cuando creamos un programa en Delphi, Pascal, Etc. lo compilados, el desensablador puede 'desensamblar' el program para dejarlo en

Ensamblador para la ingeniería inversa.

Ensamblador es un lenguaje de programación de bajo nivel, ¿ Qué significa bajo nivel ?... pues al revés de un lenguaje avanzado como 'C', o uno medio como Pascal que son lenguajes para crear programas.. que son de alto nivel.. el lenguaje de bajo nivel es una manera de decir que mientras 'Mas programemos o más programa creemos menos control tendremos de este..'.

Este lenguaje les va ayudar mucho ... Si prestamos atención a este pequeño código fuente, no lo entenderán si no saben acerca de ensamblador.. si es que es así . Les ayudaré con los tipos ...

|| MOV AX,1111h || ||
|| MOV BX,1112h || ||
|| CMP AX,BX || ||
|| JB saltobueno || ||
|| HLT || ||
|| saltobueno: || ||
|| DEC BX || ||
|| CMP AX,BX || ||
|| JNE Acaba || ||
|| JE Continua || ||
|| Continua: || ||
|| DEC BX || ||
|| CMP AX,BX || ||
|| JE Acaba || ||
|| JB Acaba || ||
|| JG Acaba || ||
|| Acaba: || ||
|| XOR AX,AX || ||
|| XOR BX,BX || ||

¿Que rayos significa esto?

¿Estudiaremos todo lo que hace este pequeño texto, e iremos aprendiendo para seguir adelante en nuestro curso.. empezaremos por aprender que es ax y bx mostrados en la primera instrucción. Primero que nada, no son solo estás dos palabras, en total son las siguiente palabras : AX, BX, CX, DX ... pero .. ¿que son estás palabras? ... estas palabras son //registros de datos//, o sea, que contienen información en ellas para cálculos y otras cosas en general. Digamos que guardan datos temporales de la 'memoria'. tocaremos de manera superficial este tema ya que está curso de aesoft que les puede ayudar al respecto muy meticulosamente. Pensemos que estos registros son para acumular datos en memoria temporalmente .. ¿Ok?.. pensemos ahora que un equipo estándar con Win95 Usa 32 Bits, los registros para 16 bits (Windows 3.11, piénsenlo así) son Ax, Bx, Cx, Dx.Pero si queremos trabajar en 32 Bits, o sea Win95, tendremos que agregarles una E para depurarlos en Win95, (P.e. Eax, Ebx, Ecx, Edx)..

Me Explico nuevamente, en windows 95 se usan datos de 32 Bits(Para guardar datos)... si estamos trabajando en Windows 3.11 o dos(Versión anterior de Win95, y el añorado DOS) trabajaremos para guardar datos en 16 bits. Si trabajamos en DOS o en WIN 3.11, deberíamos ver los registros de datos como AX,BX,CX,DX, si trabajamos en Win95 serían así EAX,EBX,ECX,EDX. (Si ves en alguna parte registros de 16 bits. como AH no te sorprendas, es que se separan AX,BX,CX,DX .. ¿Cómo? .. AX se separa en AH y AL, BX se separa en BH y BL... y así sucesivamente.)

Ahora imaginemos que tenemos estos registros, ¿cada uno debe tener un valor o no?.. claro, y para este segmento de un código fuente tenemos el comando mov, el cuál en inglés significa move, el cuál significa mover, o sea que 'mueve' el valor 1111 a Ax, y mueve el valor 1112 A Bx, ¿Por qué la h? significa que está en hexadecimal, y tal como dijo Hot Byte en su curso, aprenderemos a transformar de decimal, hexadecimal, binario.

Decimal a binario (Todo esta siguiente explicación gracias a Hot Byte):

|| Decimal || Binario ||
|| || ||
|| 1 || 1 ||
|| 2 || 10 ||
|| 3 || 11 ||
|| 4 || 100 ||
|| 5 || 101 ||
|| 6 || 110 ||
|| 7 || 111 ||
|| 8 || 1000 ||
|| 9 || 1001 ||
|| 10 || 1010 ||

Aquí se presenta la conversión de binario decimal: 


|| Si tenemos el número : || 1 || 1 || || || 1 || ||
|| La conversión sería : || 1*2 || || 1*2 || 1 || 0*2 || 2 || 0*2 || 3 || 1*2 || 4 || ||
|| || || || || ||
|| y en decimal es : || 1 || +2 || +0 || +0 || +16 || =  19 ||

El * lo utilizo para multiplicar ... y el número pequeño, es elevar o potencionar (si no sabes, estas muerto).. ahora pongamos el primer número, 1*2, quedaría 2, si lo elevamos a 0 siempre y siempre quedará 1, cualquier número elevado a 0 siempre dará 1, además si te diste cuenta, dependiendo de los números que se van agregando en binario para que se vaya aumentando en 1 el exponente (0,1,2,3,4...). En este caso hemos logrado satisfactoriamente convertir el binario 11001 en del decimal 19. //Otra cosa! debes tener claro que en la computación se usa para potencionar el signo '^'//..// //Sigamos ... Pero primero les aconsejaría tener una calculadora científica a mano:

A continuación me apoyaré en el instituto de investigaciones de México para apoyar lo que voy a decir:

La división de un número entre dos es objetiva, cuando se divide y queda entre comas el resultado(p.e.:15,3), quedarán 'residuos',(15,3 <esto es residuo) si el residuo es mayor que 0, será 1, si igual a 0, será . si  esto se explica de la siguiente manera ...

TOMEMOS EL NUMERO 43 COMO EJEMPLO:

43/2 = El resultado es 21,5 .. 5 es mayor que 0, o sea que queda como 1 21/2 = El resultado es 10,5 .. 5 es mayor que 0, o sea que queda como 1 10/2 = El resultado es 5,0 ... 0 es igual a 0, o sea queda como 5/2 = El resultado es 2,5 ... 5 es mayor que 0, o sea queda como 1 2/2 = El resultado es 1,0 ... 0 es igual a 0, o sea queda como 1/2 = El resultado es 0,5 ... 5 es mayor a 0, o sea queda como 1 Vamos a tener que mirar este número de abajo hacia arriba, o sea 101011

Conversiones a Hexadecimal

 Miremos la siguiente tabla para empezar a guiarnos un poco: 



|| Decimal || Hexadecimal ||
|| || ||
|| 1 || 1 ||
|| 2 || 2 ||
|| 3 || 3 ||
|| 4 || 4 ||
|| 5 || 5 ||
|| 6 || 6 ||
|| 7 || 7 ||
|| 8 || 8 ||
|| 9 || 9 ||
|| 1 || A ||
|| 11 || B ||
|| 12 || C ||
|| 13 || D ||
|| 14 || E ||
|| 15 || F ||
|| 16 || 10 ||
|| 17 || 11 ||
|| 18 || 12 ||
|| 19 || 13 ||
|| 20 || 14 ||
|| 21 || 15 ||
|| 22 || 16 ||
|| 23 || 17 ||
|| 24 || 18 ||
|| 25 || 19 ||
|| 26 || 1A ||
|| 27 || 1B ||
||
-
|| siguiente con lo dicho convertiremos de binario a hexadecimal.   Un número binario (1-0) es un bit, ocho bits son un byte, 1.024 bytes es un kilobyte, 1.024 kilobytes es 1 Megabyte, 1.024 Megabytes es un gigabyte... || ||

Volvamos a lo nuestro ; veamos nuevamente el código fuente : 


|| MOV AX,1111h || ; Nuevamente sabemos que el registro AX vale 1111 en Hexadecimal, se pone una 'h' si es hexadecimal ||
|| MOV BX,1112h || ; Ahora sabemos que BX vale 1112 en Hexadecimal. ||
|| CMP AX,BX || ||
|| Ahora averiguaremos que es CMP, 'podríamos' decir que proviene de 'comprobar', primero comprueba el 2do valor con el primero, o sea, comprueba si es que BX es igual a AX. Y después de comprobar tenemos que saber qué queremos comprobar, si es menor, o mayor, o lo que sea, para esto utilizaremos el comando JB(abajo). ||
|| JB saltobueno || ||
|| El comando JB es uno de varios saltos disponibles para operaciones .. o sea, que si tenemos que comprueba el valor de AX con BX .. ¿luego qué? .. es como decir que : mira, te subo el sueldo y después hago algo .. ¿pero qué? .. --mira, te subo el sueldo pero luego te despido-- se entiende? después de hacer alguna operación debemos darle una instrucción .. en este caso JB significa : salta si es inferior... en este caso veremos que si dejamos a AX con el valor de 1111 y a BX con el valor de 1112, después los comprobamos y JB hará la comprobación de : Si AX es menor que BX, entonces salta a la instrucción SALTOBUENO que está abajo. Ojalá que hayas entendido esto .. mira la tabla que está mas abajo. ||
|| HLT || ; Esta orden bloquea el ordenador, halt > con esto decimos todo. ||
|| saltobueno:  || ; si te das cuenta, hemos puesto saltobueno: con ':' al final, para declarar que es una función. ||
|| DEC BX || ||
|| DEC, ¿Qué es esto? .. viene de la palabra inglesa 'decrease', que significa decrementar o disminuir, y entonces disminuirá el valor BX (1112) en 1 y quedará 1111. Dec sirve para quitar solamente 1. ||
|| CMP AX,BX || ; Después de programar comprobaººrá que Ax con BX ahora valen lo mismo ||
|| JNE Acaba  || ||
|| JE Continua  || ||
|| Trataré de explicar, JNE es un salto también, JNE significa = Salta si no es equivalente, y JE es el contrario de JNE, o sea  JE = Salta si es equivalente, dime.. ¿crees que la función JNE se va a ejecutar? .. piensa tu respuesta. ||
|| Continua:  || ||
|| DEC BX || ; Ahora BX vale 1110h ||
|| ¿ Ahora te diste cuenta que disminuimos nuevamente a BX ? ||
|| CMP AX,BX || ; comprueba nuevamente a AX con BX ||
|| JE Acaba  || ||
|| JB Acaba  || ||
|| JG Acaba  || ||
|| JE = Salta si es equivalente, (Saltará? .. no ..) JB = Salta si es inferior,(No es menor, no saltará) JG = Salta si es mayor, en este caso, saltará.. AX es mayor que BX. ||
|| Acaba:  || ||
|| XOR AX,AX || ||
|| XOR BX,BX  || ||
|| ; AX y BX valen ahora cero. XOR torna los registros en 0. ||

Si tomamos todo lo que decía toda la sentencia de este mini programa en ensamblador es como si se tomara esto :

Ax = Javier - Bx = Federico (Bueno para el pic..),

Javier tiene ahora (mov ax,1111h) 1111 Condones, y Federico tiene 1112(mov bx,1112h) Condones, para comprobarlo los cuentan(cmp ax,bx) y por que Javier tiene menos se van al prostíbulo(JB Saltobueno), y en el prostíbulo(saltobueno:), Federico se gasta uno (Dec bx), después nuevamente los cuentan (cmp ax,bx). Se dan cuenta que no están disparejos (JNE acaba) y que tienen los mismo, pero después se van al basurero municipal(JE continua), y Federico necesita solo 1110, así que bota uno (Dec bx). Los cuentan nuevamente (cmp ax,bx), después cuentan si tienen los mismos (JE acaba) y no tienen lo mismo. Después ven si Javier tiene menos(JB acaba), no, no tiene menos, después ven si Javier tiene más, si tiene más,(JG acaba), después se aburren, y los van a bota todos (acaba:) ... Javier los quema todos(XOR AX,AX), y Federico también (XOR BX,BX).

|| Hexadecimal || Assembler || Significa ||
|| 75 o 0F85 || jne || Salta si no es equivalente ||
|| 74 o 0F84 || je || Salta si es equivalente ||
|| EB || jmp || Salta directamente a . . . ||
|| 90 || nop || ( No OPeration ) Sin operación ||
|| 77 o 0F87 || ja || Salta si esta sobre ||
|| OF86 || jna || Salta si no esta sobre ||
|| 0F83 || jae || Salta si esta sobre o igual ||
|| 0F82 || jnae || Salta si no esta sobre o igual ||
|| 0F82 || jb || Salta si es inferior ||
|| 0F83 || jnb || Salta si no es inferior ||
|| 0F86 || jbe || Salta si esta debajo o igual ||
|| 0F87 || jnbe || Salta si no esta debajo o igual ||
|| 0F8F || jg || Salta si es mayor ||
|| 0F8E || jng || Salta si no es mayor ||
|| 0F8D || jge || Salta si es mayor o igual ||
|| 0F8C || jnge || Salta si no es mayor o igual ||
|| 0F8C || jl || Salta si es menor ||
|| 0F8D || jnl || Salta si no es menor ||
|| 0F8E || jle || Salta si es menor o igual ||
|| 0F8F || jnle || Salta si no es menor o igual ||

Según por lo que hemos visto hasta ahora los términos que nos podrían servir serían :

Cmp xx,xx = (X = Registro) Compara valores de un registro y a sea AX,BX,CX,DX (Recordad que pueden ser de 32 bits, o sea, (E)AX, (E)BX, (E)CX, (E)DX.) .. Que recomendación podría darte cuando en futuros casos te encuentres con estas comparaciones ? :-Intercéptalas cuando están en plena comprobación-:]

Jne xxxxx = Cuando saltes a una dirección por ejemplo; cuando saltes a una ventana de error diciendo que te registraste mal, y estés después de una comprobación ... :-Revierte los saltos! así pensará que no es equivalente-:, me explico, si nos encontramos con una operación de registro que dice así: 


|| 014F:00401DD 3BC7 || Cmp eax, edi || ||
|| 014F:00401DE  0F85061DC1FF  || Jne 00401DF  || ; 000401DF es una dirección de ejemplo, cuando tengamos que desensamblar un programa será así. ||
|| 014F:00401DF  || "Registro Falló" || El texto solo por ejemplo de lo que sería un registro fallido. ||
|| Lo que podemos hacer aquí es "invertir" el salto tal como lo mencionamos anteriormente... lo que está en COLOR lo puse así para que reconocieran que esta es la instrucción en hexadecimal, para invertir miremos la tabla que tenemos arriba, tendríamos que cambiar la instrucción 0F85061DC1FF por 0F84061DC1FF ... en muchos otros casos más se puede usar este método... no solo en la instrucción JNE, también se puede usar en otras instrucciones, así, estaremos revirtiendo la comprobación, y pensará ... : La comprobación original tiene esta apariencia : 'Si no es el número correcto, entonces, saltará al error' ... pero la cambiaremos para que diga .. 'Si el número no es correcto... entonces... registro Exitoso!'... así estaremos burlando la protección del programa; pero nos podremos encontrar algún día con alguna protección así: ||
|| :004049CD 755A  || jne 00404A29 || ||
|| Lo que podemos hacer es hacer que sea un salto directo, o sea reemplazando 755A con EB5A .así quedaría en un JMP 00404A29... ||
|| Todavía los tengo enredados con la parte teórica, pero con los ejemplos nos acostumbraremos con los ejemplos que tendremos .. ||

Test xx,xx = Estas instrucciones no se las he mostrado, pero también son rutinas de verificación, también podemos poner una interrupción aquí.
< anterior | 1 .. 2 3 4 5 6 .. 11 | siguiente >

Autor y licencia de 'Curso de ingeniería inversa'


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