SlideShare una empresa de Scribd logo
1 de 163
Descargar para leer sin conexión
INTRODUCCION AL CRACKING CON OLLYDBG DESDE
CERO
La idea de esta INTRODUCCION AL CRACKING CON OLLYDBG DESDE CERO es la de dar una
base para todos los que recién se inician en el arte del cracking con OLLYDBG, tratando de ser
una introducción pero a su vez que proporcione una base fuerte para poder ingresar a la lectura y
comprensión de tutoriales mas avanzados como los que se encuentran en el actual NUEVO
CURSO de CRACKSLATINOS, el cual por supuesto sigue abierto para seguir agregando
novedades, concursos y teorías como hasta ahora.
La idea se genero a partir de que los newbies actuales que leen el llamado NUEVO CURSO de
CRACKSLATINOS, se encuentran con que este se inicia en un nivel muy alto, y no pueden
insertarse gradualmente en el mismo, por lo cual se sienten frustrados y muchas veces abandonan
antes de empezar, la idea de esta INTRODUCCION es no repetir los grandes tutes que existen en
ese curso que son ya mas de 500 y de un nivel espectacular, si no mas bien sentar la base para
que el que termine esta introducción, le sea mas fácil leer cualquier tutorial, obviamente requerirá
esfuerzo como todo en el cracking, pero la tarea nuestra es tratar de alivianar ese esfuerzo,
sentando aquí las bases del cracking en OLLYDBG para que sea compresible y se pueda entender
fácilmente.

PORQUE OLLYDBG?
Aquí no entraremos a hacer grandes elucubraciones o reeditar viejas polémicas de SOFTICE vs
OLLYDBG de cual es mejor ni nada de eso, creo que hasta los fanáticos de SOFTICE reconocen
que es mas sencillo empezar con OLLYDBG, ya que muestra mayor información y es mas cómodo
para aprender, la idea es ingresar al mundo del cracking, por la puerta del OLLYDBG, mas
adelante cuando uno ya conoce, puede trasladar fácilmente a cualquier debugger lo aprendido
pues cambian las formas de usar de los programas, pero no la esencia.

LO PRIMERO ES LO PRIMERO
Exactamente lo primero es munirse de la herramienta que vamos a utilizar mayormente, para ello
pueden hacer clic AQUI para bajarlo.

Como aquí estamos empezando desde cero pues, recién nos estamos haciendo del archivo, y
ahora ya que es un archivo zipeado, lo unzipearemos con WINZIP preferentemente a una carpeta
en nuestro disco rígido que podamos localizar fácilmente, una buena idea seria poner dicha
carpeta en C:/ aunque funciona en cualquier lugar, yo la pondré en C:/.
Una vez descomprimido podemos entrar a la carpeta y ver

Allí esta el archivo ejecutable OLLYDBG.exe el cual ejecutaremos para arrancar el OLLYDBG y al
cual para comodidad le haré un acceso directo en mi escritorio.

Bueno ya tenemos bajado y preparado para arrancar a nuestro OLLYDBG.exe, lo ejecutamos.
Nos aparece este cartel avisándonos que la DLL que esta en la carpeta de OLLYDBG es mas
antigua que la de sistema, si apretamos SI, borrara la antigua de la carpeta del OLLY y usara la de
sistema, yo a pesar de no ver grandes diferencias siempre prefiero elegir que use la propia antes
que la de sistema, ya que fue concebido con esa dll, por lo tanto elijo NO.

Allí esta el OLLYDBG vacío, y como siempre el primer programa que abriremos mas que nada para
mirar las diferentes partes del OLLYDBG y a vuelo de pájaro poder ubicarnos en sus diferente
partes, es el famoso CRACKME DE CRUEHEAD que vendrá adjunto en este tutorial.
Para abrir el archivo a debuggear en el OLLYDBG, vamos a FILE OPEN o hacemos clic en el icono

Se abrirá la ventana para que busquemos el archivo a debuggear en este caso es el crackme de
CRUEHEAD.
Allí se abre el susodicho crackme y por ahora no importa que no entendamos lo que nos muestra
ya mas adelante aprenderemos eso, la idea es ir mostrando las partes del OLLYDBG y ciertas
configuraciones del mismo para que cuando en sucesivos tutes, diga, por ejemplo vayan al DUMP,
sepan al menos donde esta, así que esto es mas que nada para ubicación, no es un tute profundo
sobre OLLY.

Allí vemos la cuatro partes de la ventana principal del OLLYDBG
1)DESENSAMBLADO :
También llamado listado, aquí el OLLY nos muestra el listado desensamblado del programa que
vamos a debuggear, por DEFAULT el OLLY viene configurado para analizar el programa que
vamos a debuggear al iniciar, esto se configura en OPTIONS-DEBUGGING OPTIONS.

O sea al estar marcada esa tilde en AUTO START ANALISIS OF MAIN MODULE el OLLYDBG
analizara el programa y mostrara información adicional sobre el mismo.

Allí esta el listado inicial del crackme de CRUEHEAD analizado, y si arranca sin analizar debajo
podemos ver la diferencia.
La ventana analizada muestra mas información, que aunque aun no sepamos bien que es, se ve
mas completa, igual es bueno saber que de la ventana analizada se puede quitar el análisis, si uno
no esta de acuerdo con el mismo o uno se da cuenta que el mismo esta equivocado lo cual puede
ocurrir.
Muchas veces el OLLYDBG muestra partes que no son listado correcto porque interpreto mal el
código ejecutable como datos, en ese caso se ven unos DB como estos

En ese caso puedo quitar manualmente el análisis que el OLLYDBG ha realizado haciendo CLICK
DERECHO en el listado y eligiendo ANALISIS-REMOVE ANALYSIS FROM MODULE

y en ese caso el listado se vera sin análisis pero correcto
Otra cosita que hace a la claridad para trabajar y que por lo menos a mi me gusta, aunque cada
uno puede variar en estos temas es colorizar los JUMPS Y CALLS eso se hace haciendo clic
derecho APPEARENCE – HIGHLIGHTING – JUMPS AND CALLS

El resultado es el siguiente

Allí vemos que en celeste quedan resaltados los CALLS y en amarillo los JUMPS, lo cual es mas
claro para la vista.
Bueno con eso nuestro listado queda mas fácil de interpretar, aunque aun no tengamos la mas
remota idea de que significa, pero bueno hay que preparar antes las herramientas para poder ir de
a poco aprendiendo
2)REGISTROS
La segunda ventana importante del OLLYDBG es la de los REGISTROS

Recordamos que la ventana de registros se encuentra en la parte superior derecha del OLLYDBG,
allí muestra bastante mas información que los registros en si.

Tiene muchísima más información que aun no veremos, pero se puede cambiar el modo de
visualización en tres formas. (VIEW FPU REGISTERS, VIEW 3D NOW REGISTERS y VIEW
DEBUG REGISTERS) por default viene elegida la primera.

Por ahora no ahondaremos mucho en eso ya que nos preocuparemos más que nada en el tema
REGISTROS y FLAGS, lo menciono para que sepan que hay varias vistas en el registro.
3)STACK O PILA:
Bueno allí vemos el llamado STACK O PILA aquí no hay mucha configuración posible solo la
opción de mostrar la información relativa al registro ESP o al registro EBP.

Por default y lo que mas se utiliza es la vista relativa a ESP, pero para cambiar a la vista según EBP, haciendo
clic derecho en el stack eligiendo GO TO EBP cambiamos y para volver GO TO ESP volvemos a la opción
por default.

En sucesivas entregas explicaremos bien el funcionamiento del stack por ahora miramos como se puede variar
su configuración solamente.

4) DUMP:
La ventana del DUMP tiene muchas opciones de visualización, por DEFAULT nos muestra la visualización
HEXADECIMAL de 8 columnas o bytes, la cual puede ser modificada haciendo CLICK DERECHO en el
DUMP y eligiendo la opción deseada.

La opción por DEFAULT es la que generalmente mas se usa, aunque tenemos opciones para cambiar para
mostrar desensamblado (DISASSEMBLE), Texto (TEXT) y diversos formatos (SHORT, LONG, FLOAT)
Y además la opción SPECIAL – PE HEADER que mas adelante en próximos capítulos veremos para que
sirve esto que es muy útil.

Ya conocemos las partes que se ven en la ventana principal del OLLYDBG, aunque también hay más
ventanas que no se ven directamente, se puede acceder a ellas, tanto por el menú, como por los botones de las
vistas.

Veremos que es cada uno
El botón L o VIEW-LOG nos muestra lo que el OLLYDBG escribe en la ventana del LOG lo cual puede ser
configurado para mostrar diferentes tipos de información, por default en la ventana del LOG va guardando allí
información sobre el arranque, y de la información escrita en el mismo por los diferentes BREAKPOINTS
CONDICIONAL LOGS, lo cual se vera mas adelante, por ahora vemos allí ,la información del proceso que
arranco, en este caso el crackme de cruehead, las dll que cargo, y ciertos tips sobre el análisis.

Una de las opciones mas importantes de esta ventana es la de loguear a una fila, para ciertos casos que
deseemos guardar la información en una fila de texto, en ese caso CLICK DERECHO-LOG TO FILE.
El botón E o VIEW-EXECUTABLES nos muestra la listado de los ejecutables que utiliza el programa, exe,
dlls, ocxs, etc

Aquí también el botón derecho tiene muchas opciones que por ahora no veremos ya que estamos mirando en
forma general al OLLYDBG.
El botón M o VIEW – MEMORY, nos muestra la memoria ocupada por nuestro programa, allí se ven las
secciones del ejecutable, dlls que utiliza el proceso, así como el stack y diversas secciones allocadas por el
sistema, y muchas veces al correr los programas, los mismos realizan nuevas allocaciones de memoria. En
tiempo de ejecución.

Haciendo clic derecho podemos hacer SEARCH en la memoria para buscar en ella, strings, cadenas hexa,
unicode etc, además nos da la posibilidad de colocar diferentes tipos de breakpoints en la secciones, como asi
también la posibilidad de cambiar el acceso a las mismas con SET ACCESS ya profundizaremos en esto.
El botón T o VIEW-THREADS nos da el listado de los THREADS del programa

Aunque no sabemos aun que es esto y la explicación llegara en los próximos capítulos es bueno ir
familiarizándose en donde esta cada cosa, luego aprenderemos que es y como se usan mas adelante.
El botón W o VIEW-WINDOWS nos muestra las ventanas del programa, como aun no corrió, no hay
ventanas así que esta vacía.
El botón H o VIEW-HANDLES, nos muestra los handles por ahora localícenlo, ya explicaremos que es y
para que sirve

El botón C o VIEW-CPU nos retorna a la ventana principal del programa.
El botón / o VIEW-PATCHES nos muestra los parches si el programa ha sido modificado, por ahora esta
vacío al estar sin cambios

El botón K o VIEW-CALL STACK nos muestra el call stack, que es el listado de los calls que entramos,
hasta el punto donde el programa esta detenido.

El botón B o VIEW-BREAKPOINTS es el listado de los breakpoints comunes colocados en el programa, no
muestra los hardware breakpoint ni los memory breakpoints aquí, solo los BP comunes.
El botón R o VIEW- REFERENCES nos muestra la ventana de referencias la cual nos da los resultados de
cuando hacemos una búsqueda de referencias en el OLLY

El botón … o VIEW-RUN TRACE, nos muestra el listado si hemos hecho algún RUN TRACE en nuestra
maquina, y tiene también la posibilidad de elegir LOG TO FILE, para guardar el resultado del traceo en un
archivo txt

Bueno hasta aquí un paneo a vuelo de pájaro por los botones mas importantes, no detallamos explicación
porque aun hay que aprender antes algo de ASM, y practicando el uso del OLLYDBG podremos ir aclarando
mas profundamente para que sirve cada botón y cada OPCION, la idea es irse familiarizándose con donde
están las cosas que veremos en las próximas entregas.

COMO CONFIGURAR EL OLLYDBG COMO JIT ( JUST IN TIME DEBUGGER)
Aclaro que no conviene tener configurado el OLLYDBG constantemente COMO JIT, solo conviene hacerlo
en ocasiones especiales, ya que al estar como JIT capturara el error de cualquier programa de nuestra maquina
y arrancara solo, lo cual puede resultar molesto si no estamos debuggeando o crackeando, por lo tanto les
enseño como se configura para casos especiales, pero conviene dejarlo con la opción que trae por default que
no esta como JIT.
Para colocar el OLLYDBG como JIT vamos a OPTIONS-JUST IN TIME DEBUGGING
Y aprieto el botón MAKE OLLYDBG JUST IN TIME DEBUGGER y DONE

Para quitarlo, en el mismo lugar aprieto RESTORE JUST IN TIME DEBUGGER y DONE

Agregando PLUGINS al OLLYDBG
El OLLYDBG trae la opción para agregar plugins que nos son necesarios para realizar cierta tarea, por ahora
solo agregaremos el plugin COMMAND BAR para aprender como se agregan los mismos.
Bajamos el plugin COMMAND BAR el cual puede ser bajado de AQUÍ y la mayoría de los plugins se hallan
AQUI

Allí esta bajado en mi escritorio el plugin lo descomprimo con WINZIP entro a la carpeta que descomprimí a
ver el contenido
Ahora antes que nada crearemos una carpeta para los PLUGINS en nuestra maquina, yo la creare en C:/ y la
llamare PLUGINS nada mas.
Voy a C y creo una NUEVA CARPETA

Allí esta, puede estar ubicada en cualquier lugar, pero a mi me gusta tener todo en C por eso la coloque allí,
de cualquier forma debemos configurar el OLLYDBG para que reconozca esta carpeta como la que tendrá los
plugins.
Para ello en el OLLYDBG vamos a OPTIONS-APPEARANCE

Y en la ventana que se abre vamos a la pestaña DIRECTORIES
Vemos que en donde apunta al path de los plugins (PLUGIN PATH), en realidad nos esta apuntando a la
carpeta donde esta el OLLYDBG.exe y podría dejarlo allí, pero a mi me gusta tener los plugins separados por
lo tanto en donde dice PLUGIN PATH- BROWSE busco la carpeta que cree para mis plugins.

Allí elegí la carpeta PLUGINS que cree y sale este aviso

O sea que debo reiniciar el OLLY para que me reconozca la nueva carpeta de plugins, pero antes copio el
contenido que baje del comand bar a mi carpeta de plugins.
Allí copie todo el contenido y lo pego en mi carpeta PLUGINS

Allí esta el contenido del plugin Command Bar en la carpeta PLUGINS, cada plugin que baje y agregue solo
deberé copiar su contenido allí, muchas veces con copiar solo la dll es suficiente.
Ahorra cierro el OLLYDBG si lo tenia aun abierto y lo reinicio.
Vemos que en el menú PLUGINS me apareció el COMMAND BAR y las opciones del mismo.

A su vez en la parte inferior del OLLYDBG vemos la COMMAND BAR instalada
Es una barra para tipear comandos que nos facilitara mucho las cosas, mas adelante veremos su uso, por ahora
lo importante es saber agregar plugins.
Para quitar cualquier PLUGIN con solo quitar la dll correspondiente de nuestra carpeta PLUGINS y reiniciar
el OLLYDBG, desaparecerá, les aconsejo que dejen siempre activa la COMMAND BAR.
Arranco nuevamente el crackme de CRUEHEAD EN OLLYDBG
Las teclas mas usadas en el OLLYDBG son:
F7: Ejecuta una sola línea de código (si estas en un CALL entra al mismo a ejecutarlo por dentro)
F8: Ejecuta una sola línea de código (si estas en un CALL no entra al mismo lo ejecuta completo sin entrar y
sigue en la siguiente línea luego del CALL)
Esos dos formas de tracear manualmente son verdaderamente diferentes y según cada caso usaremos F7 o F8
lo cual veremos más adelante.
F2: Coloca un Breakpoint COMUN en la línea que marcas con el Mouse o esta grisada en el listado, para
quitar el BP apretas nuevamente F2.
Por ejemplo:

Quiero poner un BP en 40101A pues marco con el Mouse esa linea

Al hacer clic una sola vez se marca y queda grisada como vemos en la imagen, luego apreto F2.
Vemos que se pinta de rojo la zona de la dirección, eso significa que hay activo un BP o Breakpoint allí, si
apreto F2 nuevamente se quita.
F9: Para Correr el programa es similar a RUN, con esto el programa correrá, hasta que encuentre algún
BREAKPOINT, o alguna EXCEPCION que lo detenga o FINALICE por algún motivo, al apretar RUN
veremos en la esquina inferior del OLLYDBG la palabra RUNNING o sea que esta CORRIENDO.

Allí arranco el CRACKME DE CRUEHEAD, lo podemos ver correr

Si PAUSO la ejecución en OLLYDBG apretando F12 o DEBUG –PAUSE

Vemos que el OLLYDBG cambia a mostrar PAUSED o sea que esta PAUSADO, podemos volver a hacerlo
correr con F9 o DEBUG-RUN.
Para cerrar el programa que esta siendo DEBUGGEADO apreto DEBUG-CLOSE

Bueno esto a sido una mirada a vuelo de pájaro del OLLYDBG la cual profundizaremos mas adelante pues
tiene muchísimas opciones y configuraciones las cuales seguiremos estudiando en las próximas entregas, es
muy útil que bajen el programa lo configuren y miren donde están las cosas que muestra este tute, así como le
agreguen el plugin para practicar, y hagan correr y pausar el CRACKME DE CRUEHEAD, prueben ponerle
un Breakpoint y practiquen esas cosas para que en la segunda entrega estén mas familiarizados con el mismo
y podamos avanzar lento pero seguro, y sin dudas.
Un abrazo a todos los CRACKSLATINOS
Hasta la parte 2
Ricardo Narvaja
07 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 2
Luego de haber visto a grandes trazos, la ubicación y las principales partes del OLLYDBG, debemos
aprender el sistema de numeración utilizado y cual es el concepto de stack aunque sea para tener una idea,
luego profundizaremos.
SISTEMAS NUMERICOS
Los tres sistemas numéricos que más se utilizan son el binario el decimal y el hexadecimal.
El concepto básico que deben tener de ellos es el siguiente:
BINARIO: Se representa los números con dos caracteres el 0 y 1 por eso se llama BINARIO.
DECIMAL: Se representa todos los números con 10 caracteres (del 0 al 9) por eso se llama decimal.
HEXADECIMAL: Se representa todos los números con caracteres del 0 al F ( del 0 al 9, mas A, B, C, D,
E y F, o sea serian 16 caracteres en total).
Normalmente a partir de aquí cuando diga un número y no diga a que sistema de numeración pertenece es
porque es HEXADECIMAL que es el que utiliza OLLYDBG, si son decimales o binarios aclarare
expresamente.
Existen formulas matemáticas que no utilizaremos aquí, para convertir números de un sistema al otro, que
no son muy simpáticas, pero llegado el momento, un cracker realmente usa la CALCULADORA DE
WINDOWS, que es lo mas rápido y directo y no va a ponerse a hacer cuentas de potencias, sumas etc
para convertir un numero de un sistema a otro.
Abramos la CALCULADORA DE WINDOWS y preparémosla

Allí vemos en el menú VER como se puede cambiar a CIENTIFICA.
Allí vemos que por DEFAULT arranca en DECIMAL, y al lado tiene la opción de cambiar a
HEXADECIMAL (HEX), OCTAL (OCT) y BINARIO (BIN).
El Octal que representa la numeración con 8 caracteres no es muy usado en cracking pero la calculadora
trae dicha opción incluida, si se llegara a necesitar.
Pues para pasar un número de un sistema a otro es muy sencillo, pongo la calculadora en el sistema del
número que quiero cambiar, por ejemplo si quiero cambiar 55 de DECIMAL a HEXA, pongo la
calculadora en DECIMAL y tipeo 55.

Ahora cambio la calculadora a HEXA y automáticamente me lo convierte a ese sistema de numeración

Ahí esta 55 decimal equivale a 37.
Resalte las letras A,B,C,D,E,F para ver que al pasar la calculadora a HEXA se nos habilita la posibilidad
de teclear las mismas, que estaban deshabilitadas en modo DECIMAL.
Creo que esta es la forma mas practica de manejarse con los sistemas de numeración, y poder pasar
valores de uno a otro sin grandes complicaciones.
NUMEROS NEGATIVOS en HEXADECIMAL
Esto es lo mas duro de entender por lejos tratemos de ir despacio.
En el sistema de numeración hexadecimal, como podemos representar los números negativos, ya que no
se puede poner el signo menos delante como hacemos en la tradicional numeración decimal ?
Como hago para representar en formato hexadecimal -1 por ejemplo ?
Pues aquí viene el problema y espero que se entienda.
Solo tenemos la posibilidad de escribir en hexadecimal desde 00000000 hasta FFFFFFFF, como
representaríamos los números negativos?
Pues bien a un genio se le ocurrió que en vez de representar desde 00000000 hasta FFFFFFFF todos
números positivos, usaríamos la mitad para los positivos y la otra mitad para los negativos.
Los números positivos van entonces desde 00000000 hasta 7FFFFFFF y los negativos desde 80000000
hasta FFFFFFFF.

POSITIVOS
000000000 es igual a 0 decimal
000000001 es igual a 1 decimal
………………………………..
………………………………..
7FFFFFFF es igual a 2147483647 decimal (que seria el máximo positivo)

NEGATIVOS
FFFFFFFF seria el -1 decimal
FFFFFFFE seria el -2 decimal
………………………………
………………………………
80000000 seria -2147483648 decimal (que sería el máximo negativo)

Podemos probar averiguar en la Command Bar el valor de 7FFFFFFF para ello usamos el signo de
interrogación y a continuación el valor que deseamos pasar a decimal,

Vemos a la derecha que nos da el valor DECIMAL correspondiente, que es 2147483647 sin problemas.
Ahora cuando deseamos averiguar el valor de 80000000 que es negativo, vemos que no nos lo muestra
sigue dando el resultado para 7FFFFFFF (esto es un bug de la Command Bar), así que como podemos
hallar su valor en OLLYDBG ?

Con este pequeño truquito.
Vamos a los registros y marcamos EAX
Luego hacemos CLICK DERECHO-MODIFY

Nos aparece una ventana en la que podemos colocarle a EAX el valor que queremos, así que
aprovechamos y usamos dicha ventana para hacer las conversiones, en el primer renglón tipeamos el
valor HEXADECIMAL que queremos convertir y en el segundo renglón nos aparcera el resultado en
DECIMAL.
En este caso vemos que 80000000 corresponde al valor -214783648 decimal.

Si averiguo el valor de FFFFFFFF allí vale -1 decimal.
Por lo tanto en la ventana de modificar un registro podemos averiguar el valor de números negativos
perfectamente, luego para salir podemos CANCELAR así no realizamos ningún cambio.
CARACTERES ASCII
Uno de los temas que debemos conocer también es la forma en que nuestro sistema escribe datos en la
pantalla, para eso asigna a cada carácter un valor hexadecimal, de forma que puede interpretar los mismos
como si fueran letras, números símbolos etc.
De la teoría de ASM de Caos Reptante le copiamos la tablita jeje allí vemos a continuación el valor
decimal, en la segunda columna el valor hexadecimal y en la tercera el carácter o sea por ejemplo si
quiero escribir un espacio en OLLY, tengo que usar el 20 o 32 decimal, cualquier carácter que
necesitemos, sea letra o numero podemos verlo en esta tablita.

Dec. Hex. Carac
t
32
20
esp
33
21
!
34
22
"
35
23
#
36
24
$
37
25
%
38
26
&
39
27
'
40
28
(
41
29
)
42
2A
*
43
2B
+
44
2C
,
45
2D
46
2E
.
47
2F
/
48
30
0
49
31
1
50
32
2
51
33
3
52
34
4
53
35
5
54
36
6
55
37
7
56
38
8
57
39
9
58
3A
:
59
3B
;
60
3C
<
61
3D
=
62
3E
>
63
3F
?

Dec.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

Hex. Carac
t
40
@
41
A
42
B
43
C
44
D
45
E
46
F
47
G
48
H
49
I
4A
J
4B
K
4C
L
4D
M
4E
N
4F
O
50
P
51
Q
52
R
53
S
54
T
55
U
56
V
57
W
58
X
59
Y
5A
Z
5B
[
5C

5D
]
5E
^
5F

Dec.
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

Hex. Caract
60
61
62
63
64
65
66
67
68
69
6A
6B
6C
6D
6E
6F
70
71
72
73
74
75
76
77
78
79
7A
7B
7C
7D
7E
7F

`
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
{
|
}
~

Por lo demás la command bar cuando averiguamos el valor de un numero hexadecimal, nos proporciona
también el carácter ASCII correspondiente si tuviera, veamos un ejemplo tipeemos en la command bar.
? 45
Vemos que 45 corresponde a la letra E mayúscula, si en la tabla anterior buscamos 45 en la columna del
medio que corresponde a hexa vemos que es la letra E

69

45

E

Por lo demas en la ventana del DUMP del OLLYDBG, tenemos una columna que muestra los caracteres
ASCII, si miramos allí mismo en el crackme de CRUEHEAD la ventana del DUMP.

Vemos que al lado de la columna que representa los valores hexadecimales, esta la columna ASCII,
donde podemos ver resaltadas algunas cadenas de texto compuestas por combinaciones apropiadas de
caracteres ASCII.
QUE ES EL STACK O PILA
El stack o pila es una zona de la memoria, en la cual se van guardando datos que mas adelante deben ser
recuperados.
El nombre PILA es porque asemeja un mazo o pila de cartas o barajas que se encuentran en una mesa.
En dicho mazo, si agregas una nueva carta solo podes hacerlo arriba de la pila y si quiero sacar una será la
de más arriba de la pila de cartas.
Esa es la característica principal del stack es como un mazo de cartas, la carta que agregas a la pila ira
arriba, y será la primera que salga, cuando quites una.
Ya veremos mas adelante en la explicación de las instrucciones la forma de modificar o agregar y quitar
cartas en nuestro mazo, o sea nuestro querido STACK que como recordamos del tute anterior esta
representado en la parte inferior derecha del OLLYDBG.
Bueno creo que ya tienen bastante para quemarse un rato mas la cabeza nos vemos en la parte 3 donde
explicaremos que son los registros y los flags y para que sirven.
Hasta la parte 3
Ricardo Narvaja
08 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 3
QUE SON LOS REGISTROS Y PARA QUE SIRVEN
Ahora para que sirven y que son exactamente los registros?
Bueno el procesador necesita asistentes en su tarea de ejecutar los programas.
Los registros lo ayudan en ello, cuando veamos las instrucciones ASM veremos por ejemplo que no se
pueden sumar el contenido de dos posiciones de memoria directamente, el procesador tiene que pasar una
de ellas a un registro y luego sumarla con la otra posición de memoria, este es un ejemplo pero por
supuesto ciertos registros tienen usos mas específicos veamos.
ESP apunta al valor superior del stack, vemos en nuestro Crackme de Cruehead como ejemplo.

ESP vale 12FFc4 y si miramos el stack en OLLY en el mismo momento

Vemos que apunta al valor superior de nuestro stack o dicho en forma simpática, a la carta superior de
nuestro mazo de cartas o barajas.
EIP es otro registro muy importante apunta a la instrucción que esta siendo ejecutada en este momento
veamos

Veamos en el listado del OLLYDBG, que al arrancar el crackme de Cruehead, este paro allí en 401000,
que es la primera instrucción a ejecutar y por supuesto el valor de EIP cuando esta detenido allí será
401000.
Si apreto F7 ejecuta la primera instrucción y pasa a la siguiente.

EIP ahora vale 401002 y en al listado vemos que se ejecuto la primera instrucción y ahora estamos en
401002.

Los otros registros pueden tomar valores variables y sirven para asistir al procesador en las ejecuciones de
las instrucciones, ECX es usado casi siempre como contador los demás son fluctuantes y asisten en la
ejecución de programas como veremos en la explicación de cada instrucción.

Recordamos donde el OLLYDBG nos mostraba el valor de los REGISTROS

Vemos a simple vista que son EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI y EIP
Esos son los llamados REGISTROS de 32 bits
OLLYDBG expresa el contenido en hexadecimal, vemos por ejemplo que EAX vale 00000000, y el
máximo valor que podría tener es FFFFFFFF, si lo pasamos a BINARIO seria
11111111111111111111111111111111.

Vemos que son 32 bits cada uno con la posibilidad de ser 0 o 1 en numero binario, por eso se llama a
estos, registros de 32 bits.
En el lenguaje ASM se pueden operar con partes de los registros de 32 bits, en este caso EAX, puede ser
subdividido.
Veamos en el OLLY para más practicidad con un ejemplo:
Cambiare el valor de EAX a uno que yo quiera en este caso 12345678.
Abro el OLLYDBG y allí mi programa será el CRACKME DE CRUEHEAD, aunque podría ser
cualquiera.
Una vez que arranca y para en el inicio hago clic derecho en EAX y elijo MODIFY

En la ventana que se abre escribo en la línea hexadecimal el valor 12345678

Queda así

Luego acepto con OK

Allí vemos como quedo cambiado al valor que yo deseaba, OLLYDBG tiene la particularidad de poner en
ROJO los valores que se modifican.
Como decíamos se pueden usar solo partes de EAX, en este caso AX seria el registro de 16 bits o sea las
cuatro ultimas cifras de EAX, por lo tanto AX valdría en este caso 5678, corroborémoslo en OLLY en el
commandbar tipeemos
? AX (ya que el signo de interrogación sirve también para hallar el valor de una expresión o de un
registro)

Cuando apreto ENTER
Vemos que dice 5678 que es lo que suponíamos, AX son las ultimas cuatro cifras de EAX.
También existen AL y AH, cuales son estos miremos en OLLYDBG
? AL

? AH

O sea si
EAX=12345678
AX son las ultimas cuatro cifras

AH la 5 y 6 cifra y a su vez AL las ultimas dos cifras

También en la misma forma EBX se puede subdividir en BX, BH y BL y así sucesivamente existen
subdivisiones para casi todos los otros registros.
COMO CAMBIAR LOS VALORES DE LOS REGISTROS
Ya vimos como se pueden cambiar valores de los registros en OLLYDBG, lo que hicimos en EAX se
puede hacer en los otros registros de la misma forma, marcando el registro que deseamos cambiar de
valor, luego haciendo CLICK DERECHO-MODIFY, salvo en el caso de EIP, dado que el mismo apunta
a la instrucción que se esta ejecutando.
Para cambiar EIP operamos de la siguiente forma:
Ya que EIP siempre apunta a la instrucción que se va a ejecutar, elegimos una nueva instrucción en el
listado.
Luego que esta marcada como en este ejemplo 40101A, hago en ella CLICK DERECHO-NEW ORIGIN
HERE y cambiara EIP a 40101A, continuando el programa ejecutándose desde allí.

Como vemos queda EIP valiendo 40101A

QUE SON LOS FLAGS?
Como vimos en el primer tutorial en OLLYDBG debajo de los registros se encuentran los flags o
banderas.

Vemos que los flags son C P A Z S T D y O
Vemos que solo pueden tener valores de cero o uno, que nos advierten que al ejecutar determinada
instrucción, ha ocurrido algo, según el flag que sea.
Vayamos mirando que indica cada uno:
EL FLAG O O FLAG OVERFLOW (DESBORDAMIENTO)
Se activa cuando al hacer una operación, el resultado cambia de signo dando un valor incorrecto.
Miremos en OLLYDBG este ejemplo, como siempre en el CRACKME DE CRUEHEAD de paso vamos
practicando usar el OLLYDBG.
Modifico como hicimos antes el valor de EAX a 7FFFFFFF que es el máximo positivo posible.

Ahora le sumare 1, lo cual excederá la posibilidad de EAX de mostrar un resultado positivo ya que
80000000 ya corresponde a un número negativo
Para eso apreto la barra espaciadora que me permite escribir instrucciones.

Me sale esa ventana donde escribo ADD EAX,1.

Al apretar el botón ASSEMBLE vemos que cambia la instrucción que había antes en 401000 por la que
yo escribí.

ADD EAX, 1 (ya lo veremos cuando enumeremos y expliquemos las instrucciones) seria sumarle a EAX
el valor 1, y guardando el resultado en el mismo EAX.
Veo que antes de ejecutar la línea con F7 el flag O esta en cero
Si ejecuto la instrucción con F7 para ver que es lo que ocurre, al realizar dicha operación veo que EAX al
sumarle 1 se desborda y me muestra 80000000 lo cual traspasa la línea del cambio de signo.
El FLAG O se activa poniéndose a 1 indicándome que la operación excedió el máximo resultado posible
y esa es su función indicar cuando ocurra desborde al ejecutar una instrucción.

El FLAG A o AUXILIAR
Tiene una función similar pero para cuando se realizan operaciones con otros formatos que por ahora no
nos interesan.
El FLAG P o PARIDAD
Dicho flag se activa cuando ejecutamos una instrucción y su resultado es un valor, que pasado a numero
binario tiene una cantidad par de unos, como por ejemplo 1010, o 1100 o 1111000 que tienen resultados
cuya cantidad de unos total es par.
Para probar esto ya que tenemos en el OLLYDBG escrito ADD EAX,1 y como ya ejecutamos esa línea
para probar el flag anterior, pues la marcamos de nuevo y hacemos CLICK DERECHO-NEW ORIGIN
HERE lo cual llevara EIP de nuevo a 401000 (volvemos atrás) y a que si apreto F7 se ejecute de nuevo la
instrucción que escribimos ADD EAX,1.

Allí tenemos pues de nuevo justo antes de ejecutar la suma, con EAX valiendo 00000000 y el flag P
valiendo 1, porque quedo así de la operación anterior, veamos que ocurre cuando le sumamos 1 a EAX
nuevamente.
Apretamos F7
Vemos que P nos marca 0 porque el resultado que muestra EAX=00000001 que en binario es 1 y tiene un
solo 1 o sea un numero impar de unos por eso no se activa.
Y vuelvo a hacer ahora click derecho en nuestro ADD EAX,1 y de nuevo CLICK DERECHO- NEW
ORIGIN HERE para volver a sumar 1 y apreto F7.

Vemos que EAX que valía uno, al sumarle uno nuevamente, ahora vale 2 que es 10 en binario y sigue el
resultado teniendo un solo uno por lo cual el flag P no se activo, si repito el procedimiento una vez mas,
volviendo atrás y apretando F7 para sumarle 1 nuevamente a EAX.

Ahora EAX vale 3 que en BINARIO es 11 o sea el resultado tiene un numero par de unos por lo cual se
activo el FLAG P o de paridad.
Con eso vemos como funciona el susodicho FLAG, al ejecutar una operación solo mira el resultado y si
el mismo en BINARIO tiene cantidad par de unos, se activa.
El FLAG Z o FLAG CERO
Uno de los más conocidos y usados en el cracking es el FLAG CERO el mismo se activa cuando
ejecutamos una instrucción y el resultado es cero.
Podemos volver con CLICK DERECHO-NEW ORIGIN HERE a nuestro ADD EAX,1 de 401000, pero
cambiemos ahora el valor de EAX a FFFFFFFF que es -1 decimal, de forma de que cuando apretemos F7
y ejecutemos ADD EAX,1 , sumemos -1 +1 el resultado sea cero a ver si se activa el FLAG Z.
Vemos que al apretar F7, EAX quedo en cero y como el resultado es cero, se activo el FLAG Z
poniéndose a uno.

Creo que queda claro que dicho flag, se activa cuando el resultado de una instrucción es cero ya veremos
diversas formas de activarlo mas adelante.
El FLAG S o FLAG DE SIGNO
Se activa cuando el resultado de una operación es negativo, o sea si quiero probarlo cambio EAX a
FFFFFFF8 que es -8 decimal

Y vuelvo con NEW ORIGIN HERE a mi ADD EAX,1 al apretar F7 y ejecutarlo, estoy sumando a -8 el
valor 1, el resultado es FFFFFFF9 que es -7 decimal, el cual es negativo aun por lo cual debería activarse
el flag de SIGNO probemos en OLLY.
Vemos que al apretar F7 y hacer la suma se activa el flag S de signo quedando a 1, queda claro como
funciona, resultado negativo de una instrucción se activa el FLAG S.
EL FLAG C o CARRY FLAG
Se activa cuando se excede el máximo valor posible que se puede mostrar, si ponemos EAX a FFFFFFFF
y le sumamos 1 como hicimos las veces anteriores veremos activarse el CARRY FLAG poniéndose a 1.

EL FLAG T , D e I
No los explicaremos por ahora pues son bastante complejos, si lo haremos mas adelante, no tiene mayor
interés por ahora, ya que vamos a explicar las instrucciones mas sencillas, así que los dejaremos para mas
adelante.
Bueno con esto tenemos una idea de que es cada registro y en que caso se activa cada FLAG, con esa
información ya podremos en la tercera parte estudiar instrucción por instrucción ya que por ahora solo
vimos la instrucción ADD para ayudarnos a comprender cuando se activaba cada FLAG.
Se que esta parte y la que viene son las mas indigestas de todas así que léanla con paciencia, practiquen
con el OLLY activar los FLAGS al ejecutar nuestro ADD EAX,1 y nos vemos en la parte 3 de esta
INTRODUCCION.
Es muy importante que queden bien grabados todos estos conceptos básicos, recomiendo leer practicar y
releer hasta que no haya dudas.
Hasta la parte 4
Ricardo Narvaja
10 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 4
INSTRUCCIONES
Como ya venimos diciendo en las anteriores partes, la idea de esta introducción es ir aprendiendo a la vez
que indigestándonos con la dura teoría, practicándola en OLLYDBG para ir conociendo el mismo, y de
paso ir tomado confianza e ir mirando las posibilidades que tiene.
Así como con los flags vimos en OLLYDBG que instrucciones los activaban, ahora veremos que ocurre
al ejecutar cada instrucción en el mismo OLLYDBG lo cual da una idea mas cercana a la realidad y se
hace mas llevadero.
Veremos las instrucciones mas importantes si al mirar un listado uno encuentra alguna que no se
definimos aquí, siempre se puede consultar un manual de ASM para ver que función cumple.
NOP (NO OPERATION)
Es la instrucción que al ejecutarla no hace nada ni provoca ningún cambio en registros, stack o memoria,
por eso en ingles es NO OPERATION o sea que no hay operación alguna, y para que se usa dirán,
muchas veces al cambiar una instrucción por otra, queda un hueco ya que la instrucción que escribimos es
mas corta, y hay que rellenar con NOPS para que el procesador no encuentre basura y de error.
También sirve para anular cualquier instrucción, si la reemplazo por nops el programa ejecutara los
mismos en vez de la instrucción original y no hará nada lo que es comúnmente conocido como NOPEAR.
Si abrimos nuevamente el crackme de cruehead.

Allí vemos el código original en el inicio, lo que haremos será nopear la primera instrucción PUSH 0, que
es un comando de 2 bytes de extensión, para ello marcamos la línea con el mouse, y luego apretamos la
barra espaciadora o bien hacemos CLICK DERECHO –ASSEMBLE.

Allí vemos que en el mismo menú nos confirma que es lo mismo apretar la barra espaciadora, esto nos
abrirá una ventana para escribir la instrucción que queramos.

Escribo NOP y apreto ASSEMBLE.
Vemos que OLLY además de escribirnos un NOP, como es bastante inteligente, reconoce que el PUSH
que había antes es un comando de DOS BYTES por eso para no desarmar el código siguiente nos agrega
otro NOP para completar con el NOPEADO del PUSH.
Si comparamos ambas imágenes vemos que donde estaba el PUSH 0 ahora hay dos NOPS que al
ejecutarlos no hacen nada, esto lo podemos corroborar, apretando dos veces F7 hasta llegar al CALL
siguiente, si miramos al apretar si cambia algún registro o algo en el stack, o un FLAG, vemos que todo
esta igual , lo único que cambio fue EIP pues como sabemos apunta a la instrucción que se va a ejecutar y
en este caso ahora es el CALL, pero no hay cambios en el resto de los registros ni stack, ni flags, ni
memoria.
Ahora veremos esos mismos 2 bytes que reemplazamos en el DUMP, para hallarlos allí, debemos
buscarlos por la dirección de memoria, vemos que la misma es 401000 y 401001

Voy a la ventana del DUMP y hago CLICK DERECHO - GOTO EXPRESSION y pongo la dirección de
memoria a partir de la cual quiero que muestre los bytes que contiene.

Por supuesto tipeo 401000

Los que vemos es
El rojo es original puesto POR OLLY ya que cuando cambiamos bytes, OLLY nos los recuerda
mostrandolos en color rojo, allí vemos los dos 90 que pusimos y luego E8, FF y los siguientes bytes que
ya pertenecen a la siguiente instrucción que es un CALL.
Podemos en OLLY quitar lo que hemos escrito y volver al código original?
Jeje, si podemos.
En cualquiera de los dos, sea en el DUMP o en el listado, marcamos los dos bytes que escribí.

Ahora hago CLICK DERECHO-UNDO SELECTION

Y aquí no ha pasado nada, vuelve a aparecer el PUSH original

Lo mismo si miramos el DUMP, vemos que ahora están los bytes originales.

Bueno eso es todo en cuanto a la instrucción NOP sigamos adelante.
INSTRUCCIONES DE STACK
Bueno habíamos dicho que el stack era como un mazo de cartas que se le agregaban o quitaban cartas por
arriba del mismo.
Por supuesto hay instrucciones para agregarle y quitarle cartas.
PUSH
La instrucción PUSH es la típica instrucción que agrega una carta o valor al stack
Veámoslo en OLLYDBG la primera instrucción del programa original del crackme de cruehead era un
PUSH.

En este caso es un PUSH 0, al ejecutarla lo que hará en este caso, será colocar el 0 en la posición superior
del stack, sin sobrescribir lo que se encontraba antes lo cual quedara debajo.
Veamos como esta el stack antes de ejecutar el PUSH, en mi maquina esta en esta dirección, en la de
ustedes puede variar aunque el efecto será el mismo.

Este es el stack en mi maquina, la dirección 12FFc4 puede variar en su máquina, ya que el stack se puede
acomodar en otra dirección en cada caso, y el contenido inicial a veces también puede variar o sea que
ustedes pueden tener otro valor que 7c816d4f, pero no importa al ejecutar F7, el cero pasara a la parte
superior del stack y el resto quedara abajo, veamos apreto F7.

Vemos que al ejecutar F7 fue realmente como si se agregara encima el cero que vemos resaltado allí,
abajo en 12ffc4 sigue estando 7c816d4f, y no vario nada todos los mismos valores están en las mismas
direcciones del stack.
La única diferencia que ahora el valor superior del stack es 12ffc0 y allí esta el cero que pusimos con el
PUSH, fue realmente como agregar una carta a un mazo, se coloco arriba y dejo el resto que estaba antes
sin cambiar nada debajo.
Vemos también que el puntero ESP que muestra la dirección del valor superior del stack ahora marca
12FFc0.

Por supuesto el comando PUSH tiene variantes no solo puedo agregar números, si hago:
PUSH EAX, agregare el valor de EAX en lugar del cero, podemos PUSHEAR cualquier registro, numero
etc.
Podemos PUSHEAR también el contenido de una dirección de memoria
PUSH [401008]
Veamos que se debe interpretar bien la diferencia con
PUSH 401008
Sin corchetes
Si hago PUSH 401008 lo que hará será colocar el número 401008 en el stack

Al ejecutarlo quedara así

En cambio si fuera PUSH [401008]
Los corchetes significan el contenido de la memoria en 401008 o sea que debemos ir en el DUMP a ver
esa dirección y ver que hay alli.
Con GOTO EXPRESSION 401008 vemos

Que los 4 bytes que hay allí son CA 20 40 00, ejecutemos con F7 el PUSH

Vemos que mando al stack el valor que leyó pero los bytes están al revés o sea nosotros vemos en el
dump CA 20 40 00 y los puso al revés o sea 00 40 20 CA.
Bueno esta es una propiedad del procesador, al leer o escribir contenidos de memoria siempre los bytes se
toman al revés, y bueno quejas al inventor del procesador jeje.
Pero la idea que debe quedar grabada es que sin corchetes el valor es simplemente un número, y con
corchetes el valor refiere al contenido de una dirección de memoria.
Ahora vemos que el OLLY cuando escribimos PUSH [401000] interpreto y escribió

PUSH DWORD PTR DS:[401008]
Porque ocurrió eso
Es que si uno no aclara el OLLY interpreta que uno quiere leer los 4 bytes de esa posición de memoria,
eso es DWORD leer los 4 bytes completos ya veremos las otras variantes en otras instrucciones.

POP
La instrucción POP es la inversa de PUSH lo que hace es quitar la primera carta o el primera valor del
stack y lo coloca en la posición que indicamos a continuación del POP, por ejemplo,
POP EAX tomara el primer valor del stack y lo quitara moviéndolo a EAX, y será como si quitamos una
carta, ya que el valor que estaba debajo quedara como primero.
Vemos arranquemos de nuevo el crackme de cruehead y en el inicio esta

Cambiemos dicha instrucción por POP EAX, marcamos la primera línea, apretamos la barra espaciadora
y tipeamos.

Ahí esta el stack antes de ejecutar la instrucción esta

Y ESP apunta a 12FFc4 que es el valor superior del stack.
Y vemos que EAX esta a cero antes de ejecutar la línea en mi caso.
Apreto F7

Vemos que en el stack desapareció nuestra primera carta, ahora el primer lugar lo ocupa la que entes
estaba 2da y ESP apunta a 12ffc8.

Pero donde fue a parar nuestra carta se perdió?, noo como era un POP EAX fue a parar a EAX vemos en
la imagen que EAX ahora vale 7c816d4f en mi caso y en el suyo tendrá el valor que antes estaba superior
en el stack en vuestra maquina.
Lo mismo si hubiera sido POP ECX el valor superior hubiera ido a ECX o al registro que eligiéramos.
Bueno ya vimos las instrucciones que ponen o quitan una carta al stack ahora tenemos.
PUSHAD
PUSHAD guarda el contenido de los registros en la pila en un orden determinado. Así pues, pushad
equivale a: push EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI.
Veamos si es cierto lo que nos dice nuestro amigo CAOS REPTANTE en su tute de asm, jeje.
Abrimos de nuevo el crackme de cruehead y ya sabemos que apretamos la barra para escribir y alli
tipeamos PUSHAD.
Allí esta mi stack inicial y los registros antes de ejecutar el pushad son

Apreto F7 y veamos que paso en el stack

Vemos que hizo un PUSH a cada uno de los registros, el primero que agrego esta arriba de 12ffc4 que era
el valor superior del stack antes de ejecutar, ahora hay un cero arriba que corresponde a PUSH EAX,
luego hizo PUSH ECX y mando el 12ffb0 que estaba en ECX, luego envió consecutivamente los valores
de los registros uno a uno al stack hasta el ultimo que fue PUSH EDI.
POPAD
La inversa de PUSHAD es POPAD en este caso toma los valores del stack y los manda a los registros
como si fuera un POP a cada uno. Así popad equivale a: pop EDI, ESI, EBP, ESP, EBX, EDX, ECX,
EAX.
Allí mismo donde quedo del ejemplo anterior escribamos un POPAD

Allí esta para ejecutarse el POPAD los registros están guardados en el stack y al apretar F7 vuelven del
stack a sus lugares originales.

Allí esta el stack como era antes del pushad y los registros recuperan sus valores

La dupla PUSHAD-POPAD se usa mucho cuando se quiere guardar el estado de registros en un punto,
realizar muchas operaciones que cambian registros y el stack, y luego con POPAD restaurar los registros
y el stack al estado original.
Existen algunas variantes como

PUSHA equivale a: push AX, CX, DX, BX, SP, BP, SI, DI.
POPA equivale a: pop DI, SI, BP, SP, BX, DX, CX, AX (los valores recuperados correspondientes a ESP
y SP, no se colocan en los registros sino que se descartan).
En el caso de PUSHA y POPA es similar a sus hermanas PUSHAD y POPAD salvo se que utilizan en
programas de 16 bits lo cual no nos interesa ya que OLLYDBG es un debugger para programas de 32
bits.
INSTRUCCIONES PARA MOVER DATOS
MOV
Esta instrucción es lo que comúnmente llamaríamos MOVER, mueve el segundo operando al primero por
ejemplo.
MOV EAX, EBX
Lo que hace es mover el valor de EBX a EAX, miremos en OLLY y nuestro bendito crackme de
cruehead.

Ya no repetiré como se escribe una instrucción ya lo hemos visto, veamos los registros antes de ejecutar

En mi maquina EAX es 0 y ECX es 7c91eb94, como son valores iniciales en la suya pueden ser
diferentes pero al apretar F7 lo importante es que el valor de EBX lo moverá a EAX, veamos apretemos
F7.

Viola esta claro no?
MOV tiene variantes por ejemplo
MOV AL, CL
Esto movería el valor de CL a AL veamos reinicio OLLYDBG y escribo
Los registros

Recordamos lo que vimos ya que AL son las ultimas dos cifras de EAX y CL las dos ultimas cifras de
ECX, ejecutemos con F7

Vemos que sin tocar el resto de EAX y ECX el B0 se copio a AL, o sea las ultimas dos cifras de EAX.
También podemos mover a algún registro el contenido de una posición de memoria o al revés.

En esta caso moveremos el contenido de 405000 a EAX y como dice DWORD serán los cuatro bytes lo
que moveremos.
Esta instrucción puede dar error si la dirección de memoria no existe, lo cual podemos ver fácilmente en
el OLLY.
Vamos al DUMP y hacemos GOTO EXPRESSION 405000
Vemos que existe y su contenido es 00 10 00 00 o sea al moverlo a EAX, dado que trabajamos con el
contenido de una dirección de memoria se moverá al revés o sea 00 00 10 00 apretemos F7 a ver que pasa

Allí esta el 1000 que leyó de dicha dirección de memoria, ahora si quisiera escribir un valor en dicha
dirección seria
MOV DWORD PTR DS:[400500],EAX
Reinicio el OLLYDBG y la escribo

En 405000 veo en el DUMP

Al apretar F7 oops

Me da una excepción y eso es porque la sección donde vamos a escribir no tiene permiso de escritura, lo
cual impide cambiar bytes ejecutando instrucciones.
Bueno ya veremos como cambiar permisos de secciones mas adelante lo importante es que ya conocen la
instrucción.
Obviamente como podemos mover 4 bytes especificando la palabra DWORD si usamos WORD moverá
2 y si usamos BYTE moverá 1 .
Veamos
MOV AX,WORD PTR DS:[405008]

En este caso moverá dos bytes del contenido de 405000 a AX, en este caso no podemos escribir EAX ya
que como son solo 2 bytes los que movemos debemos usar el registro de 16 bits AX.
Veamos que hay en el DUMP en 405008

Al apretar F7 debería mover solo esos 2 bytes a AX, veamos

Allí esta en AX, al revés como corresponde a leer de contenidos de memoria, el resto de EAX no ha sido
cambiado solo lo correspondiente a AX.
Lo mismo seria si usáramos BYTE
MOV AL, BYTE PTR DS:[405008]
En este caso movería a AL el ultimo byte solamente o sea el 08.
MOVSX (Move with Sign-Extension)
Copia el contenido del segundo operando, que puede ser un registro o una posición de memoria, en el
primero (de doble longitud que el segundo), rellenándose los bits sobrantes por la izquierda con el valor
del bit más significativo del segundo operando. Aquí tenemos un par de ejemplos:
La definición la sacamos del tute de CAOS ahora veamos un ejemplo en OLLYDBG para aclarar y
usemos a nuestro amigo CRUEHEAD.

Como aun no se los dije porque soy muy malo y quería que siempre buscaran a mano, los valores de los
operandos jeeje, OLLYDBG tiene una ventana de aclaraciones que esta justo debajo de el listado y arriba
del DUMP.

Allí vemos que la ventana de aclaraciones nos muestra el valor de los operándoos de nuestra instrucción
en mi caso BX vale F000 eso lo puedo corroborar en los registros

Y allí mismo veo que EAX vale cero, así que siempre el OLLYDBG nos ayuda a interpretar los
operandos de la instrucción a ejecutar. (que malo soy jeje pero quise que fijen el concepto de donde
buscar cada cosa antes de la comodidad jeje)
Al apretar F7
Vemos que se copia el BX que era F000 a AX y que se rellena con FFFF ya que el numero es un negativo
de 16 bits , si hubiera sido BX 1234 entonces quedaría EAX=00001234 ya que rellena con ceros al ser
BX positivo.
El tema de los positivos y negativos de 16 bits es similar a 32 bites se divide por la mitad el espacio 0000
a FFFF
de 0000 hasta 7FFF son positivos y de 7FFF a FFFF son negativos vemos que si modificamos BX a
7FFF y ponemos EAX a cero y volvemos a ejecutar la instrucción

Copia 7FFF a AX pero rellena con ceros ya que 7FFF es positivo si repetimos pero con BX=8000 que es
negativo,

Ejecuto nuevamente con F7 y

Copia BX a AX y rellena con FFFF ya que 8000 es negativo
MOVZX (Move with Zero-Extend)
Igual a movsx, pero en este caso, los espacios sobrantes se rellenan siempre con ceros o sea no depende
de si el segundo operando es positivo o no como en el caso anterior no haremos ejemplos porque es
sencillo darse cuenta que todos los ejemplos anteriores darían en EAX 0000…… y a continuación los
bytes de BX que se copiaron a AX.

LEA (Load Effective Address)
Similar a la instrucción mov, pero el primer operando es un registro de uso general y el segundo una
dirección de memoria. Esta instrucción es útil sobre todo cuando esta dirección de memoria responde a un
cálculo previo.
Esto nos dice nuestro amigo CAOS y significa que en este caso por ejemplo reinicio OLLY.

Aquí es el único caso en que hay corchetes que no se mueve el contenido de la dirección de memoria que
se calcula dentro del corchete si no la dirección en si.
En mi caso ECX vale 12FFb0

Y lo que hace LEA es sumarle 38 en este ejemplo y mover ECX mas 38 que es igual a 12ffe8 a EAX
En la ventana de las aclaraciones ya muestra ambos operándoos

Muestra que un operando es 12FFe8 que proviene de sumar ECX+38 y EAX vale cero antes de operar.
Al apretar F7
Dicha dirección se mueve a EAX, hay que tener cuidado porque los corchetes nos llevan a pensar que
deberíamos mover el contenido de la dirección 12ffe8 que debemos buscar en el dump como en el caso de
la instrucción MOV, pero LEA solo mueve la dirección al primer operando no su contenido.
XCHG (Exchange Register/Memory with Register)
Esta instrucción intercambia los contenidos de los dos operandos.
En este caso intercambia los valores si escribimos
XCHG EAX,ECX
El valor de EAX pasara a ECX y viceversa comprobémoslo en OLLY

Antes de ejecutar en mi maquina EAX vale cero y ECX vale 12FFb0

Al apretar F7 vemos que intercambian sus valores

También se puede usar para intercambiar con una posición de memoria siempre que tenga permiso de
escritura dicha sección

Al ejecutar con F7
Nos pasa lo mismo que cuando quisimos hacer MOV a dicha dirección al no tener permiso de escritura
nos genera una excepción.
Bueno creo que como primera parte de las instrucciones ya tienen para divertirse y practicar, creo que los
ejemplos si los van haciendo mientras leen aclaran bastante la cosa, en la siguiente parte seguiremos con
mas instrucciones hasta terminar con las mas importantes y tratar de terminar esto que es lo mas duro.
Hasta la parte 5
Ricardo Narvaja
13 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 5
INSTRUCCIONES MATEMATICAS
INC Y DEC
Estas instrucciones incrementan o decrementan respectivamente el operando, sumándole uno si es INC o
restándole uno en el caso de DEC.
Veamos en el OLLY, como siempre abrimos el OLLYDBG y el crackme de cruehead y en la primera
línea escribimos

EAX en el estado inicial en mi maquina esta a cero, si no puedo cambiarlo a cero a mano

Así que al apretar F7 y ejecutar la instrucción se INCREMENTARA EAX en uno veamos apretemos F7

Lo mismo ocurre con DEC podemos escribirlo debajo del anterior

Al apretar F7 y ejecutar la instrucción se DECREMENTA EAX que estaba en 1 y volverá a 0.
También se pueden incrementar o decrementar el contenido de posiciones de memoria

Aunque en este caso la sección no tiene permiso de escritura y no dejara aumentar el contenido dando
excepción.

Si la sección hubiera tenido permiso de escritura, vamos en el dump a la dirección 405000

Ya que el contenido al leerlo al revés es 00001000, si lo incrementamos seria 00001001 o sea quedaría
así

Este fue el caso para DWORD sumándole UNO a los 4 bytes del contenido.

En el caso de WORD el ejemplo sumaria solo a los últimos 2 bytes

Y en el caso de BYTE sumaria solo al último byte

ADD
Add como ya vimos es la instrucción correspondiente a la suma, siempre suma ambos operandos y
guarda el resultado en el primero.
ADD EAX,1 es similar a INC EAX
También puede sumar registros
Veamos en OLLY
Antes de ejecutar la operación

En mi maquina EAX vale 00000000 y ECX vale 12FFB0 en sus maquina puede tener otros valores,
pueden cambiarlos si quieren, pero al apretar F7 sumara ambos y guardara el resultado en EAX, veamos

Allí esta EAX esta en rojo pues fue el que se modifico y tiene el resultado de la suma.
También podemos sumar a un registro el contenido de una memoria

En este caso no hay problema por el permiso de escritura ya que como EAX cambiara y guardara el
resultado y el contenido de [405000] no cambiara ya que es el segundo operando, la operación no
generara excepción.
Antes de apretar F7 vemos que EAX vale 0 y el contenido de 405000 vale 00001000
Apreto F7 y se ejecuta la suma

Entonces EAX=0 mas 1000 se modifica EAX quedando el resultado allí que es 1000.
Si hacemos al revés y escribimos

En este caso el resultado se guardara en el contenido de 405000 y esto modificara el mismo por lo cual al
apretar F7 generara una excepción al no tener permiso de escritura.

ADC (ADD WITH CARRY)
En este caso se suman ambos operandos y se le suma el valor del CARRY FLAG O FLAG C y se guarda
en el primer operando.
Allí vemos que sumara EDX que vale 21 mas 3 mas el valor del flag C, que en este caso es cero, si apreto
F7.

Veo que el resultado es 24, pero si repito la operación con el FLAG C puesto a 1 el cual se puede cambiar
haciendo doble click en el mismo.

Allí lo cambie a uno y pongo todo como antes para repetir la operación solo cambiando el flag C.
Apreto F7 para que se realice la suma y ahora el resultado es 25

Ya que suma EDX =21 mas 3 mas el FLAG C que en este caso vale 1.
SUB
Es la resta o substracción o sea la operación contraria a ADD, lo que hace es restar el segundo operando
al primero y guardar el resultado en el primer operando.

En mi maquina los registros valen antes de ejecutar

Al apretar F7 le restara a EAX que vale cero el valor 2
El resultado es -2 que en hexadecimal se representa FFFFFFFE si hacemos doble click en dicho valor

Vemos que corresponde al decimal -2.
También se pueden restar registros, y posiciones de memoria en la misma forma que lo hicimos con
ADD.
SUB EAX,ECX
Por ejemplo hará EAX-ECX y guardara el resultado en EAX
Y
SUB EAX,DWORD PTR DS:[405000]
Restará a EAX el contenido de la posición de memoria 405000, guardando el resultado en EAX.
En el caso inverso
SUB DWORD PTR DS:[405000],EAX
Ya que el resultado se guarda en el primer operando, si no tenemos permiso de escritura en la sección, nos
dará una excepción.
SBB
Es la operación contraria a ADC, es este caso se restan ambos operandos y se le resta el valor del CARRY
FLAG O FLAG C y se guarda en el primer operando.

Antes de ejecutar la operación ponemos EDX a 21 y el carry flag a 0
Al apretar F7 hará EDX-3 y le restara cero del FLAG C

Ahora su repito la operación con el FLAG C a 1

Apreto F7 y ahora hará EDX-3 y le restara 1 del FLAG C
En este caso el resultado es 1D.
MUL
Bueno hay dos instrucciones para realizar multiplicaciones, la primera de ellas es MUL, la cual no
considera los signos de los números que va a multiplicar, y usa un solo operando el otro operando es
siempre EAX aunque no se escribe y el resultado lo guarda en EDX:EAX que quiere decir esto veamos
el ejemplo.

Por ejemplo
MUL ECX
Esto multiplicara ECX por EAX y guardara el resultado en EDX:EAX y no considerara el signo de los
operandos.
Por ejemplo veamos en OLLYDBG

Pongo EAX a FFFFFFF7 y ECX a 9 si realizo la multiplicación en la calculadora de Windows veo que
El resultado es

Y no entra en EAX veamos que pasa en OLLY al apretar F7

Allí vemos en rojo que EDX y EAX cambiaron y como vemos guarda en EAX los bytes que entran allí y
luego guarda los que no entran en EDX, en este caso el 8 que no puede mostrar EAX, lo guardo en EDX,
por eso se dice que en este caso el resultado se muestra en EDX:EAX ya que usa ambos como si fueran
un solo registro del doble de largo.
En el caso
MUL DWORD PTR DS:[405000]
Multiplicara el contenido de 405000 por EAX y como siempre guardara el contenido en EDX:EAX sin
considerar el signo de los operandos.
Siempre que en OLLY queramos ver cuanto es el valor de un numero hexadecimal sin signo, hacemos
doble click en cualquier registro
Como habíamos visto la segunda línea nos daba el valor con signo en este caso FFFFFFAF es -81
considerado con SIGNO, pero en operaciones como MUL donde los números se consideran SIN SIGNO
el valor decimal se lee en la tercera línea la que dice UNSIGNED, allí vemos 4294967215 seria el valor
tomando al numero como positivo o sin SIGNO.
IMUL (multiplicación con signo)
La instrucción IMUL no solo es multiplicar con signo de la misma forma que lo hacia MUL
IMUL ECX
Es igual que antes ECX por EAX y el resultado se guarda en EDX:EAX salvo que se considera el signo
de los operandos.
Además de la similitud con la instrucción anterior IMUL permite poner mas de un operando, lo que no
estaba permitido en MUL.
Del tute de CAOS
Además de la utilización de los registros EAX y EDX, así como de sus subdivisiones, pueden
especificarse otros orígenes y destinos de datos y puede haber hasta tres operandos. El primero, es el lugar
donde se va a guardar el resultado, que debe ser siempre un registro, el segundo y el tercero son los dos
valores a multiplicar. En estos ejemplos vemos como estas instrucciones con dos o tres operandos, tienen
el mismo espacio para el resultado que para cada uno de los factores:
F7EB

imul ebx

EAX x EBX -> EDX:EAX

Este primer ejemplo es el conocido y similar a MUL salvo que se consideran los signos
696E74020080FF

imul ebp, dword ptr [esi+74], FF800002

[ESI+74] x FF800002 -> EBP

Este es el segundo ejemplo que pone veamos en este caso hay tres operandos, multiplica el contenido de
ESI+74 por FF800002 y el resultado lo guarda en EBP, podemos hacerlo en OLLY
Copio la linea imul ebp, dword ptr [esi+74], FF800002 al OLLY

Veo que al apretar ASSEMBLE me da error y eso es porque en el OLLY los números que empiezan por
letras deben agregársele un cero delante si no, no los interpreta, corrijamos
Ahora apreto ASSEMBLE y lo acepta

Cambio el valor de ESI a 401000 para asegurarme que la dirección ESI mas 74 exista y se pueda leer su
contenido

Veamos en la aclaración del OLLY

Alli nos dice que ESI + 74 es la dirección 401074 y que su contenido es C7000000, veamos en el dump
con GOTO EXPRESSION 401074.

Y si, es cierto el contenido leído al revés seria C7000000, eso lo multiplicara por FF800002 y como el
primer operando es EBP pues guardara allí el resultado
imul ebp, dword ptr [esi+74], FF800002
Al apretar F7 vemos que se puso rojo EBP ya que ahora contiene el resultado
El resultado en la calculadora nos da C7000000 * FF800002

Pero como especificamos que se muestre en EBP pues solo muestra los bytes que caben allí, el resto los
descarta.
En el tercer ejemplo que hay solo dos operandos se multiplican ambos y el resultado se guarda en el
primero.

0FAF55E8

imul edx, dword ptr [ebp-18]

EDX x [EBP-18] -> EDX

Como vemos la mejor opción para multiplicar números largos es usando IMUL con solo un operando
pues en este caso el resultado lo guarda en EDX:EAX con la posibilidad del doble de largo lo cual no
ocurre cuando usamos dos o tres operandos, dichas opciones son mas útiles en operaciones pequeñas.
DIV (Unsigned Divide) / IDIV (Signed Divide)
Estos son la contrapartida de MUL Y IMUL respectivamente
DIV solo tiene un operando y no considera los signos y el resultado se guarda en EDX:EAX
IDIV siempre considera los signos si usa un solo operando será como DIV y guardara en EDX:EAX y en
el caso de dos operandos dividirá ambos y guardara en el primero, y en el de tres operandos dividirá el
segundo y el tercero y guardara en el primero.
No creo que sea necesario repetir los ejemplos pues son similares a los de MUL e IMUL.
XADD (Exchange and Add)
Es como realizar en una sola instrucción XCHG y ADD o sea que si tenemos
XADD EAX,ECX
Allí vemos ECX que es 1 y EAX es 7 al apretar F7 se intercambian o sea que EAX pasa a valer 1 y ECX
9 luego se suman

Como vemos el resultado se sigue guardando en el primer operando, lo único que cambio fue que se
intercambiaron los valores antes de sumarlos, vemos que ECX quedo valiendo 9 que era lo que valía
EAX antes de intercambiarse y sumarse.
NEG
Esta instrucción tiene la finalidad de cambiar de signo el número representado o sea que si tenemos el
número 32 en hexa y le aplicamos NEG el resultado será el negativo del mismo.
Ejemplo

Escribo en OLLY NEG EAX y pongo en EAX el valor 32
Al apretar F7 quedara en EAX el negativo de 32 veamos

Allí vemos el resultado -50 en decimal como nos muestra la segunda columna corresponde a -32 en hexa.

Allí esta si tipeamos en la comandbar que nos de el valor de -32 hexa en decimal, nos dice -50 y nos
aclara que se escribe FFFFFFCE ya que no se puede escribir el signo en OLLY.
Pues como vemos la instrucción NEG nos convierte el operando en su negativo.

INSTRUCCIONES LOGICAS
Provienen de realizar operaciones lógicas entre dos operandos pasados a binario bit a bit y guardando el
resultado en el primer operando

AND
El resultado es 1 si los dos bits son 1, y 0 en cualquier otro caso.
1 and 1 = 1
1 and 0 = 0
0 and 1 = 0
0 and 0 = 0
Vemos un ejemplo en OLLYDBG
AND EAX,ECX

Pongamos ECX=0001200 y EAX=3500

Si lo hiciéramos a mano deberíamos pasar a binario ambos
1200 en binario seria 01001000000000
3500 en binario seria 11010100000000
Aplicándole la tablita de la operación AND bit a bit vemos que por ejemplo la ultima cifra

Al hacer AND entre dos ceros el resultado seria cero, así hay que hacer bit a bit y nos daría
01000000000000 ya que el resultado es uno solo cuando los dos bits son 1 y eso ocurre solo en
la columna resaltada.

Si ejecutamos F7 en el OLLY vemos el resultado en ECX que es 1000 que pasado a binario es
01000000000000
OR
En esta instrucción realizamos el mismo proceso que la anterior solo que en vez de utilizar la tablita AND
para hallar el resultado entre bits, lo hacemos con la tablita OR

El resultado es 1 si uno o los dos operandos es 1, y 0 en cualquier otro caso.
1 or 1 = 1
1 or 0 = 1
0 or 1 = 1
0 or 0 = 0

XOR
Aquí es similar solo que usamos la tablita de la función XOR para las operaciones entre bits
El resultado es 1 si uno y sólo uno de los dos operandos es 1, y 0 en cualquier otro caso
1 xor 1 = 0
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0

NOT

Simplemente invierte el valor del único operando de esta función
not 1 = 0
not 0 = 1
Ejemplo: not 0110 = 1001

Si tenemos por ejemplo EAX=1200 que en binario es 1001000000000 convertimos los 0 en 1 y los 1 en 0
considerando que es un numero de 32 bits y que al inicio tiene ceros o sea seria llenado de ceros delante
hasta completar los 32 bits.

00000000000000000001001000000000
Al hacerle NOT quedaría
11111111111111111110110111111111
que en la calculadora de Windows vemos que es FFFFEDFF en hexa
En OLLY antes de apretar F7 pongo EAX a 1200

Apreto F7

Vemos que el resultado es el mismo

Bueno aquí terminamos esta quinta parte veo que esto es un poco mas largo de lo que pensaba pero bueno
vamos paso a paso, nos quedan ver las comparaciones, los saltos y los call y ret.
Bueno paciencia que despacio se llega a ROMA
Hasta la parte 6
Ricardo Narvaja
14 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 6

COMPARACIONES Y SALTOS CONDICIONALES
En términos generales, las comparaciones entre dos operandos, y según el resultado de esa comparación
la decisión si el programa saltara o no en un salto condicional posterior, suele ser lo primero que se
menciona en cualquier tute básico que comienza desde cero de cracking.
Sabemos que si el programa nos pide un serial para registrarnos, en algún momento deberá decidir si es
correcto no y para ello deberá comparar y realizar uno o varios saltos y la dirección adonde saltará variará
según si pusiste bien el serial o no.
Ahora como funciona en profundidad la comparación y el salto es lo que veremos a continuación.
Sabemos porque lo hemos visto ya en partes anteriores de esta introducción, que según el resultado una
instrucción se activan o desactivan los flags, el caso mas conocido es el flag que se activa cuando el
resultado de una instrucción es cero el FLAG Z y hemos visto diferentes formas de activar los flags según
el resultado de una instrucción.
CMP
Esta es la instrucción mas conocida de comparación y lo que hace es comparar dos operandos, en realidad
es una instrucción SUB, que no guarda el resultado de la resta en el primer operando, ambos operandos
quedan igual, lo que cambian son los flags según el resultado.
Como vimos si hacemos por ejemplo
CMP EAX, ECX
Siendo EAX y ECX iguales, se restan ambos, no se modifican, pero el resultado de la resta es cero lo que
hace activar el flag Z, veamos el ejemplo en OLLYDBG.

Allí escribí la instrucción y ahora modificare EAX y ECX para que sean iguales.

A apretar F7 veo que EAX y ECX no modificaron su valor pero se activo el flag Z, al haber realizado una
resta y ser su resultado CERO aunque no podamos ver el resultado ya que no lo guarda.
En realidad no nos importa el resultado numérico de la resta en si, sino que de alguna forma podemos
saber según los flags si EAX era igual a ECX, o si son desiguales, cual es mayor.
Como comentario ya que aun no hemos llegado a los saltos condicionales, los tienen dos posibilidades,
deciden si saltar o no saltar según el estado de los flags, el mas claro ejemplo y que trabajaría en conjunto
con la comparación anterior es el salto JZ que salta si el FLAG Z esta activo o a UNO y no salta si esta
inactivo o a CERO.
De esta forma se logra que el programa tome una decisión, si fueran dos seriales que esta comparando,
por ejemplo en EAX esta el serial que vos ingresaste para registrar un programa y en ECX esta el serial
correcto, el programa podría decidir con un CMP que si son iguales se activa el flag Z, y el salto JZ al ver
el flag activo, nos llevara a una zona para usuarios registrados, y si el serial que tipeaste y esta en EAX no
es igual al de ECX que es el correcto, seguí intentando jeje, el flag Z sigue a CERO, y no salta
manteniéndote en la zona de usuario no registrado.
Ya veremos los ejemplos más concretos al estudiar los saltos condicionales.
De la misma forma con el flag S o de signo podemos ver si en una comparación el primer operando era
mayor que el segundo, o al revés.
Miremos el ejemplo
Repitamos el CMP EAX, ECX pero ahora pongamos EAX mayor que ECX

Si apretamos F7
Vemos que el FLAG Z es cero por lo cual ya sabemos que no son iguales, y a la vez el flag S es cero lo
cual quiere decir que al hacer la resta EAX-ECX el resultado es positivo, lo cual significa que EAX es
mayor que ECX.
De la misma forma si repetimos la operación con EAX menor que ECX

Y apretamos F7

Allí vemos que al dar la resta de EAX con ECX negativa ya que ECX es mayor, se activa el FLAG S que
recordamos se activa con resultados negativos.
Las diferentes posibilidades de comparación activaran los correspondientes flags y según lo que el
programa necesite saltara o no de acuerdo a chequear la activación de uno o mas de dichos flags.
También permite la comparación entre registros y posiciones de memoria utilizando DWORD, WORD y
BYTE .

Allí compararía EAX con el contenido de 405000 y como siempre la ventana de aclaraciones del OLLY
nos da el valor de cada operando en mi caso

Al apretar F7 en este ejemplo y EAX es menor que el contenido de 405000 que es 1000, dará un resultado
negativo y activara el FLAG S.
Existen en forma similar
CMP AX,WORD PTR DS:[405000]
Y
CMP AL,BYTE PTR DS:[405000]
En el caso de comparar 2 bytes o 1 byte del contenido de la memoria.

TEST (Logical Compare)

El principio de esta instrucción es, en cierto modo, el mismo de cmp, es decir, una operación entre dos
valores que no se guarda, sino que puede modificar el estado de algunos flags (en este caso, SF, ZF y PF)
que determinan si debe efectuarse el salto que también suele acompañar a esta instrucción. La diferencia
está en que en este caso, en vez de tratarse de una resta, se trata de una operación AND.
Esto nos dice nuestro amigo CAOS en su tute de ASM veremos ejemplos para aclarar la definición,
generalmente el comando TEST lo veremos en este formato
TEST EAX,EAX
Ustedes dirán para que quiere testearse contra si mismo el valor de EAX o el registro que sea?
Pues se usa esta instrucción, para saber si EAX en este caso es cero o no, y como funciona?
Escribamos en OLLY
TEST EAX,EAX

La tablita de la operación AND era

. El resultado es 1 si los dos operandos son 1, y 0 en cualquier otro caso.
1 and 1 = 1
1 and 0 = 0
0 and 1 = 0
0 and 0 = 0
Vemos que la única forma que el resultado sea cero es que ambos operandos sean cero (no
interesan en este caso los casos de bytes diferentes pues EAX esta operando contra si mismo, por lo que
ambos bytes siempre son iguales) pues si EAX en binario tiene algún bit que es 1, al hacer AND contra si
mismo daría 1 y ya no podría ser cero el resultado.
Pongamos EAX igual a CERO
En el OLLYDBG eso sea realiza fácilmente haciendo CLICK DERECHO en el registro a
modificar y eligiendo ZERO.

Allí esta apreto F7

Vemos que se activo el flag Z o sea como sabíamos la operación AND entre dos valores que son
cero es igual a cero y se activara.
Si repito la operación con EAX diferente de cero

Apreto F7
Y el FLAG Z no se activa al ser el resultado diferente de cero.
Si uso la calculadora puedo comprobar que 390 AND 390 da como resultado 390
En binario 390 es 1110010000

Como la operación AND si ambos operandos son CEROS dará como resultado cero y si son dos UNOS
dará como resultado UNO, vemos que el resultado no cambiará o sea será 390 en hexadecimal, y no se
activara el flag Z.

Hay alguna instrucciones mas de comparación pero estas son las principales llego el momento de ver los
saltos
SALTOS
Todos as instrucciones de salto tienen un solo operando que es la dirección adonde saltaría el
programa, veamos los diferentes tipos aquí en la tabla y aclarémoslos.

JMP
Es el salto directo o incondicional, aquí no hay ninguna decisión SIEMPRE saltara a la dirección que nos
muestra el operando por ejemplo veamos en OLLY

Al ejecutar ese salto el programa ira a 401031 y seguirá ejecutándose desde allí.
Tenemos un par de lindas configuraciones del OLLY para los saltos que les enseñare aquí, así son mas
visibles los mismos.
Si vamos a OPTIONS-DEBUGGING OPTIONS

Y allí en la pestaña CPU

Marcamos estas tres tildes

Vemos que la información es mucho mayor ahora y mas visible
Vemos que OLLYDBG ahora nos muestra con una flecha roja que va a saltar y además a adonde va a
saltar, exactamente a 401031.
Si ejecuto ahora con F7

Se realizo el salto y EIP es 401031

Ya que EIP apunta a la instrucción que se va a ejecutar a continuación, en este caso 401031.

JE o JZ
Ambos son el mismo tipo de salto condicional y pueden escribirse de las dos formas ya vimos que JZ
saltara cuando el flag Z sea cero.

Escribamos en OLLYDBG dos instrucciones una comparación y el salto así verificamos como funciona.
Pongo EAX y ECX iguales
Al ejecutar la comparación se realiza la resta y como ambos son iguales se activa el FLAG Z al ser el
resultado CERO.

La siguiente instrucciones es el salto condicional veamos

OLLYDBG ya nos avisa la decisión y como el FLAG Z esta activado nos muestra en rojo que va a saltar,
si la indicación estuviera en gris quiere decir que la decisión es no saltar, en este caso saltara, apreto F7.
Allí vemos que salto y EIP ahora es 401031.
Repitamos el ejemplo con EAX diferente de ECX

Al apretar F7 en la primera instrucción como el resultado no es cero, el flag Z no se activa.

Y vemos en OLLY

Que como el JE salta si el flag Z es UNO, en este caso no saltara, y la flecha del salto esta gris, al apretar
F7 nuevamente
Vemos que no salto y siguió a continuación en 401004, esto que parece tan tonto es la base de la
comparaciones y decisiones en todos los programas.
Si repito el ejemplo anterior y llego al salto, nuevamente y no va a saltar

Sabemos que no salta porque el flag Z esta a cero, ahora que ocurre si hago doble click en el flag Z y lo
cambio a 1.

Vemos que la flecha cambio a rojo y OLLYDBG saltara, independientemente de la comparación,
manipulando directamente el flag, ya que la decisión se toma sobre el estado actual del mismo, si cambia
el flag cambiara el salto.
Los otros saltos los veremos rápidamente con un ejemplo cada uno
JNE o JNZ
Es el opuesto al salto anterior en este caso, salta si el flag Z no esta activo o sea si el resultado de la
operación fue distinto de cero.
Allí escribo la comparación y el JNZ
Si EAX y ECX son iguales se activa el FLAG 0 al ser la diferencia CERO

Y al revés que el JZ que saltaba al estar el FLAG Z activo este es el opuesto, salta cuando el FLAG Z es
cero o esta inactivo.
Se puede entender que si pongo EAX diferente de ECX, el resultado será diferente de cero y el flag Z
quedara inactivo y allí si saltara.
JS
Como vemos en la tabla saltara si la comparación da un resultado negativo o sea si EAX en menor que
ECX en el ejemplo anterior.

Al apretar F7
El FLAG S se pone a 1 y saltara al ser negativo,

Allí vemos que la flecha roja nos indica que saltara, en el caso que EAX sea mayor que ECX el flag S no
se activara al ser un resultado positivo y el salto JS no saltara.
JNS
Es el opuesto al anterior saltara cuando el FLAG S este a cero o sea cuando el resultado sea positivo, en el
ejemplo anterior cuando EAX sea mayor que ECX.
JP o JPE
En esta caso el salto condicional JP saltara cuando el FLAG P este activo y esto ocurrirá como habíamos
visto cuando el resultado de la comparación tenga paridad par o par cantidad de unos al verlo en binario.

Ponemos EAX a 20 y ECX a 18 y apretamos F7
Como la diferencia entre EAX y ECX es 2 y este pasado a binario es 10 que tiene 1 solo uno o sea una
cantidad impar de unos, el flag P no se activa y el JPE no saltara.

Ahora si cambio ECX a 17 y repito apreto F7

Vemos que al ser el resultado 3 que en binario es 11 y tiene un número par de unos, entonces allí si se
activa el FLAG P y el JPE saltara.

JNP o JNPE
Es el opuesto del anterior o sea este salta cuando el flag P esta a cero o sea la paridad es impar, en el
ejemplo anterior hubiera saltado la primera vez cuando el resultado era 2 y no hubiera saltado cuando el
resultado era 3, al revés del JP.
JO
Este salta cuando hay overflow o capacidad excedida lo cual activa el flag O.

Aquí cambiamos la comparación porque para activar el FLAG O hay que hacer OVERFLOW y esto es
posible mediante una suma.

Apreto F7

Y el JO saltara al haberse activado el FLAG O por OVERFLOW o capacidad excedida.
JNO
Es el opuesto al anterior este salta cuando el FLAG O esta a CERO o sea no hay OVERFLOW
JB
Salta si es mas bajo, veamos el ejemplo
Vemos que EAX es mas bajo que ECX o sea que debería saltar, al apretar F7

El flag C se activa, ya que tiene que al hacer la diferencia que da un numero negativo, en el bit mas
significativo o sea el primero habrá acarreo y eso activa el FLAG C, y según eso decide el JB en
resumidas cuentas si EAX era menor que ECX.
JNB
Es el opuesto de JB saltara si el FLAG C es cero o sea no hay acarreo porque el resultado fue positivo, lo
cual supone que EAX fue mayor que ECX y al revés que el anterior este saltara en ese caso.
JBE
Este salta si es mas bajo o igual o sea testea dos flags a la vez ve si el FLAG C esta activo en ese caso
salta, y también verifica si el FLAG Z esta activo con el cual también salta, o sea si EAX es igual a ECX
saltara y si es menor también.

Ponemos como primer caso que EAX y ECX sean iguales
Apreto F7

Al ver que el flag Z esta activo salta

Si EAX es menor que ECX

Apreto F7
En este caso se activa el FLAG C al ser resultado negativo que usa un carry en el bit mas significativo, o
sea salta cuando EAX es menor a ECX también
En el ultimo caso que EAX es mayor a ECX repito el ejemplo apreto F7

Ambos flags Z y C están a cero por lo tanto no saltara

O sea la conclusos es que JBE salta si EAX es mas bajo o igual que ECX en el ejemplo.
JNBE
Es el opuesto al anterior, salta si el flag Z y el FLAG C son cero ambos o sea solo en el ultimo ejemplo
anterior cuando EAX es mayor que ECX, allí ambos flags están a cero y este JNBE saltara.
JL
en este caso JL salta si es menor, pero en diferente forma, veamos aquí mira si FLAG S es diferente a
FLAG O y en ese caso salta
Veamos en los ejemplos cuando se da esto si ambos EAX y ECX son positivos siendo EAX mayor que
ECX
Al apretar F7 no salta ya que EAX es mayor que ECX y el resultado es positivo lo que no activa el FLAG
O ni el FLAG S.

Si EAX es menor que ECX pero ambos son positivos repito el ejemplo

Apreto F7

Y como S y O son diferentes salta o sea que salta cuando es menor si ambos son positivos, veamos otro
caso.

En este caso EAX es menor que ECX, ya que es un número negativo veamos que pasa
Salta perfectamente porque es menor pero que pasa si usamos estos dos mismos valores con el otro salto
que parece realizar el mismo trabajo el JB
Al apretar F7

Vemos que el JB no salta quiere decir que JB compara ambos como si fueran positivos o SIN SIGNO
mientras que si el salto debe considerar el signo de lo que compara se utiliza JL esa es la principal
diferencia entre ambos.

Aquí vemos en esta los saltos condicionales según queramos considerar el signo de lo que comparamos o
no,
Vemos que JA, JB JBE y JAE consideran ambos operandos positivos mientras que JG, JL, JLE y JGE
consideran los operandos con signo, JE y JNE se comportan igual en ambos casos.
Creo que con esto hemos aclarado el tema de los saltos condicionales y las comparaciones, en la práctica
mas adelante veremos su utilización en los programas lo cual nos será mucho mas liviano que esta pesada
tarea de revisarlos a casi todos.
Queda en la ultima parte de ASM por suerte ver los calls y ret, y los modos de direccionamiento ya casi
llegamos al fin de lo duro paciencia jeje..
Hasta la parte 7
Ricardo Narvaja
16 de noviembre de 2005
INTRODUCCION AL CRACKING CON OLLYDBG Parte 7

Los CALL y RET
He dejado algunas instrucciones para esta ultima parte porque creo que a esta altura ya tienen claro
algunas cosas, y es mejor explicar estas ultimas instrucciones ya teniendo una pequeña base, ahora
explicaremos los CALL y RET.
Esta instrucción aunque parezca su funcionamiento sencillo, muchos de los newbies no comprenden
realmente su funcionamiento, por eso quería dedicarle un espacio importante e insistir en repasar toldo lo
anterior, pero ademas mirar de entender muy bien el funcionamiento de los CALL y RET yo creo que es
algo muy importante para el cracking.
Carguemos nuevamente nuestro crackme de ejemplo el CRACKME DE CRUEHEAD en OLLYDBG,
Para practicar hagamos click derecho en el listado desensamblado en cualquier línea y elijamos GO TO –
EXPRESSION

Y en la ventana que aparece tipeemos 401245

Nos llevara a dicha dirección en el listado desensamblado, donde hay un CALL para practicar.
Allí vemos el CALL que elegí para practicar, para poder ejecutarlo hago CLICK DERECHO-NEW
ORIGIN HERE con lo cual EIP apuntara a 401245 y dicha dirección será la próxima que se ejecutará.

Allí vemos como cambiamos EIP

Volvamos a nuestro CALL

La instrucción CALL lo que hace es ir a ejecutar una subrutina o si quieren parte del programa cuya
dirección esta dada por el valor del operando o sea en este caso del ejemplo:
CALL 401362 significa que la próxima línea a ejecutarse será 401362 y cuando se termine de ejecutar la
rutina que esta allí dentro, volverá a la instrucción siguiente a continuación del CALL que la llamo.
En este ejemplo luego de ejecutarse el contenido del CALL 401362, volverá a 40124A y seguirá desde
allí.
Ahora hagamos unos ciertos movimientos con el OLLYDBG, que nos ayudan en los casos que estamos
encima de un CALL como este.
Si yo quiero mirar el contenido del CALL podría entrar al mismo con F7 y tracearlo por dentro, pero si
quiero echar un vistazo a ver si el contenido me interesa para ser traceado o no, ya que también tengo
como recuerdan la opción de tracear con la tecla F8, la cual en este caso ejecutara el CALL sin entrar al
mismo y seguirá en 40124A sin ni siquiera enterarnos de lo que hizo el programa dentro del CALL.
Entonces cada vez que llegamos a un CALL y estamos traceando un programa se plantea una disyuntiva,
será importante para entrar a tracearlo con F7? O lo salteo con F8 porque es un call secundario que no
hace nada que me importe?
Bueno, lo que OLLYDBG nos permite hacer es mirar sin ejecutar, a ver que veo dentro del CALL y si me
interesa.
Para ello hago click derecho en el CALL y elijo FOLLOW.

FOLLOW no ejecuta ninguna línea solo va a mostrarnos la próxima línea a ejecutarse, pero no cambia
nada EIP seguirá en 401245, a la espera de nuestra decisión.

Cuando entro a mirar veo la rutina interna que obviamente empieza en 401362 que era el operando del
CALL y donde terminará, pues en el primer RET que vea en este caso OLLYDBG escribe los RET como
RETN, pero es lo mismo dicha instrucción es la finalización de la rutina y la vuelta a 40124A a la
instrucción siguiente del CALL que nos trajo aquí.
Es muy importante entender esto, ahora que vimos como podemos mirar dentro sin ejecutar volvamos a la
línea actual presionando la tecla - del teclado numérico o sea la tecla MENOS, esto siempre nos lleva al
paso anterior sin ejecutar nada también.
Pues estamos en el CALL

Ahora si entraremos con F7, pero antes de entrar el CALL veamos el stack, esto es muy importante pues
allí se almacenan los datos para que el programa sepa donde regresar cuando llega al RET.
En mi maquina este es el stack, en la suya los valores pueden variar pero el mecanismo será similar.
Apreto F7 ahora

Allí entre en el CALL y estoy en 401362 pero a diferencia de la vez anterior que entre con FOLLOW
ahora EIP cambio a 401362, lo cual quiere decir que estamos ejecutando esta rutina.
Veamos que paso en el stack

Allí en la imagen resalte el stack como estaba antes y veo que se agrego una nueva carta arriba o sea al
entrar en un CALL el sistema automáticamente hace un PUSH con la dirección de retorno, o sea donde
volverá al llegar al RET y salir de la rutina.
Vemos que la línea tiene el valor 40124A que es como sabemos la dirección de retorno.
Por si alguno lo olvido recordemos que es la dirección siguiente al CALL inicial, allí se ve.

Bueno vemos que OLLY nos aclara aun mas el tema agregándonos información.
Nos dice RETORNO A 40124A desde 401362
O sea OLLY aun no sabe donde estará el RET que nos devolverá, pero sabe que la rutina empieza en
401362 y lo marca como que aquí empieza y terminara en un RET y volverá a 40124A.
Apretemos F7 una vez vemos que ejecuta un PUSH 0 lo cual pone un CERO en el stack y abajo del
mismo queda el indicador para el RET de la dirección de retorno.

El programa puede hacer mil operaciones dentro de la rutina hacer miles de PUSH, POPS lo que quiera,
pero al llegar al RET deberá dejar arriba en el stack nuevamente el valor de la dirección de retorno,
sigamos ejecutando con F8 para no entrar en los CALL y llegar al RET.

Allí llegue al RET y veo que como dije el stack tiene arriba nuevamente el valor donde retornara.

Como habíamos mencionado el RET es el final de la rutina y contrapartida de la instrucción CALL, si
CALL nos trajo aquí, RET nos devolverá a la zona donde estábamos antes de entrar en esta rutina.
Pero además RET quitara la dirección de retorno del stack que es un valor que al sistema ya no le interesa
pues ya volvemos y luego la dirección ya no es útil más.
Apreto F7

Y vuelvo a 40124A y el stack quedo como estaba antes de ejecutar el CALL en mi maquina en 12FFc4.

Es de mencionar que si uno ejecuta un RET sin haber entrado en ningún call por ejemplo
PUSH 401256
RET
Lo que hará esto es poner en el primer lugar del stack el valor 401256, y como la siguiente instrucción es
un RET, pues ella interpreta que el primer lugar del stack es una dirección de retorno de algún call
anterior y aunque ello no haya ocurrido, al ejecutarlo nos llevara allí.
Ahora reinicio el CRACKME DE CRUEHEAD
Ahora haré otro ejemplo voy en el listado con GO TO – EXPRESSION a 401364 es una dirección que
elegí para mostrar algo ya verán.

Ahora no cambiare EIP ni nada si no que apretare F2 que es un BREAKPOINT los cuales ya
explicaremos mas adelante en detalle, lo importante es que cuando el programa ejecute esa instrucción
OLLYDBG parara allí.

Allí esta puesto el BREAKPOINT ahora apreto F9 que es RUN para que el programa corra.
Vemos que nos sale la ventana del crackme, si no la ven, pues búsquenla con ALT mas TAB entre los
programas que están corriendo.
Allí se ve, el programa no paso aun por nuestro BREAKPOINT, vayamos en dicha ventanita a HELP REGISTER

Nos sale la ventana para poner un NOMBRE Y UN SERIAL

Pongamos cualquiera
Y apreto OK

Nos sale una ventanita diciendo que no tuvimos suerte o sea que tipeamos el user y serial incorrecto (lo
increíble seria que fuera el correcto jeje), y al aceptar dicha ventana para en nuestro BREAKPOINT.
Si no les para prueben con el user y serial que puse yo.

Allí estamos en el medio de la ejecución del programa pero algo de información tenemos

Vemos allí unos cuantos RETURN TO …. Que el stack tiene almacenados allí, así que podemos pensar
que el superior de todos, será donde volverá el programa al llegar a un RET ya que suponemos estamos
dentro de un CALL (porque vemos que hay RETURN TO …… en el stack ) y al llegar a un RET ese
RETURN quedara en la línea superior y volverá a 40124A .
Como vemos también estamos en la misma rutina que analizamos antes cambiando el EIP, pero ahora
dentro de la ejecución el programa, no suelta.
Tratamos de llegar al RET apretando F8 como antes, en el call anterior al RET se para ya que nos debe
mostrar algo que hace el CALL dentro que es una mensaje y que debemos aceptar para seguir.
Presionamos ACEPTAR

Y llegamos al RET y como supusimos el valor superior del stack es

La diferencia entre la vez anterior y esta es que la vez anterior al cambiar EIP e ir directamente allí,
ejecutamos el CALL solo aislado, no el resto del programa, ahora al poner un BREAKPOINT el
programa se ejecuto normalmente, y al pasar por allí paro, y si apreto F9 seguirá corriendo como si nada.

Además lo que quise mostrar es que a veces cuando estamos en el medio de la ejecución de un programa
y paramos por algún motivo, la información del stack nos sirve para saber de donde fue llamado la rutina
en que estamos y donde volverá, y si hay mas RETURN TO hacia abajo, también sabremos que son
CALLS unos dentro de otros, o sea anidados, y que estamos dentro de un CALL que al llegar al primer
RETURN TO, saldremos y al llegar al segundo pues saldremos de otro y así.
Creo que esta claro, igual como es muy importante que entiendan esto aclararemos con otro ejemplo
reiniciemos el OLLY y apretamos la barra espaciadora y escribamos como primera línea solo para
entender esto CALL 401245
Alli esta ahora podemos practicar hacer FOLLOW para la rutina por dentro

Vemos que como modificamos el programa la rutina ahora empieza en 401245 y terminara en el RET de
401288 (que es un RETN10 un poco diferente a un RET común, pero no es eso el tema de esta
explicación ya lo veremos mas adelante lo que quiero que vean es lo que pasa cuando entramos en un call
como en este caso y dentro de la rutina entramos en un segundo CALL.
Bueno ya hicimos FOLLOW y miramos ahora apretemos MENOS para volver y ahora si apretemos F7
para entrar ejecutando.

Allí estamos y EIP apunta a 401245 que es la próxima instrucción a ejecutarse
Y en el stack vemos que en el primer lugar esta el valor de retorno a la línea siguiente del call que
escribimos a mano.

Vemos que el valor esta, pero OLLYDBG no nos aclaro RETURN TO 401005, porque ocurre esto, es
bueno entenderlo para saber como funciona OLLYDBG, como nosotros agregamos el CALL después del
análisis inicial que el OLLYDBG había hecho, pues de esta forma, le hemos cambiado el caballo en el
medio del río y lo hicimos ahogar jeje, por lo cual si queremos arreglarlo, debemos hacer en el listado en
cualquier línea CLICK DERECHO- ANALICE CODE, con lo cual lo volverá a pensar después de los
cambios que hemos introducido.

Vemos que después de reanalizar el código

Bueno nos dijo que volverá a MODULE ENTRY POINT + 5
Dicho valor es 401000 que era el ENTRY POINT mas 5 =401005
Es muy importante esto porque muchas veces uno le dice a una persona que le pide consejo, fíjate los
RETURN TO …… en el stack, pero resulta que uno mismo ha modificado cosas o el mismo programa se
ha auto modificado al ejecutarse entonces el análisis inicial del OLLYDBG fallara en las aclaraciones y
debemos actualizarlo al detenernos, o quitar el análisis como vimos si nos trae problemas en la parte 1.
Bueno aclarado esto volvemos a donde estábamos

Apreto F7 para entrar en el segundo CALL

Vemos que arriba de donde guardo la dirección de retorno del primer call ahora guarda la segunda
dirección de retorno de este, en este caso están consecutivos, pero podría haber valores numéricos
intermedios productos de PUSH o operaciones diversas, lo importante es que el primer RETURN TO ..
que hallamos de arriba hacia abajo es la dirección de retorno del ultimo CALL que entramos y la segunda
que hallemos bajando será la dirección de retorno del call anterior que es el inicial que escribimos.
Esta es la idea de calls anidados o uno dentro de otro, si yo por poner un BREAKPOINT o por algún
motivo parara aquí en el medio de la ejecución del programa, aunque no haya venido traceando ni tuviera
información de cómo se vino ejecutando el programa al ver el stack , puedo sacar como conclusión
1) CAI AQUÍ Y VEO UN RET un poco mas abajo, supongo que estaré dentro de un CALL para
confirmarlo miro el stack

2) MIRO EL STACK
Al mirarlo y buscar desde arriba del stack hacia abajo y hallar el primer RETURN TO se que el programa
al llegar al RET volverá a 40124A.

Y además de saber donde volverá se que estoy dentro de la ejecución del CALL ANTERIOR al punto de
retorno, o sea que el programa llamo a la zona donde estoy desde 401245 usando un CALL que llama a la
rutina de 401362.
Y no solo se eso si no que se también que antes de llegar a ese CALL, había entrado antes en otro ya que
hay otro RETURN TO …. Mas abajo

Ese me informa que luego de ejecutar todo saldrá a 401005 y además se que el programa provenía del
CALL de la línea anterior o sea

Solo parando y mirando el stack ya determine que el programa provino de aquí que entro en ese call,
luego fue a 401245, allí había otro call que me llevo a 401362 y de esa forma llegue a la zona donde
estoy.
Esa forma de pensar en el cracking es muy útil porque me hace reconstruir la forma que el programa fue
llegando a cierto punto, que muchas veces no son dos calls uno dentro de otro si no que hay 30 calls uno
dentro de otro y uno no puede tracearlos todos, así que si caigo en un punto, puedo hacer un análisis
personal, y llegar a la conclusión de cómo el programa arribo al punto donde me encuentro en este
momento.
Espero que haya quedado claro, lo de los CALL Y RETS les sugiero practicarlos repasarlo, si tienen
dudas preguntar porque esto es muy importante, iba a terminar a continuación con los métodos de
direccionamientos y algunas instrucciones que quedaron en el tintero, pero preferiría que le den buena
importancia a entender esto y en la próxima parte continuamos con los temas pendientes.
Hasta la parte 8
Ricardo Narvaja
18 de noviembre de 2005

.
INTRODUCCIÓN AL CRACKING EN OLLYDBG PARTE 8
Trataremos en esta parte de ver rápidamente algunas instrucciones importantes para el cracking que nos
quedaron en el tintero para terminar con las mismas y empezar a crackear.
INTRUCCIONES PARA LOOPS O CICLOS
Ciertamente se pueden realizar ciclos en un programa con las instrucciones ya vistas o sea ejecutando
varias instrucciones, poniendo un contador por ejemplo en ECX y al final una comparación de si es cero y
un salto condicional que si no es cero vuelva a repetirse el ciclo se disminuya ECX y así se repetirá hasta
que ECX sea cero seria algo así:
Xor ECX,ECX
Add ECX,15
Eso seria para inicializar el contador de nuestro loop que sera puesto a 15, aquí comienza el LOOP en si

DEC ECX
Para disminuir ECX cada vez que se ejecute el loop
Luego la ejecución de las instrucciones que se deben repetir
Y luego
TEST ECX,ECX
JNE salta hacia el inicio del LOOP
O sea que al testear si ECX es cero la primera vez será 14 ya que lo decremente una vez y al no ser cero
volverá a repetirse, y así se repetirá hasta que ECX sea cero donde saldrá fuera del LOOP y continuará
con la instrucción siguiente.
Escribámoslo en OLLYDBG

Allí lo vemos la zona resaltada en amarillo es el loop en si, que se repetirá hasta que ECX sea cero, y
entre 401008 y 40100C se deberían escribir las instrucciones que el programa desea repetir que aquí no
interesan pues solo vemos el mecanismo de iteración del LOOP por eso dejamos NOPS alli.
Si lo traceamos vemos que al apretar F7, ECX se pone a cero
Apreto F7 nuevamente y le sumo 15 para establecer la cantidad de iteraciones en ECX.

Luego apreto f7 hasta llegar al DEC ECX el cual al ejecutarlo pone ECX en 14
Luego llegamos hasta la comparación TEST ECX,ECX que sabemos que verifica si ECX es cero

Al no ser cero no se activa el FLAG Z y el JNZ salta hacia 401007, donde vuelve a decrementar ECX
quedando en 13, puedo tracear así haciendo los loops hasta llegar al momento que ECX vale CERO
Vemos que al ejecutar la comparación con ECX igual a cero se activa el FLAG Z lo que hace que el JNZ
no salte

Recordemos que JNZ es el inverso de JZ que saltaba cuando se activaba el FLAG Z, el JNZ es el opuesto
no salta cuando se activa el FLAG Z.
Allí lo vemos la flecha en gris indica que no va a saltar, al apretar F7 nuevamente sale del loop a la
instrucción siguiente

Esa seria una forma sencilla de loop con las instrucciones ya vistas, aunque hay instrucciones especiales
para eso.
LOOP
La instrucción LOOP nos ayuda a hacer algunas de las tareas que vimos en el ejemplo anterior,
reemplazamos

En donde estaba DEC ECX hacemos CLICK DERECHO – BINARY NOP con los cual NOPEARA esa
instrucción, lo mismo donde estaban TEST ECX,ECX y JNZ 401007, todas esas instrucciones pueden ser
reemplazadas por una sola que es la INSTRUCCIÓN LOOP la cual compara si ECX es cero, si no lo es
salta al operando en este caso 401007 y además decrementa ECX .
Hagamos en la primera línea, CLICK DERECHO-NEW ORIGIN HERE para ejecutar mi nuevo LOOP.
Vemos que al apretar f7 pone ECX a cero luego le suma 15 igual que antes para marcar la cantidad de
iteraciones o repeticiones.
Ahora traceo y llego hasta la instrucción LOOP
Vemos que igual que antes al no ser ECX igual a cero, salta a 401007, pero no solo compara si es cero y
salta, también vemos que decrementa ECX ya que volvió siendo 14.
Si traceamos hasta que llega a LOOP pero valiendo ECX igual a cero veremos como se repite el ciclo.

En el momento que ECX vale cero ya no se repite mas el LOOP y al apretar F7 continua con la ejecución
de la instrucción subsiguiente.

Luego tenemos variaciones de la instrucción LOOP estas son

LOOPZ salta o mantiene dentro del bucle mientras que el flag Z sea cero cada vez que se ejecute la
instrucción LOOP, y la opuesta LOOPNZ mientras que el FLAG Z sea 1, en este tipo de ciclo hay ademas
contador que se decrementa y se sale por alguna comparación anterior que ponga el FLAG Z a cero en el
primer caso o a 1 en el segundo o porque ECX llegue a cero por cualquiera de ambos casos.
INSTRUCCIONES PARA EL MANEJO DE CADENAS de BYTES
Aquí vemos las mas importantes las aclaramos debajo
MOVS
Esta instrucción, lo que hace es mover el contenido de ESI al contenido de EDI, realmente no necesita
ningún parámetro, pero al escribir en OLLY la instrucción MOVS y apretar ASSEMBLE, la completa
(innecesariamente) al ensamblar y queda como
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10
Introduccion al cracking con ollydbg partes 1 a 10

Más contenido relacionado

Similar a Introduccion al cracking con ollydbg partes 1 a 10

Ollydbg introducción
Ollydbg introducciónOllydbg introducción
Ollydbg introducciónTensor
 
Como instalar Prolog en Windows
Como instalar Prolog en WindowsComo instalar Prolog en Windows
Como instalar Prolog en WindowsCesarMartinez474
 
Guía básica de depuración de código xcode 6 apple coding
Guía básica de depuración de código xcode 6   apple codingGuía básica de depuración de código xcode 6   apple coding
Guía básica de depuración de código xcode 6 apple codingRoggerza
 
Practica google drive
Practica   google drivePractica   google drive
Practica google drivecobymotion
 
Complementando El control parental II de III
Complementando El control parental II de IIIComplementando El control parental II de III
Complementando El control parental II de IIIRober Garamo
 
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copia
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copiaIntroduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copia
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copiaesekazz
 
Toggle - merinadesign
Toggle - merinadesignToggle - merinadesign
Toggle - merinadesignMerinadesign
 
Corcuera pablo gestorincidenciasocs
Corcuera pablo gestorincidenciasocsCorcuera pablo gestorincidenciasocs
Corcuera pablo gestorincidenciasocspablo2017
 
que es slideshare
que es slideshareque es slideshare
que es slideshareernesto503
 
Instalación Eclipse. Básico
Instalación Eclipse. BásicoInstalación Eclipse. Básico
Instalación Eclipse. Básicormirandaibanez
 
INFOSAN Curso de delphi básico
INFOSAN Curso de delphi básicoINFOSAN Curso de delphi básico
INFOSAN Curso de delphi básicoFRANCIACOCO
 
Code bloks tutorial_terminado
Code bloks tutorial_terminadoCode bloks tutorial_terminado
Code bloks tutorial_terminadoLEFR202
 

Similar a Introduccion al cracking con ollydbg partes 1 a 10 (20)

Ollydbg introducción
Ollydbg introducciónOllydbg introducción
Ollydbg introducción
 
2 curso
2 curso2 curso
2 curso
 
Como instalar Prolog en Windows
Como instalar Prolog en WindowsComo instalar Prolog en Windows
Como instalar Prolog en Windows
 
Netbeans
Netbeans Netbeans
Netbeans
 
Guía básica de depuración de código xcode 6 apple coding
Guía básica de depuración de código xcode 6   apple codingGuía básica de depuración de código xcode 6   apple coding
Guía básica de depuración de código xcode 6 apple coding
 
Practica google drive
Practica   google drivePractica   google drive
Practica google drive
 
6 curso
6 curso6 curso
6 curso
 
Tutorial
TutorialTutorial
Tutorial
 
EL ZINJAI
EL ZINJAIEL ZINJAI
EL ZINJAI
 
Complementando El control parental II de III
Complementando El control parental II de IIIComplementando El control parental II de III
Complementando El control parental II de III
 
Curso de batch_desde_0_por_juanla
Curso de batch_desde_0_por_juanlaCurso de batch_desde_0_por_juanla
Curso de batch_desde_0_por_juanla
 
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copia
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copiaIntroduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copia
Introduccic3b3n bc3a1sica-a-netbeans-para-desarrollo-java - copia
 
Toggle - merinadesign
Toggle - merinadesignToggle - merinadesign
Toggle - merinadesign
 
Corcuera pablo gestorincidenciasocs
Corcuera pablo gestorincidenciasocsCorcuera pablo gestorincidenciasocs
Corcuera pablo gestorincidenciasocs
 
que es slideshare
que es slideshareque es slideshare
que es slideshare
 
Instalación Eclipse. Básico
Instalación Eclipse. BásicoInstalación Eclipse. Básico
Instalación Eclipse. Básico
 
INFOSAN Curso de delphi básico
INFOSAN Curso de delphi básicoINFOSAN Curso de delphi básico
INFOSAN Curso de delphi básico
 
Interfaz de flash
Interfaz de flashInterfaz de flash
Interfaz de flash
 
Code bloks tutorial_terminado
Code bloks tutorial_terminadoCode bloks tutorial_terminado
Code bloks tutorial_terminado
 
Code bloks tutorial_terminado
Code bloks tutorial_terminadoCode bloks tutorial_terminado
Code bloks tutorial_terminado
 

Último

Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaarkananubis
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
ejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofJuancarlosHuertasNio1
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxJOSEMANUELHERNANDEZH11
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersIván López Martín
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxNombre Apellidos
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...FacuMeza2
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadMiguelAngelVillanuev48
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfsoporteupcology
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesFundación YOD YOD
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativaAdrianaMartnez618894
 
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...JaquelineJuarez15
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfSergioMendoza354770
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA241531640
 

Último (20)

Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en mina
 
La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
ejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sof
 
Hernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptxHernandez_Hernandez_Practica web de la sesion 12.pptx
Hernandez_Hernandez_Practica web de la sesion 12.pptx
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidad
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdf
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento Protégeles
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativa
 
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
 

Introduccion al cracking con ollydbg partes 1 a 10

  • 1. INTRODUCCION AL CRACKING CON OLLYDBG DESDE CERO La idea de esta INTRODUCCION AL CRACKING CON OLLYDBG DESDE CERO es la de dar una base para todos los que recién se inician en el arte del cracking con OLLYDBG, tratando de ser una introducción pero a su vez que proporcione una base fuerte para poder ingresar a la lectura y comprensión de tutoriales mas avanzados como los que se encuentran en el actual NUEVO CURSO de CRACKSLATINOS, el cual por supuesto sigue abierto para seguir agregando novedades, concursos y teorías como hasta ahora. La idea se genero a partir de que los newbies actuales que leen el llamado NUEVO CURSO de CRACKSLATINOS, se encuentran con que este se inicia en un nivel muy alto, y no pueden insertarse gradualmente en el mismo, por lo cual se sienten frustrados y muchas veces abandonan antes de empezar, la idea de esta INTRODUCCION es no repetir los grandes tutes que existen en ese curso que son ya mas de 500 y de un nivel espectacular, si no mas bien sentar la base para que el que termine esta introducción, le sea mas fácil leer cualquier tutorial, obviamente requerirá esfuerzo como todo en el cracking, pero la tarea nuestra es tratar de alivianar ese esfuerzo, sentando aquí las bases del cracking en OLLYDBG para que sea compresible y se pueda entender fácilmente. PORQUE OLLYDBG? Aquí no entraremos a hacer grandes elucubraciones o reeditar viejas polémicas de SOFTICE vs OLLYDBG de cual es mejor ni nada de eso, creo que hasta los fanáticos de SOFTICE reconocen que es mas sencillo empezar con OLLYDBG, ya que muestra mayor información y es mas cómodo para aprender, la idea es ingresar al mundo del cracking, por la puerta del OLLYDBG, mas adelante cuando uno ya conoce, puede trasladar fácilmente a cualquier debugger lo aprendido pues cambian las formas de usar de los programas, pero no la esencia. LO PRIMERO ES LO PRIMERO Exactamente lo primero es munirse de la herramienta que vamos a utilizar mayormente, para ello pueden hacer clic AQUI para bajarlo. Como aquí estamos empezando desde cero pues, recién nos estamos haciendo del archivo, y ahora ya que es un archivo zipeado, lo unzipearemos con WINZIP preferentemente a una carpeta en nuestro disco rígido que podamos localizar fácilmente, una buena idea seria poner dicha carpeta en C:/ aunque funciona en cualquier lugar, yo la pondré en C:/.
  • 2. Una vez descomprimido podemos entrar a la carpeta y ver Allí esta el archivo ejecutable OLLYDBG.exe el cual ejecutaremos para arrancar el OLLYDBG y al cual para comodidad le haré un acceso directo en mi escritorio. Bueno ya tenemos bajado y preparado para arrancar a nuestro OLLYDBG.exe, lo ejecutamos.
  • 3. Nos aparece este cartel avisándonos que la DLL que esta en la carpeta de OLLYDBG es mas antigua que la de sistema, si apretamos SI, borrara la antigua de la carpeta del OLLY y usara la de sistema, yo a pesar de no ver grandes diferencias siempre prefiero elegir que use la propia antes que la de sistema, ya que fue concebido con esa dll, por lo tanto elijo NO. Allí esta el OLLYDBG vacío, y como siempre el primer programa que abriremos mas que nada para mirar las diferentes partes del OLLYDBG y a vuelo de pájaro poder ubicarnos en sus diferente partes, es el famoso CRACKME DE CRUEHEAD que vendrá adjunto en este tutorial. Para abrir el archivo a debuggear en el OLLYDBG, vamos a FILE OPEN o hacemos clic en el icono Se abrirá la ventana para que busquemos el archivo a debuggear en este caso es el crackme de CRUEHEAD.
  • 4. Allí se abre el susodicho crackme y por ahora no importa que no entendamos lo que nos muestra ya mas adelante aprenderemos eso, la idea es ir mostrando las partes del OLLYDBG y ciertas configuraciones del mismo para que cuando en sucesivos tutes, diga, por ejemplo vayan al DUMP, sepan al menos donde esta, así que esto es mas que nada para ubicación, no es un tute profundo sobre OLLY. Allí vemos la cuatro partes de la ventana principal del OLLYDBG
  • 5. 1)DESENSAMBLADO : También llamado listado, aquí el OLLY nos muestra el listado desensamblado del programa que vamos a debuggear, por DEFAULT el OLLY viene configurado para analizar el programa que vamos a debuggear al iniciar, esto se configura en OPTIONS-DEBUGGING OPTIONS. O sea al estar marcada esa tilde en AUTO START ANALISIS OF MAIN MODULE el OLLYDBG analizara el programa y mostrara información adicional sobre el mismo. Allí esta el listado inicial del crackme de CRUEHEAD analizado, y si arranca sin analizar debajo podemos ver la diferencia.
  • 6. La ventana analizada muestra mas información, que aunque aun no sepamos bien que es, se ve mas completa, igual es bueno saber que de la ventana analizada se puede quitar el análisis, si uno no esta de acuerdo con el mismo o uno se da cuenta que el mismo esta equivocado lo cual puede ocurrir. Muchas veces el OLLYDBG muestra partes que no son listado correcto porque interpreto mal el código ejecutable como datos, en ese caso se ven unos DB como estos En ese caso puedo quitar manualmente el análisis que el OLLYDBG ha realizado haciendo CLICK DERECHO en el listado y eligiendo ANALISIS-REMOVE ANALYSIS FROM MODULE y en ese caso el listado se vera sin análisis pero correcto
  • 7. Otra cosita que hace a la claridad para trabajar y que por lo menos a mi me gusta, aunque cada uno puede variar en estos temas es colorizar los JUMPS Y CALLS eso se hace haciendo clic derecho APPEARENCE – HIGHLIGHTING – JUMPS AND CALLS El resultado es el siguiente Allí vemos que en celeste quedan resaltados los CALLS y en amarillo los JUMPS, lo cual es mas claro para la vista. Bueno con eso nuestro listado queda mas fácil de interpretar, aunque aun no tengamos la mas remota idea de que significa, pero bueno hay que preparar antes las herramientas para poder ir de a poco aprendiendo 2)REGISTROS
  • 8. La segunda ventana importante del OLLYDBG es la de los REGISTROS Recordamos que la ventana de registros se encuentra en la parte superior derecha del OLLYDBG, allí muestra bastante mas información que los registros en si. Tiene muchísima más información que aun no veremos, pero se puede cambiar el modo de visualización en tres formas. (VIEW FPU REGISTERS, VIEW 3D NOW REGISTERS y VIEW DEBUG REGISTERS) por default viene elegida la primera. Por ahora no ahondaremos mucho en eso ya que nos preocuparemos más que nada en el tema REGISTROS y FLAGS, lo menciono para que sepan que hay varias vistas en el registro. 3)STACK O PILA:
  • 9. Bueno allí vemos el llamado STACK O PILA aquí no hay mucha configuración posible solo la opción de mostrar la información relativa al registro ESP o al registro EBP. Por default y lo que mas se utiliza es la vista relativa a ESP, pero para cambiar a la vista según EBP, haciendo clic derecho en el stack eligiendo GO TO EBP cambiamos y para volver GO TO ESP volvemos a la opción por default. En sucesivas entregas explicaremos bien el funcionamiento del stack por ahora miramos como se puede variar su configuración solamente. 4) DUMP: La ventana del DUMP tiene muchas opciones de visualización, por DEFAULT nos muestra la visualización HEXADECIMAL de 8 columnas o bytes, la cual puede ser modificada haciendo CLICK DERECHO en el DUMP y eligiendo la opción deseada. La opción por DEFAULT es la que generalmente mas se usa, aunque tenemos opciones para cambiar para mostrar desensamblado (DISASSEMBLE), Texto (TEXT) y diversos formatos (SHORT, LONG, FLOAT)
  • 10. Y además la opción SPECIAL – PE HEADER que mas adelante en próximos capítulos veremos para que sirve esto que es muy útil. Ya conocemos las partes que se ven en la ventana principal del OLLYDBG, aunque también hay más ventanas que no se ven directamente, se puede acceder a ellas, tanto por el menú, como por los botones de las vistas. Veremos que es cada uno El botón L o VIEW-LOG nos muestra lo que el OLLYDBG escribe en la ventana del LOG lo cual puede ser configurado para mostrar diferentes tipos de información, por default en la ventana del LOG va guardando allí información sobre el arranque, y de la información escrita en el mismo por los diferentes BREAKPOINTS CONDICIONAL LOGS, lo cual se vera mas adelante, por ahora vemos allí ,la información del proceso que arranco, en este caso el crackme de cruehead, las dll que cargo, y ciertos tips sobre el análisis. Una de las opciones mas importantes de esta ventana es la de loguear a una fila, para ciertos casos que deseemos guardar la información en una fila de texto, en ese caso CLICK DERECHO-LOG TO FILE.
  • 11. El botón E o VIEW-EXECUTABLES nos muestra la listado de los ejecutables que utiliza el programa, exe, dlls, ocxs, etc Aquí también el botón derecho tiene muchas opciones que por ahora no veremos ya que estamos mirando en forma general al OLLYDBG. El botón M o VIEW – MEMORY, nos muestra la memoria ocupada por nuestro programa, allí se ven las secciones del ejecutable, dlls que utiliza el proceso, así como el stack y diversas secciones allocadas por el sistema, y muchas veces al correr los programas, los mismos realizan nuevas allocaciones de memoria. En tiempo de ejecución. Haciendo clic derecho podemos hacer SEARCH en la memoria para buscar en ella, strings, cadenas hexa, unicode etc, además nos da la posibilidad de colocar diferentes tipos de breakpoints en la secciones, como asi también la posibilidad de cambiar el acceso a las mismas con SET ACCESS ya profundizaremos en esto. El botón T o VIEW-THREADS nos da el listado de los THREADS del programa Aunque no sabemos aun que es esto y la explicación llegara en los próximos capítulos es bueno ir familiarizándose en donde esta cada cosa, luego aprenderemos que es y como se usan mas adelante. El botón W o VIEW-WINDOWS nos muestra las ventanas del programa, como aun no corrió, no hay ventanas así que esta vacía.
  • 12. El botón H o VIEW-HANDLES, nos muestra los handles por ahora localícenlo, ya explicaremos que es y para que sirve El botón C o VIEW-CPU nos retorna a la ventana principal del programa. El botón / o VIEW-PATCHES nos muestra los parches si el programa ha sido modificado, por ahora esta vacío al estar sin cambios El botón K o VIEW-CALL STACK nos muestra el call stack, que es el listado de los calls que entramos, hasta el punto donde el programa esta detenido. El botón B o VIEW-BREAKPOINTS es el listado de los breakpoints comunes colocados en el programa, no muestra los hardware breakpoint ni los memory breakpoints aquí, solo los BP comunes.
  • 13. El botón R o VIEW- REFERENCES nos muestra la ventana de referencias la cual nos da los resultados de cuando hacemos una búsqueda de referencias en el OLLY El botón … o VIEW-RUN TRACE, nos muestra el listado si hemos hecho algún RUN TRACE en nuestra maquina, y tiene también la posibilidad de elegir LOG TO FILE, para guardar el resultado del traceo en un archivo txt Bueno hasta aquí un paneo a vuelo de pájaro por los botones mas importantes, no detallamos explicación porque aun hay que aprender antes algo de ASM, y practicando el uso del OLLYDBG podremos ir aclarando mas profundamente para que sirve cada botón y cada OPCION, la idea es irse familiarizándose con donde están las cosas que veremos en las próximas entregas. COMO CONFIGURAR EL OLLYDBG COMO JIT ( JUST IN TIME DEBUGGER) Aclaro que no conviene tener configurado el OLLYDBG constantemente COMO JIT, solo conviene hacerlo en ocasiones especiales, ya que al estar como JIT capturara el error de cualquier programa de nuestra maquina y arrancara solo, lo cual puede resultar molesto si no estamos debuggeando o crackeando, por lo tanto les enseño como se configura para casos especiales, pero conviene dejarlo con la opción que trae por default que no esta como JIT. Para colocar el OLLYDBG como JIT vamos a OPTIONS-JUST IN TIME DEBUGGING
  • 14. Y aprieto el botón MAKE OLLYDBG JUST IN TIME DEBUGGER y DONE Para quitarlo, en el mismo lugar aprieto RESTORE JUST IN TIME DEBUGGER y DONE Agregando PLUGINS al OLLYDBG El OLLYDBG trae la opción para agregar plugins que nos son necesarios para realizar cierta tarea, por ahora solo agregaremos el plugin COMMAND BAR para aprender como se agregan los mismos. Bajamos el plugin COMMAND BAR el cual puede ser bajado de AQUÍ y la mayoría de los plugins se hallan AQUI Allí esta bajado en mi escritorio el plugin lo descomprimo con WINZIP entro a la carpeta que descomprimí a ver el contenido
  • 15. Ahora antes que nada crearemos una carpeta para los PLUGINS en nuestra maquina, yo la creare en C:/ y la llamare PLUGINS nada mas. Voy a C y creo una NUEVA CARPETA Allí esta, puede estar ubicada en cualquier lugar, pero a mi me gusta tener todo en C por eso la coloque allí, de cualquier forma debemos configurar el OLLYDBG para que reconozca esta carpeta como la que tendrá los plugins. Para ello en el OLLYDBG vamos a OPTIONS-APPEARANCE Y en la ventana que se abre vamos a la pestaña DIRECTORIES
  • 16. Vemos que en donde apunta al path de los plugins (PLUGIN PATH), en realidad nos esta apuntando a la carpeta donde esta el OLLYDBG.exe y podría dejarlo allí, pero a mi me gusta tener los plugins separados por lo tanto en donde dice PLUGIN PATH- BROWSE busco la carpeta que cree para mis plugins. Allí elegí la carpeta PLUGINS que cree y sale este aviso O sea que debo reiniciar el OLLY para que me reconozca la nueva carpeta de plugins, pero antes copio el contenido que baje del comand bar a mi carpeta de plugins.
  • 17. Allí copie todo el contenido y lo pego en mi carpeta PLUGINS Allí esta el contenido del plugin Command Bar en la carpeta PLUGINS, cada plugin que baje y agregue solo deberé copiar su contenido allí, muchas veces con copiar solo la dll es suficiente. Ahorra cierro el OLLYDBG si lo tenia aun abierto y lo reinicio. Vemos que en el menú PLUGINS me apareció el COMMAND BAR y las opciones del mismo. A su vez en la parte inferior del OLLYDBG vemos la COMMAND BAR instalada
  • 18. Es una barra para tipear comandos que nos facilitara mucho las cosas, mas adelante veremos su uso, por ahora lo importante es saber agregar plugins. Para quitar cualquier PLUGIN con solo quitar la dll correspondiente de nuestra carpeta PLUGINS y reiniciar el OLLYDBG, desaparecerá, les aconsejo que dejen siempre activa la COMMAND BAR. Arranco nuevamente el crackme de CRUEHEAD EN OLLYDBG Las teclas mas usadas en el OLLYDBG son: F7: Ejecuta una sola línea de código (si estas en un CALL entra al mismo a ejecutarlo por dentro) F8: Ejecuta una sola línea de código (si estas en un CALL no entra al mismo lo ejecuta completo sin entrar y sigue en la siguiente línea luego del CALL) Esos dos formas de tracear manualmente son verdaderamente diferentes y según cada caso usaremos F7 o F8 lo cual veremos más adelante. F2: Coloca un Breakpoint COMUN en la línea que marcas con el Mouse o esta grisada en el listado, para quitar el BP apretas nuevamente F2. Por ejemplo: Quiero poner un BP en 40101A pues marco con el Mouse esa linea Al hacer clic una sola vez se marca y queda grisada como vemos en la imagen, luego apreto F2.
  • 19. Vemos que se pinta de rojo la zona de la dirección, eso significa que hay activo un BP o Breakpoint allí, si apreto F2 nuevamente se quita. F9: Para Correr el programa es similar a RUN, con esto el programa correrá, hasta que encuentre algún BREAKPOINT, o alguna EXCEPCION que lo detenga o FINALICE por algún motivo, al apretar RUN veremos en la esquina inferior del OLLYDBG la palabra RUNNING o sea que esta CORRIENDO. Allí arranco el CRACKME DE CRUEHEAD, lo podemos ver correr Si PAUSO la ejecución en OLLYDBG apretando F12 o DEBUG –PAUSE Vemos que el OLLYDBG cambia a mostrar PAUSED o sea que esta PAUSADO, podemos volver a hacerlo correr con F9 o DEBUG-RUN. Para cerrar el programa que esta siendo DEBUGGEADO apreto DEBUG-CLOSE Bueno esto a sido una mirada a vuelo de pájaro del OLLYDBG la cual profundizaremos mas adelante pues tiene muchísimas opciones y configuraciones las cuales seguiremos estudiando en las próximas entregas, es muy útil que bajen el programa lo configuren y miren donde están las cosas que muestra este tute, así como le agreguen el plugin para practicar, y hagan correr y pausar el CRACKME DE CRUEHEAD, prueben ponerle un Breakpoint y practiquen esas cosas para que en la segunda entrega estén mas familiarizados con el mismo y podamos avanzar lento pero seguro, y sin dudas. Un abrazo a todos los CRACKSLATINOS Hasta la parte 2 Ricardo Narvaja 07 de noviembre de 2005
  • 20. INTRODUCCION AL CRACKING CON OLLYDBG PARTE 2 Luego de haber visto a grandes trazos, la ubicación y las principales partes del OLLYDBG, debemos aprender el sistema de numeración utilizado y cual es el concepto de stack aunque sea para tener una idea, luego profundizaremos. SISTEMAS NUMERICOS Los tres sistemas numéricos que más se utilizan son el binario el decimal y el hexadecimal. El concepto básico que deben tener de ellos es el siguiente: BINARIO: Se representa los números con dos caracteres el 0 y 1 por eso se llama BINARIO. DECIMAL: Se representa todos los números con 10 caracteres (del 0 al 9) por eso se llama decimal. HEXADECIMAL: Se representa todos los números con caracteres del 0 al F ( del 0 al 9, mas A, B, C, D, E y F, o sea serian 16 caracteres en total). Normalmente a partir de aquí cuando diga un número y no diga a que sistema de numeración pertenece es porque es HEXADECIMAL que es el que utiliza OLLYDBG, si son decimales o binarios aclarare expresamente. Existen formulas matemáticas que no utilizaremos aquí, para convertir números de un sistema al otro, que no son muy simpáticas, pero llegado el momento, un cracker realmente usa la CALCULADORA DE WINDOWS, que es lo mas rápido y directo y no va a ponerse a hacer cuentas de potencias, sumas etc para convertir un numero de un sistema a otro. Abramos la CALCULADORA DE WINDOWS y preparémosla Allí vemos en el menú VER como se puede cambiar a CIENTIFICA.
  • 21. Allí vemos que por DEFAULT arranca en DECIMAL, y al lado tiene la opción de cambiar a HEXADECIMAL (HEX), OCTAL (OCT) y BINARIO (BIN). El Octal que representa la numeración con 8 caracteres no es muy usado en cracking pero la calculadora trae dicha opción incluida, si se llegara a necesitar. Pues para pasar un número de un sistema a otro es muy sencillo, pongo la calculadora en el sistema del número que quiero cambiar, por ejemplo si quiero cambiar 55 de DECIMAL a HEXA, pongo la calculadora en DECIMAL y tipeo 55. Ahora cambio la calculadora a HEXA y automáticamente me lo convierte a ese sistema de numeración Ahí esta 55 decimal equivale a 37. Resalte las letras A,B,C,D,E,F para ver que al pasar la calculadora a HEXA se nos habilita la posibilidad de teclear las mismas, que estaban deshabilitadas en modo DECIMAL. Creo que esta es la forma mas practica de manejarse con los sistemas de numeración, y poder pasar valores de uno a otro sin grandes complicaciones. NUMEROS NEGATIVOS en HEXADECIMAL
  • 22. Esto es lo mas duro de entender por lejos tratemos de ir despacio. En el sistema de numeración hexadecimal, como podemos representar los números negativos, ya que no se puede poner el signo menos delante como hacemos en la tradicional numeración decimal ? Como hago para representar en formato hexadecimal -1 por ejemplo ? Pues aquí viene el problema y espero que se entienda. Solo tenemos la posibilidad de escribir en hexadecimal desde 00000000 hasta FFFFFFFF, como representaríamos los números negativos? Pues bien a un genio se le ocurrió que en vez de representar desde 00000000 hasta FFFFFFFF todos números positivos, usaríamos la mitad para los positivos y la otra mitad para los negativos. Los números positivos van entonces desde 00000000 hasta 7FFFFFFF y los negativos desde 80000000 hasta FFFFFFFF. POSITIVOS 000000000 es igual a 0 decimal 000000001 es igual a 1 decimal ……………………………….. ……………………………….. 7FFFFFFF es igual a 2147483647 decimal (que seria el máximo positivo) NEGATIVOS FFFFFFFF seria el -1 decimal FFFFFFFE seria el -2 decimal ……………………………… ……………………………… 80000000 seria -2147483648 decimal (que sería el máximo negativo) Podemos probar averiguar en la Command Bar el valor de 7FFFFFFF para ello usamos el signo de interrogación y a continuación el valor que deseamos pasar a decimal, Vemos a la derecha que nos da el valor DECIMAL correspondiente, que es 2147483647 sin problemas. Ahora cuando deseamos averiguar el valor de 80000000 que es negativo, vemos que no nos lo muestra sigue dando el resultado para 7FFFFFFF (esto es un bug de la Command Bar), así que como podemos hallar su valor en OLLYDBG ? Con este pequeño truquito. Vamos a los registros y marcamos EAX
  • 23. Luego hacemos CLICK DERECHO-MODIFY Nos aparece una ventana en la que podemos colocarle a EAX el valor que queremos, así que aprovechamos y usamos dicha ventana para hacer las conversiones, en el primer renglón tipeamos el valor HEXADECIMAL que queremos convertir y en el segundo renglón nos aparcera el resultado en DECIMAL. En este caso vemos que 80000000 corresponde al valor -214783648 decimal. Si averiguo el valor de FFFFFFFF allí vale -1 decimal.
  • 24. Por lo tanto en la ventana de modificar un registro podemos averiguar el valor de números negativos perfectamente, luego para salir podemos CANCELAR así no realizamos ningún cambio. CARACTERES ASCII Uno de los temas que debemos conocer también es la forma en que nuestro sistema escribe datos en la pantalla, para eso asigna a cada carácter un valor hexadecimal, de forma que puede interpretar los mismos como si fueran letras, números símbolos etc. De la teoría de ASM de Caos Reptante le copiamos la tablita jeje allí vemos a continuación el valor decimal, en la segunda columna el valor hexadecimal y en la tercera el carácter o sea por ejemplo si quiero escribir un espacio en OLLY, tengo que usar el 20 o 32 decimal, cualquier carácter que necesitemos, sea letra o numero podemos verlo en esta tablita. Dec. Hex. Carac t 32 20 esp 33 21 ! 34 22 " 35 23 # 36 24 $ 37 25 % 38 26 & 39 27 ' 40 28 ( 41 29 ) 42 2A * 43 2B + 44 2C , 45 2D 46 2E . 47 2F / 48 30 0 49 31 1 50 32 2 51 33 3 52 34 4 53 35 5 54 36 6 55 37 7 56 38 8 57 39 9 58 3A : 59 3B ; 60 3C < 61 3D = 62 3E > 63 3F ? Dec. 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 Hex. Carac t 40 @ 41 A 42 B 43 C 44 D 45 E 46 F 47 G 48 H 49 I 4A J 4B K 4C L 4D M 4E N 4F O 50 P 51 Q 52 R 53 S 54 T 55 U 56 V 57 W 58 X 59 Y 5A Z 5B [ 5C 5D ] 5E ^ 5F Dec. 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 Hex. Caract 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ Por lo demás la command bar cuando averiguamos el valor de un numero hexadecimal, nos proporciona también el carácter ASCII correspondiente si tuviera, veamos un ejemplo tipeemos en la command bar. ? 45
  • 25. Vemos que 45 corresponde a la letra E mayúscula, si en la tabla anterior buscamos 45 en la columna del medio que corresponde a hexa vemos que es la letra E 69 45 E Por lo demas en la ventana del DUMP del OLLYDBG, tenemos una columna que muestra los caracteres ASCII, si miramos allí mismo en el crackme de CRUEHEAD la ventana del DUMP. Vemos que al lado de la columna que representa los valores hexadecimales, esta la columna ASCII, donde podemos ver resaltadas algunas cadenas de texto compuestas por combinaciones apropiadas de caracteres ASCII. QUE ES EL STACK O PILA El stack o pila es una zona de la memoria, en la cual se van guardando datos que mas adelante deben ser recuperados. El nombre PILA es porque asemeja un mazo o pila de cartas o barajas que se encuentran en una mesa. En dicho mazo, si agregas una nueva carta solo podes hacerlo arriba de la pila y si quiero sacar una será la de más arriba de la pila de cartas. Esa es la característica principal del stack es como un mazo de cartas, la carta que agregas a la pila ira arriba, y será la primera que salga, cuando quites una. Ya veremos mas adelante en la explicación de las instrucciones la forma de modificar o agregar y quitar cartas en nuestro mazo, o sea nuestro querido STACK que como recordamos del tute anterior esta representado en la parte inferior derecha del OLLYDBG.
  • 26. Bueno creo que ya tienen bastante para quemarse un rato mas la cabeza nos vemos en la parte 3 donde explicaremos que son los registros y los flags y para que sirven. Hasta la parte 3 Ricardo Narvaja 08 de noviembre de 2005
  • 27. INTRODUCCION AL CRACKING CON OLLYDBG PARTE 3 QUE SON LOS REGISTROS Y PARA QUE SIRVEN Ahora para que sirven y que son exactamente los registros? Bueno el procesador necesita asistentes en su tarea de ejecutar los programas. Los registros lo ayudan en ello, cuando veamos las instrucciones ASM veremos por ejemplo que no se pueden sumar el contenido de dos posiciones de memoria directamente, el procesador tiene que pasar una de ellas a un registro y luego sumarla con la otra posición de memoria, este es un ejemplo pero por supuesto ciertos registros tienen usos mas específicos veamos. ESP apunta al valor superior del stack, vemos en nuestro Crackme de Cruehead como ejemplo. ESP vale 12FFc4 y si miramos el stack en OLLY en el mismo momento Vemos que apunta al valor superior de nuestro stack o dicho en forma simpática, a la carta superior de nuestro mazo de cartas o barajas. EIP es otro registro muy importante apunta a la instrucción que esta siendo ejecutada en este momento veamos Veamos en el listado del OLLYDBG, que al arrancar el crackme de Cruehead, este paro allí en 401000, que es la primera instrucción a ejecutar y por supuesto el valor de EIP cuando esta detenido allí será 401000.
  • 28. Si apreto F7 ejecuta la primera instrucción y pasa a la siguiente. EIP ahora vale 401002 y en al listado vemos que se ejecuto la primera instrucción y ahora estamos en 401002. Los otros registros pueden tomar valores variables y sirven para asistir al procesador en las ejecuciones de las instrucciones, ECX es usado casi siempre como contador los demás son fluctuantes y asisten en la ejecución de programas como veremos en la explicación de cada instrucción. Recordamos donde el OLLYDBG nos mostraba el valor de los REGISTROS Vemos a simple vista que son EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI y EIP Esos son los llamados REGISTROS de 32 bits OLLYDBG expresa el contenido en hexadecimal, vemos por ejemplo que EAX vale 00000000, y el máximo valor que podría tener es FFFFFFFF, si lo pasamos a BINARIO seria 11111111111111111111111111111111. Vemos que son 32 bits cada uno con la posibilidad de ser 0 o 1 en numero binario, por eso se llama a estos, registros de 32 bits. En el lenguaje ASM se pueden operar con partes de los registros de 32 bits, en este caso EAX, puede ser subdividido. Veamos en el OLLY para más practicidad con un ejemplo:
  • 29. Cambiare el valor de EAX a uno que yo quiera en este caso 12345678. Abro el OLLYDBG y allí mi programa será el CRACKME DE CRUEHEAD, aunque podría ser cualquiera. Una vez que arranca y para en el inicio hago clic derecho en EAX y elijo MODIFY En la ventana que se abre escribo en la línea hexadecimal el valor 12345678 Queda así Luego acepto con OK Allí vemos como quedo cambiado al valor que yo deseaba, OLLYDBG tiene la particularidad de poner en ROJO los valores que se modifican. Como decíamos se pueden usar solo partes de EAX, en este caso AX seria el registro de 16 bits o sea las cuatro ultimas cifras de EAX, por lo tanto AX valdría en este caso 5678, corroborémoslo en OLLY en el commandbar tipeemos ? AX (ya que el signo de interrogación sirve también para hallar el valor de una expresión o de un registro) Cuando apreto ENTER
  • 30. Vemos que dice 5678 que es lo que suponíamos, AX son las ultimas cuatro cifras de EAX. También existen AL y AH, cuales son estos miremos en OLLYDBG ? AL ? AH O sea si EAX=12345678 AX son las ultimas cuatro cifras AH la 5 y 6 cifra y a su vez AL las ultimas dos cifras También en la misma forma EBX se puede subdividir en BX, BH y BL y así sucesivamente existen subdivisiones para casi todos los otros registros. COMO CAMBIAR LOS VALORES DE LOS REGISTROS Ya vimos como se pueden cambiar valores de los registros en OLLYDBG, lo que hicimos en EAX se puede hacer en los otros registros de la misma forma, marcando el registro que deseamos cambiar de valor, luego haciendo CLICK DERECHO-MODIFY, salvo en el caso de EIP, dado que el mismo apunta a la instrucción que se esta ejecutando. Para cambiar EIP operamos de la siguiente forma: Ya que EIP siempre apunta a la instrucción que se va a ejecutar, elegimos una nueva instrucción en el listado.
  • 31. Luego que esta marcada como en este ejemplo 40101A, hago en ella CLICK DERECHO-NEW ORIGIN HERE y cambiara EIP a 40101A, continuando el programa ejecutándose desde allí. Como vemos queda EIP valiendo 40101A QUE SON LOS FLAGS? Como vimos en el primer tutorial en OLLYDBG debajo de los registros se encuentran los flags o banderas. Vemos que los flags son C P A Z S T D y O Vemos que solo pueden tener valores de cero o uno, que nos advierten que al ejecutar determinada instrucción, ha ocurrido algo, según el flag que sea.
  • 32. Vayamos mirando que indica cada uno: EL FLAG O O FLAG OVERFLOW (DESBORDAMIENTO) Se activa cuando al hacer una operación, el resultado cambia de signo dando un valor incorrecto. Miremos en OLLYDBG este ejemplo, como siempre en el CRACKME DE CRUEHEAD de paso vamos practicando usar el OLLYDBG. Modifico como hicimos antes el valor de EAX a 7FFFFFFF que es el máximo positivo posible. Ahora le sumare 1, lo cual excederá la posibilidad de EAX de mostrar un resultado positivo ya que 80000000 ya corresponde a un número negativo Para eso apreto la barra espaciadora que me permite escribir instrucciones. Me sale esa ventana donde escribo ADD EAX,1. Al apretar el botón ASSEMBLE vemos que cambia la instrucción que había antes en 401000 por la que yo escribí. ADD EAX, 1 (ya lo veremos cuando enumeremos y expliquemos las instrucciones) seria sumarle a EAX el valor 1, y guardando el resultado en el mismo EAX. Veo que antes de ejecutar la línea con F7 el flag O esta en cero
  • 33. Si ejecuto la instrucción con F7 para ver que es lo que ocurre, al realizar dicha operación veo que EAX al sumarle 1 se desborda y me muestra 80000000 lo cual traspasa la línea del cambio de signo. El FLAG O se activa poniéndose a 1 indicándome que la operación excedió el máximo resultado posible y esa es su función indicar cuando ocurra desborde al ejecutar una instrucción. El FLAG A o AUXILIAR Tiene una función similar pero para cuando se realizan operaciones con otros formatos que por ahora no nos interesan. El FLAG P o PARIDAD Dicho flag se activa cuando ejecutamos una instrucción y su resultado es un valor, que pasado a numero binario tiene una cantidad par de unos, como por ejemplo 1010, o 1100 o 1111000 que tienen resultados cuya cantidad de unos total es par. Para probar esto ya que tenemos en el OLLYDBG escrito ADD EAX,1 y como ya ejecutamos esa línea para probar el flag anterior, pues la marcamos de nuevo y hacemos CLICK DERECHO-NEW ORIGIN HERE lo cual llevara EIP de nuevo a 401000 (volvemos atrás) y a que si apreto F7 se ejecute de nuevo la instrucción que escribimos ADD EAX,1. Allí tenemos pues de nuevo justo antes de ejecutar la suma, con EAX valiendo 00000000 y el flag P valiendo 1, porque quedo así de la operación anterior, veamos que ocurre cuando le sumamos 1 a EAX nuevamente. Apretamos F7
  • 34. Vemos que P nos marca 0 porque el resultado que muestra EAX=00000001 que en binario es 1 y tiene un solo 1 o sea un numero impar de unos por eso no se activa. Y vuelvo a hacer ahora click derecho en nuestro ADD EAX,1 y de nuevo CLICK DERECHO- NEW ORIGIN HERE para volver a sumar 1 y apreto F7. Vemos que EAX que valía uno, al sumarle uno nuevamente, ahora vale 2 que es 10 en binario y sigue el resultado teniendo un solo uno por lo cual el flag P no se activo, si repito el procedimiento una vez mas, volviendo atrás y apretando F7 para sumarle 1 nuevamente a EAX. Ahora EAX vale 3 que en BINARIO es 11 o sea el resultado tiene un numero par de unos por lo cual se activo el FLAG P o de paridad. Con eso vemos como funciona el susodicho FLAG, al ejecutar una operación solo mira el resultado y si el mismo en BINARIO tiene cantidad par de unos, se activa. El FLAG Z o FLAG CERO Uno de los más conocidos y usados en el cracking es el FLAG CERO el mismo se activa cuando ejecutamos una instrucción y el resultado es cero.
  • 35. Podemos volver con CLICK DERECHO-NEW ORIGIN HERE a nuestro ADD EAX,1 de 401000, pero cambiemos ahora el valor de EAX a FFFFFFFF que es -1 decimal, de forma de que cuando apretemos F7 y ejecutemos ADD EAX,1 , sumemos -1 +1 el resultado sea cero a ver si se activa el FLAG Z. Vemos que al apretar F7, EAX quedo en cero y como el resultado es cero, se activo el FLAG Z poniéndose a uno. Creo que queda claro que dicho flag, se activa cuando el resultado de una instrucción es cero ya veremos diversas formas de activarlo mas adelante. El FLAG S o FLAG DE SIGNO Se activa cuando el resultado de una operación es negativo, o sea si quiero probarlo cambio EAX a FFFFFFF8 que es -8 decimal Y vuelvo con NEW ORIGIN HERE a mi ADD EAX,1 al apretar F7 y ejecutarlo, estoy sumando a -8 el valor 1, el resultado es FFFFFFF9 que es -7 decimal, el cual es negativo aun por lo cual debería activarse el flag de SIGNO probemos en OLLY.
  • 36. Vemos que al apretar F7 y hacer la suma se activa el flag S de signo quedando a 1, queda claro como funciona, resultado negativo de una instrucción se activa el FLAG S. EL FLAG C o CARRY FLAG Se activa cuando se excede el máximo valor posible que se puede mostrar, si ponemos EAX a FFFFFFFF y le sumamos 1 como hicimos las veces anteriores veremos activarse el CARRY FLAG poniéndose a 1. EL FLAG T , D e I No los explicaremos por ahora pues son bastante complejos, si lo haremos mas adelante, no tiene mayor interés por ahora, ya que vamos a explicar las instrucciones mas sencillas, así que los dejaremos para mas adelante. Bueno con esto tenemos una idea de que es cada registro y en que caso se activa cada FLAG, con esa información ya podremos en la tercera parte estudiar instrucción por instrucción ya que por ahora solo vimos la instrucción ADD para ayudarnos a comprender cuando se activaba cada FLAG. Se que esta parte y la que viene son las mas indigestas de todas así que léanla con paciencia, practiquen con el OLLY activar los FLAGS al ejecutar nuestro ADD EAX,1 y nos vemos en la parte 3 de esta INTRODUCCION. Es muy importante que queden bien grabados todos estos conceptos básicos, recomiendo leer practicar y releer hasta que no haya dudas. Hasta la parte 4 Ricardo Narvaja 10 de noviembre de 2005
  • 37. INTRODUCCION AL CRACKING CON OLLYDBG PARTE 4 INSTRUCCIONES Como ya venimos diciendo en las anteriores partes, la idea de esta introducción es ir aprendiendo a la vez que indigestándonos con la dura teoría, practicándola en OLLYDBG para ir conociendo el mismo, y de paso ir tomado confianza e ir mirando las posibilidades que tiene. Así como con los flags vimos en OLLYDBG que instrucciones los activaban, ahora veremos que ocurre al ejecutar cada instrucción en el mismo OLLYDBG lo cual da una idea mas cercana a la realidad y se hace mas llevadero. Veremos las instrucciones mas importantes si al mirar un listado uno encuentra alguna que no se definimos aquí, siempre se puede consultar un manual de ASM para ver que función cumple. NOP (NO OPERATION) Es la instrucción que al ejecutarla no hace nada ni provoca ningún cambio en registros, stack o memoria, por eso en ingles es NO OPERATION o sea que no hay operación alguna, y para que se usa dirán, muchas veces al cambiar una instrucción por otra, queda un hueco ya que la instrucción que escribimos es mas corta, y hay que rellenar con NOPS para que el procesador no encuentre basura y de error. También sirve para anular cualquier instrucción, si la reemplazo por nops el programa ejecutara los mismos en vez de la instrucción original y no hará nada lo que es comúnmente conocido como NOPEAR. Si abrimos nuevamente el crackme de cruehead. Allí vemos el código original en el inicio, lo que haremos será nopear la primera instrucción PUSH 0, que es un comando de 2 bytes de extensión, para ello marcamos la línea con el mouse, y luego apretamos la barra espaciadora o bien hacemos CLICK DERECHO –ASSEMBLE. Allí vemos que en el mismo menú nos confirma que es lo mismo apretar la barra espaciadora, esto nos abrirá una ventana para escribir la instrucción que queramos. Escribo NOP y apreto ASSEMBLE.
  • 38. Vemos que OLLY además de escribirnos un NOP, como es bastante inteligente, reconoce que el PUSH que había antes es un comando de DOS BYTES por eso para no desarmar el código siguiente nos agrega otro NOP para completar con el NOPEADO del PUSH. Si comparamos ambas imágenes vemos que donde estaba el PUSH 0 ahora hay dos NOPS que al ejecutarlos no hacen nada, esto lo podemos corroborar, apretando dos veces F7 hasta llegar al CALL siguiente, si miramos al apretar si cambia algún registro o algo en el stack, o un FLAG, vemos que todo esta igual , lo único que cambio fue EIP pues como sabemos apunta a la instrucción que se va a ejecutar y en este caso ahora es el CALL, pero no hay cambios en el resto de los registros ni stack, ni flags, ni memoria. Ahora veremos esos mismos 2 bytes que reemplazamos en el DUMP, para hallarlos allí, debemos buscarlos por la dirección de memoria, vemos que la misma es 401000 y 401001 Voy a la ventana del DUMP y hago CLICK DERECHO - GOTO EXPRESSION y pongo la dirección de memoria a partir de la cual quiero que muestre los bytes que contiene. Por supuesto tipeo 401000 Los que vemos es
  • 39. El rojo es original puesto POR OLLY ya que cuando cambiamos bytes, OLLY nos los recuerda mostrandolos en color rojo, allí vemos los dos 90 que pusimos y luego E8, FF y los siguientes bytes que ya pertenecen a la siguiente instrucción que es un CALL. Podemos en OLLY quitar lo que hemos escrito y volver al código original? Jeje, si podemos. En cualquiera de los dos, sea en el DUMP o en el listado, marcamos los dos bytes que escribí. Ahora hago CLICK DERECHO-UNDO SELECTION Y aquí no ha pasado nada, vuelve a aparecer el PUSH original Lo mismo si miramos el DUMP, vemos que ahora están los bytes originales. Bueno eso es todo en cuanto a la instrucción NOP sigamos adelante.
  • 40. INSTRUCCIONES DE STACK Bueno habíamos dicho que el stack era como un mazo de cartas que se le agregaban o quitaban cartas por arriba del mismo. Por supuesto hay instrucciones para agregarle y quitarle cartas. PUSH La instrucción PUSH es la típica instrucción que agrega una carta o valor al stack Veámoslo en OLLYDBG la primera instrucción del programa original del crackme de cruehead era un PUSH. En este caso es un PUSH 0, al ejecutarla lo que hará en este caso, será colocar el 0 en la posición superior del stack, sin sobrescribir lo que se encontraba antes lo cual quedara debajo. Veamos como esta el stack antes de ejecutar el PUSH, en mi maquina esta en esta dirección, en la de ustedes puede variar aunque el efecto será el mismo. Este es el stack en mi maquina, la dirección 12FFc4 puede variar en su máquina, ya que el stack se puede acomodar en otra dirección en cada caso, y el contenido inicial a veces también puede variar o sea que ustedes pueden tener otro valor que 7c816d4f, pero no importa al ejecutar F7, el cero pasara a la parte superior del stack y el resto quedara abajo, veamos apreto F7. Vemos que al ejecutar F7 fue realmente como si se agregara encima el cero que vemos resaltado allí, abajo en 12ffc4 sigue estando 7c816d4f, y no vario nada todos los mismos valores están en las mismas direcciones del stack.
  • 41. La única diferencia que ahora el valor superior del stack es 12ffc0 y allí esta el cero que pusimos con el PUSH, fue realmente como agregar una carta a un mazo, se coloco arriba y dejo el resto que estaba antes sin cambiar nada debajo. Vemos también que el puntero ESP que muestra la dirección del valor superior del stack ahora marca 12FFc0. Por supuesto el comando PUSH tiene variantes no solo puedo agregar números, si hago: PUSH EAX, agregare el valor de EAX en lugar del cero, podemos PUSHEAR cualquier registro, numero etc. Podemos PUSHEAR también el contenido de una dirección de memoria PUSH [401008] Veamos que se debe interpretar bien la diferencia con PUSH 401008 Sin corchetes Si hago PUSH 401008 lo que hará será colocar el número 401008 en el stack Al ejecutarlo quedara así En cambio si fuera PUSH [401008]
  • 42. Los corchetes significan el contenido de la memoria en 401008 o sea que debemos ir en el DUMP a ver esa dirección y ver que hay alli. Con GOTO EXPRESSION 401008 vemos Que los 4 bytes que hay allí son CA 20 40 00, ejecutemos con F7 el PUSH Vemos que mando al stack el valor que leyó pero los bytes están al revés o sea nosotros vemos en el dump CA 20 40 00 y los puso al revés o sea 00 40 20 CA. Bueno esta es una propiedad del procesador, al leer o escribir contenidos de memoria siempre los bytes se toman al revés, y bueno quejas al inventor del procesador jeje. Pero la idea que debe quedar grabada es que sin corchetes el valor es simplemente un número, y con corchetes el valor refiere al contenido de una dirección de memoria. Ahora vemos que el OLLY cuando escribimos PUSH [401000] interpreto y escribió PUSH DWORD PTR DS:[401008] Porque ocurrió eso
  • 43. Es que si uno no aclara el OLLY interpreta que uno quiere leer los 4 bytes de esa posición de memoria, eso es DWORD leer los 4 bytes completos ya veremos las otras variantes en otras instrucciones. POP La instrucción POP es la inversa de PUSH lo que hace es quitar la primera carta o el primera valor del stack y lo coloca en la posición que indicamos a continuación del POP, por ejemplo, POP EAX tomara el primer valor del stack y lo quitara moviéndolo a EAX, y será como si quitamos una carta, ya que el valor que estaba debajo quedara como primero. Vemos arranquemos de nuevo el crackme de cruehead y en el inicio esta Cambiemos dicha instrucción por POP EAX, marcamos la primera línea, apretamos la barra espaciadora y tipeamos. Ahí esta el stack antes de ejecutar la instrucción esta Y ESP apunta a 12FFc4 que es el valor superior del stack.
  • 44. Y vemos que EAX esta a cero antes de ejecutar la línea en mi caso. Apreto F7 Vemos que en el stack desapareció nuestra primera carta, ahora el primer lugar lo ocupa la que entes estaba 2da y ESP apunta a 12ffc8. Pero donde fue a parar nuestra carta se perdió?, noo como era un POP EAX fue a parar a EAX vemos en la imagen que EAX ahora vale 7c816d4f en mi caso y en el suyo tendrá el valor que antes estaba superior en el stack en vuestra maquina. Lo mismo si hubiera sido POP ECX el valor superior hubiera ido a ECX o al registro que eligiéramos. Bueno ya vimos las instrucciones que ponen o quitan una carta al stack ahora tenemos. PUSHAD PUSHAD guarda el contenido de los registros en la pila en un orden determinado. Así pues, pushad equivale a: push EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI. Veamos si es cierto lo que nos dice nuestro amigo CAOS REPTANTE en su tute de asm, jeje. Abrimos de nuevo el crackme de cruehead y ya sabemos que apretamos la barra para escribir y alli tipeamos PUSHAD.
  • 45. Allí esta mi stack inicial y los registros antes de ejecutar el pushad son Apreto F7 y veamos que paso en el stack Vemos que hizo un PUSH a cada uno de los registros, el primero que agrego esta arriba de 12ffc4 que era el valor superior del stack antes de ejecutar, ahora hay un cero arriba que corresponde a PUSH EAX, luego hizo PUSH ECX y mando el 12ffb0 que estaba en ECX, luego envió consecutivamente los valores de los registros uno a uno al stack hasta el ultimo que fue PUSH EDI. POPAD
  • 46. La inversa de PUSHAD es POPAD en este caso toma los valores del stack y los manda a los registros como si fuera un POP a cada uno. Así popad equivale a: pop EDI, ESI, EBP, ESP, EBX, EDX, ECX, EAX. Allí mismo donde quedo del ejemplo anterior escribamos un POPAD Allí esta para ejecutarse el POPAD los registros están guardados en el stack y al apretar F7 vuelven del stack a sus lugares originales. Allí esta el stack como era antes del pushad y los registros recuperan sus valores La dupla PUSHAD-POPAD se usa mucho cuando se quiere guardar el estado de registros en un punto, realizar muchas operaciones que cambian registros y el stack, y luego con POPAD restaurar los registros y el stack al estado original. Existen algunas variantes como PUSHA equivale a: push AX, CX, DX, BX, SP, BP, SI, DI. POPA equivale a: pop DI, SI, BP, SP, BX, DX, CX, AX (los valores recuperados correspondientes a ESP y SP, no se colocan en los registros sino que se descartan). En el caso de PUSHA y POPA es similar a sus hermanas PUSHAD y POPAD salvo se que utilizan en programas de 16 bits lo cual no nos interesa ya que OLLYDBG es un debugger para programas de 32 bits.
  • 47. INSTRUCCIONES PARA MOVER DATOS MOV Esta instrucción es lo que comúnmente llamaríamos MOVER, mueve el segundo operando al primero por ejemplo. MOV EAX, EBX Lo que hace es mover el valor de EBX a EAX, miremos en OLLY y nuestro bendito crackme de cruehead. Ya no repetiré como se escribe una instrucción ya lo hemos visto, veamos los registros antes de ejecutar En mi maquina EAX es 0 y ECX es 7c91eb94, como son valores iniciales en la suya pueden ser diferentes pero al apretar F7 lo importante es que el valor de EBX lo moverá a EAX, veamos apretemos F7. Viola esta claro no? MOV tiene variantes por ejemplo MOV AL, CL Esto movería el valor de CL a AL veamos reinicio OLLYDBG y escribo
  • 48. Los registros Recordamos lo que vimos ya que AL son las ultimas dos cifras de EAX y CL las dos ultimas cifras de ECX, ejecutemos con F7 Vemos que sin tocar el resto de EAX y ECX el B0 se copio a AL, o sea las ultimas dos cifras de EAX. También podemos mover a algún registro el contenido de una posición de memoria o al revés. En esta caso moveremos el contenido de 405000 a EAX y como dice DWORD serán los cuatro bytes lo que moveremos. Esta instrucción puede dar error si la dirección de memoria no existe, lo cual podemos ver fácilmente en el OLLY. Vamos al DUMP y hacemos GOTO EXPRESSION 405000
  • 49. Vemos que existe y su contenido es 00 10 00 00 o sea al moverlo a EAX, dado que trabajamos con el contenido de una dirección de memoria se moverá al revés o sea 00 00 10 00 apretemos F7 a ver que pasa Allí esta el 1000 que leyó de dicha dirección de memoria, ahora si quisiera escribir un valor en dicha dirección seria MOV DWORD PTR DS:[400500],EAX Reinicio el OLLYDBG y la escribo En 405000 veo en el DUMP Al apretar F7 oops Me da una excepción y eso es porque la sección donde vamos a escribir no tiene permiso de escritura, lo cual impide cambiar bytes ejecutando instrucciones.
  • 50. Bueno ya veremos como cambiar permisos de secciones mas adelante lo importante es que ya conocen la instrucción. Obviamente como podemos mover 4 bytes especificando la palabra DWORD si usamos WORD moverá 2 y si usamos BYTE moverá 1 . Veamos MOV AX,WORD PTR DS:[405008] En este caso moverá dos bytes del contenido de 405000 a AX, en este caso no podemos escribir EAX ya que como son solo 2 bytes los que movemos debemos usar el registro de 16 bits AX. Veamos que hay en el DUMP en 405008 Al apretar F7 debería mover solo esos 2 bytes a AX, veamos Allí esta en AX, al revés como corresponde a leer de contenidos de memoria, el resto de EAX no ha sido cambiado solo lo correspondiente a AX. Lo mismo seria si usáramos BYTE MOV AL, BYTE PTR DS:[405008] En este caso movería a AL el ultimo byte solamente o sea el 08.
  • 51. MOVSX (Move with Sign-Extension) Copia el contenido del segundo operando, que puede ser un registro o una posición de memoria, en el primero (de doble longitud que el segundo), rellenándose los bits sobrantes por la izquierda con el valor del bit más significativo del segundo operando. Aquí tenemos un par de ejemplos: La definición la sacamos del tute de CAOS ahora veamos un ejemplo en OLLYDBG para aclarar y usemos a nuestro amigo CRUEHEAD. Como aun no se los dije porque soy muy malo y quería que siempre buscaran a mano, los valores de los operandos jeeje, OLLYDBG tiene una ventana de aclaraciones que esta justo debajo de el listado y arriba del DUMP. Allí vemos que la ventana de aclaraciones nos muestra el valor de los operándoos de nuestra instrucción en mi caso BX vale F000 eso lo puedo corroborar en los registros Y allí mismo veo que EAX vale cero, así que siempre el OLLYDBG nos ayuda a interpretar los operandos de la instrucción a ejecutar. (que malo soy jeje pero quise que fijen el concepto de donde buscar cada cosa antes de la comodidad jeje) Al apretar F7
  • 52. Vemos que se copia el BX que era F000 a AX y que se rellena con FFFF ya que el numero es un negativo de 16 bits , si hubiera sido BX 1234 entonces quedaría EAX=00001234 ya que rellena con ceros al ser BX positivo. El tema de los positivos y negativos de 16 bits es similar a 32 bites se divide por la mitad el espacio 0000 a FFFF de 0000 hasta 7FFF son positivos y de 7FFF a FFFF son negativos vemos que si modificamos BX a 7FFF y ponemos EAX a cero y volvemos a ejecutar la instrucción Copia 7FFF a AX pero rellena con ceros ya que 7FFF es positivo si repetimos pero con BX=8000 que es negativo, Ejecuto nuevamente con F7 y Copia BX a AX y rellena con FFFF ya que 8000 es negativo MOVZX (Move with Zero-Extend)
  • 53. Igual a movsx, pero en este caso, los espacios sobrantes se rellenan siempre con ceros o sea no depende de si el segundo operando es positivo o no como en el caso anterior no haremos ejemplos porque es sencillo darse cuenta que todos los ejemplos anteriores darían en EAX 0000…… y a continuación los bytes de BX que se copiaron a AX. LEA (Load Effective Address) Similar a la instrucción mov, pero el primer operando es un registro de uso general y el segundo una dirección de memoria. Esta instrucción es útil sobre todo cuando esta dirección de memoria responde a un cálculo previo. Esto nos dice nuestro amigo CAOS y significa que en este caso por ejemplo reinicio OLLY. Aquí es el único caso en que hay corchetes que no se mueve el contenido de la dirección de memoria que se calcula dentro del corchete si no la dirección en si. En mi caso ECX vale 12FFb0 Y lo que hace LEA es sumarle 38 en este ejemplo y mover ECX mas 38 que es igual a 12ffe8 a EAX En la ventana de las aclaraciones ya muestra ambos operándoos Muestra que un operando es 12FFe8 que proviene de sumar ECX+38 y EAX vale cero antes de operar. Al apretar F7
  • 54. Dicha dirección se mueve a EAX, hay que tener cuidado porque los corchetes nos llevan a pensar que deberíamos mover el contenido de la dirección 12ffe8 que debemos buscar en el dump como en el caso de la instrucción MOV, pero LEA solo mueve la dirección al primer operando no su contenido. XCHG (Exchange Register/Memory with Register) Esta instrucción intercambia los contenidos de los dos operandos. En este caso intercambia los valores si escribimos XCHG EAX,ECX El valor de EAX pasara a ECX y viceversa comprobémoslo en OLLY Antes de ejecutar en mi maquina EAX vale cero y ECX vale 12FFb0 Al apretar F7 vemos que intercambian sus valores También se puede usar para intercambiar con una posición de memoria siempre que tenga permiso de escritura dicha sección Al ejecutar con F7
  • 55. Nos pasa lo mismo que cuando quisimos hacer MOV a dicha dirección al no tener permiso de escritura nos genera una excepción. Bueno creo que como primera parte de las instrucciones ya tienen para divertirse y practicar, creo que los ejemplos si los van haciendo mientras leen aclaran bastante la cosa, en la siguiente parte seguiremos con mas instrucciones hasta terminar con las mas importantes y tratar de terminar esto que es lo mas duro. Hasta la parte 5 Ricardo Narvaja 13 de noviembre de 2005
  • 56. INTRODUCCION AL CRACKING CON OLLYDBG PARTE 5 INSTRUCCIONES MATEMATICAS INC Y DEC Estas instrucciones incrementan o decrementan respectivamente el operando, sumándole uno si es INC o restándole uno en el caso de DEC. Veamos en el OLLY, como siempre abrimos el OLLYDBG y el crackme de cruehead y en la primera línea escribimos EAX en el estado inicial en mi maquina esta a cero, si no puedo cambiarlo a cero a mano Así que al apretar F7 y ejecutar la instrucción se INCREMENTARA EAX en uno veamos apretemos F7 Lo mismo ocurre con DEC podemos escribirlo debajo del anterior Al apretar F7 y ejecutar la instrucción se DECREMENTA EAX que estaba en 1 y volverá a 0.
  • 57. También se pueden incrementar o decrementar el contenido de posiciones de memoria Aunque en este caso la sección no tiene permiso de escritura y no dejara aumentar el contenido dando excepción. Si la sección hubiera tenido permiso de escritura, vamos en el dump a la dirección 405000 Ya que el contenido al leerlo al revés es 00001000, si lo incrementamos seria 00001001 o sea quedaría así Este fue el caso para DWORD sumándole UNO a los 4 bytes del contenido. En el caso de WORD el ejemplo sumaria solo a los últimos 2 bytes Y en el caso de BYTE sumaria solo al último byte ADD Add como ya vimos es la instrucción correspondiente a la suma, siempre suma ambos operandos y guarda el resultado en el primero. ADD EAX,1 es similar a INC EAX También puede sumar registros Veamos en OLLY
  • 58. Antes de ejecutar la operación En mi maquina EAX vale 00000000 y ECX vale 12FFB0 en sus maquina puede tener otros valores, pueden cambiarlos si quieren, pero al apretar F7 sumara ambos y guardara el resultado en EAX, veamos Allí esta EAX esta en rojo pues fue el que se modifico y tiene el resultado de la suma. También podemos sumar a un registro el contenido de una memoria En este caso no hay problema por el permiso de escritura ya que como EAX cambiara y guardara el resultado y el contenido de [405000] no cambiara ya que es el segundo operando, la operación no generara excepción. Antes de apretar F7 vemos que EAX vale 0 y el contenido de 405000 vale 00001000
  • 59. Apreto F7 y se ejecuta la suma Entonces EAX=0 mas 1000 se modifica EAX quedando el resultado allí que es 1000. Si hacemos al revés y escribimos En este caso el resultado se guardara en el contenido de 405000 y esto modificara el mismo por lo cual al apretar F7 generara una excepción al no tener permiso de escritura. ADC (ADD WITH CARRY) En este caso se suman ambos operandos y se le suma el valor del CARRY FLAG O FLAG C y se guarda en el primer operando.
  • 60. Allí vemos que sumara EDX que vale 21 mas 3 mas el valor del flag C, que en este caso es cero, si apreto F7. Veo que el resultado es 24, pero si repito la operación con el FLAG C puesto a 1 el cual se puede cambiar haciendo doble click en el mismo. Allí lo cambie a uno y pongo todo como antes para repetir la operación solo cambiando el flag C.
  • 61. Apreto F7 para que se realice la suma y ahora el resultado es 25 Ya que suma EDX =21 mas 3 mas el FLAG C que en este caso vale 1. SUB Es la resta o substracción o sea la operación contraria a ADD, lo que hace es restar el segundo operando al primero y guardar el resultado en el primer operando. En mi maquina los registros valen antes de ejecutar Al apretar F7 le restara a EAX que vale cero el valor 2
  • 62. El resultado es -2 que en hexadecimal se representa FFFFFFFE si hacemos doble click en dicho valor Vemos que corresponde al decimal -2. También se pueden restar registros, y posiciones de memoria en la misma forma que lo hicimos con ADD. SUB EAX,ECX Por ejemplo hará EAX-ECX y guardara el resultado en EAX Y SUB EAX,DWORD PTR DS:[405000] Restará a EAX el contenido de la posición de memoria 405000, guardando el resultado en EAX. En el caso inverso SUB DWORD PTR DS:[405000],EAX Ya que el resultado se guarda en el primer operando, si no tenemos permiso de escritura en la sección, nos dará una excepción. SBB Es la operación contraria a ADC, es este caso se restan ambos operandos y se le resta el valor del CARRY FLAG O FLAG C y se guarda en el primer operando. Antes de ejecutar la operación ponemos EDX a 21 y el carry flag a 0
  • 63. Al apretar F7 hará EDX-3 y le restara cero del FLAG C Ahora su repito la operación con el FLAG C a 1 Apreto F7 y ahora hará EDX-3 y le restara 1 del FLAG C
  • 64. En este caso el resultado es 1D. MUL Bueno hay dos instrucciones para realizar multiplicaciones, la primera de ellas es MUL, la cual no considera los signos de los números que va a multiplicar, y usa un solo operando el otro operando es siempre EAX aunque no se escribe y el resultado lo guarda en EDX:EAX que quiere decir esto veamos el ejemplo. Por ejemplo MUL ECX Esto multiplicara ECX por EAX y guardara el resultado en EDX:EAX y no considerara el signo de los operandos. Por ejemplo veamos en OLLYDBG Pongo EAX a FFFFFFF7 y ECX a 9 si realizo la multiplicación en la calculadora de Windows veo que
  • 65. El resultado es Y no entra en EAX veamos que pasa en OLLY al apretar F7 Allí vemos en rojo que EDX y EAX cambiaron y como vemos guarda en EAX los bytes que entran allí y luego guarda los que no entran en EDX, en este caso el 8 que no puede mostrar EAX, lo guardo en EDX, por eso se dice que en este caso el resultado se muestra en EDX:EAX ya que usa ambos como si fueran un solo registro del doble de largo. En el caso MUL DWORD PTR DS:[405000] Multiplicara el contenido de 405000 por EAX y como siempre guardara el contenido en EDX:EAX sin considerar el signo de los operandos. Siempre que en OLLY queramos ver cuanto es el valor de un numero hexadecimal sin signo, hacemos doble click en cualquier registro
  • 66. Como habíamos visto la segunda línea nos daba el valor con signo en este caso FFFFFFAF es -81 considerado con SIGNO, pero en operaciones como MUL donde los números se consideran SIN SIGNO el valor decimal se lee en la tercera línea la que dice UNSIGNED, allí vemos 4294967215 seria el valor tomando al numero como positivo o sin SIGNO. IMUL (multiplicación con signo) La instrucción IMUL no solo es multiplicar con signo de la misma forma que lo hacia MUL IMUL ECX Es igual que antes ECX por EAX y el resultado se guarda en EDX:EAX salvo que se considera el signo de los operandos. Además de la similitud con la instrucción anterior IMUL permite poner mas de un operando, lo que no estaba permitido en MUL. Del tute de CAOS Además de la utilización de los registros EAX y EDX, así como de sus subdivisiones, pueden especificarse otros orígenes y destinos de datos y puede haber hasta tres operandos. El primero, es el lugar donde se va a guardar el resultado, que debe ser siempre un registro, el segundo y el tercero son los dos valores a multiplicar. En estos ejemplos vemos como estas instrucciones con dos o tres operandos, tienen el mismo espacio para el resultado que para cada uno de los factores: F7EB imul ebx EAX x EBX -> EDX:EAX Este primer ejemplo es el conocido y similar a MUL salvo que se consideran los signos 696E74020080FF imul ebp, dword ptr [esi+74], FF800002 [ESI+74] x FF800002 -> EBP Este es el segundo ejemplo que pone veamos en este caso hay tres operandos, multiplica el contenido de ESI+74 por FF800002 y el resultado lo guarda en EBP, podemos hacerlo en OLLY Copio la linea imul ebp, dword ptr [esi+74], FF800002 al OLLY Veo que al apretar ASSEMBLE me da error y eso es porque en el OLLY los números que empiezan por letras deben agregársele un cero delante si no, no los interpreta, corrijamos
  • 67. Ahora apreto ASSEMBLE y lo acepta Cambio el valor de ESI a 401000 para asegurarme que la dirección ESI mas 74 exista y se pueda leer su contenido Veamos en la aclaración del OLLY Alli nos dice que ESI + 74 es la dirección 401074 y que su contenido es C7000000, veamos en el dump con GOTO EXPRESSION 401074. Y si, es cierto el contenido leído al revés seria C7000000, eso lo multiplicara por FF800002 y como el primer operando es EBP pues guardara allí el resultado imul ebp, dword ptr [esi+74], FF800002 Al apretar F7 vemos que se puso rojo EBP ya que ahora contiene el resultado
  • 68. El resultado en la calculadora nos da C7000000 * FF800002 Pero como especificamos que se muestre en EBP pues solo muestra los bytes que caben allí, el resto los descarta. En el tercer ejemplo que hay solo dos operandos se multiplican ambos y el resultado se guarda en el primero. 0FAF55E8 imul edx, dword ptr [ebp-18] EDX x [EBP-18] -> EDX Como vemos la mejor opción para multiplicar números largos es usando IMUL con solo un operando pues en este caso el resultado lo guarda en EDX:EAX con la posibilidad del doble de largo lo cual no ocurre cuando usamos dos o tres operandos, dichas opciones son mas útiles en operaciones pequeñas. DIV (Unsigned Divide) / IDIV (Signed Divide) Estos son la contrapartida de MUL Y IMUL respectivamente DIV solo tiene un operando y no considera los signos y el resultado se guarda en EDX:EAX IDIV siempre considera los signos si usa un solo operando será como DIV y guardara en EDX:EAX y en el caso de dos operandos dividirá ambos y guardara en el primero, y en el de tres operandos dividirá el segundo y el tercero y guardara en el primero. No creo que sea necesario repetir los ejemplos pues son similares a los de MUL e IMUL. XADD (Exchange and Add) Es como realizar en una sola instrucción XCHG y ADD o sea que si tenemos XADD EAX,ECX
  • 69. Allí vemos ECX que es 1 y EAX es 7 al apretar F7 se intercambian o sea que EAX pasa a valer 1 y ECX 9 luego se suman Como vemos el resultado se sigue guardando en el primer operando, lo único que cambio fue que se intercambiaron los valores antes de sumarlos, vemos que ECX quedo valiendo 9 que era lo que valía EAX antes de intercambiarse y sumarse. NEG Esta instrucción tiene la finalidad de cambiar de signo el número representado o sea que si tenemos el número 32 en hexa y le aplicamos NEG el resultado será el negativo del mismo. Ejemplo Escribo en OLLY NEG EAX y pongo en EAX el valor 32
  • 70. Al apretar F7 quedara en EAX el negativo de 32 veamos Allí vemos el resultado -50 en decimal como nos muestra la segunda columna corresponde a -32 en hexa. Allí esta si tipeamos en la comandbar que nos de el valor de -32 hexa en decimal, nos dice -50 y nos aclara que se escribe FFFFFFCE ya que no se puede escribir el signo en OLLY. Pues como vemos la instrucción NEG nos convierte el operando en su negativo. INSTRUCCIONES LOGICAS Provienen de realizar operaciones lógicas entre dos operandos pasados a binario bit a bit y guardando el resultado en el primer operando AND El resultado es 1 si los dos bits son 1, y 0 en cualquier otro caso. 1 and 1 = 1 1 and 0 = 0 0 and 1 = 0
  • 71. 0 and 0 = 0 Vemos un ejemplo en OLLYDBG AND EAX,ECX Pongamos ECX=0001200 y EAX=3500 Si lo hiciéramos a mano deberíamos pasar a binario ambos 1200 en binario seria 01001000000000 3500 en binario seria 11010100000000 Aplicándole la tablita de la operación AND bit a bit vemos que por ejemplo la ultima cifra Al hacer AND entre dos ceros el resultado seria cero, así hay que hacer bit a bit y nos daría 01000000000000 ya que el resultado es uno solo cuando los dos bits son 1 y eso ocurre solo en la columna resaltada. Si ejecutamos F7 en el OLLY vemos el resultado en ECX que es 1000 que pasado a binario es 01000000000000
  • 72. OR En esta instrucción realizamos el mismo proceso que la anterior solo que en vez de utilizar la tablita AND para hallar el resultado entre bits, lo hacemos con la tablita OR El resultado es 1 si uno o los dos operandos es 1, y 0 en cualquier otro caso. 1 or 1 = 1 1 or 0 = 1 0 or 1 = 1 0 or 0 = 0 XOR Aquí es similar solo que usamos la tablita de la función XOR para las operaciones entre bits El resultado es 1 si uno y sólo uno de los dos operandos es 1, y 0 en cualquier otro caso 1 xor 1 = 0 1 xor 0 = 1 0 xor 1 = 1 0 xor 0 = 0 NOT Simplemente invierte el valor del único operando de esta función not 1 = 0 not 0 = 1 Ejemplo: not 0110 = 1001 Si tenemos por ejemplo EAX=1200 que en binario es 1001000000000 convertimos los 0 en 1 y los 1 en 0 considerando que es un numero de 32 bits y que al inicio tiene ceros o sea seria llenado de ceros delante hasta completar los 32 bits. 00000000000000000001001000000000 Al hacerle NOT quedaría 11111111111111111110110111111111 que en la calculadora de Windows vemos que es FFFFEDFF en hexa
  • 73. En OLLY antes de apretar F7 pongo EAX a 1200 Apreto F7 Vemos que el resultado es el mismo Bueno aquí terminamos esta quinta parte veo que esto es un poco mas largo de lo que pensaba pero bueno vamos paso a paso, nos quedan ver las comparaciones, los saltos y los call y ret. Bueno paciencia que despacio se llega a ROMA Hasta la parte 6 Ricardo Narvaja 14 de noviembre de 2005
  • 74. INTRODUCCION AL CRACKING CON OLLYDBG PARTE 6 COMPARACIONES Y SALTOS CONDICIONALES En términos generales, las comparaciones entre dos operandos, y según el resultado de esa comparación la decisión si el programa saltara o no en un salto condicional posterior, suele ser lo primero que se menciona en cualquier tute básico que comienza desde cero de cracking. Sabemos que si el programa nos pide un serial para registrarnos, en algún momento deberá decidir si es correcto no y para ello deberá comparar y realizar uno o varios saltos y la dirección adonde saltará variará según si pusiste bien el serial o no. Ahora como funciona en profundidad la comparación y el salto es lo que veremos a continuación. Sabemos porque lo hemos visto ya en partes anteriores de esta introducción, que según el resultado una instrucción se activan o desactivan los flags, el caso mas conocido es el flag que se activa cuando el resultado de una instrucción es cero el FLAG Z y hemos visto diferentes formas de activar los flags según el resultado de una instrucción. CMP Esta es la instrucción mas conocida de comparación y lo que hace es comparar dos operandos, en realidad es una instrucción SUB, que no guarda el resultado de la resta en el primer operando, ambos operandos quedan igual, lo que cambian son los flags según el resultado. Como vimos si hacemos por ejemplo CMP EAX, ECX Siendo EAX y ECX iguales, se restan ambos, no se modifican, pero el resultado de la resta es cero lo que hace activar el flag Z, veamos el ejemplo en OLLYDBG. Allí escribí la instrucción y ahora modificare EAX y ECX para que sean iguales. A apretar F7 veo que EAX y ECX no modificaron su valor pero se activo el flag Z, al haber realizado una resta y ser su resultado CERO aunque no podamos ver el resultado ya que no lo guarda.
  • 75. En realidad no nos importa el resultado numérico de la resta en si, sino que de alguna forma podemos saber según los flags si EAX era igual a ECX, o si son desiguales, cual es mayor. Como comentario ya que aun no hemos llegado a los saltos condicionales, los tienen dos posibilidades, deciden si saltar o no saltar según el estado de los flags, el mas claro ejemplo y que trabajaría en conjunto con la comparación anterior es el salto JZ que salta si el FLAG Z esta activo o a UNO y no salta si esta inactivo o a CERO. De esta forma se logra que el programa tome una decisión, si fueran dos seriales que esta comparando, por ejemplo en EAX esta el serial que vos ingresaste para registrar un programa y en ECX esta el serial correcto, el programa podría decidir con un CMP que si son iguales se activa el flag Z, y el salto JZ al ver el flag activo, nos llevara a una zona para usuarios registrados, y si el serial que tipeaste y esta en EAX no es igual al de ECX que es el correcto, seguí intentando jeje, el flag Z sigue a CERO, y no salta manteniéndote en la zona de usuario no registrado. Ya veremos los ejemplos más concretos al estudiar los saltos condicionales. De la misma forma con el flag S o de signo podemos ver si en una comparación el primer operando era mayor que el segundo, o al revés. Miremos el ejemplo Repitamos el CMP EAX, ECX pero ahora pongamos EAX mayor que ECX Si apretamos F7
  • 76. Vemos que el FLAG Z es cero por lo cual ya sabemos que no son iguales, y a la vez el flag S es cero lo cual quiere decir que al hacer la resta EAX-ECX el resultado es positivo, lo cual significa que EAX es mayor que ECX. De la misma forma si repetimos la operación con EAX menor que ECX Y apretamos F7 Allí vemos que al dar la resta de EAX con ECX negativa ya que ECX es mayor, se activa el FLAG S que recordamos se activa con resultados negativos. Las diferentes posibilidades de comparación activaran los correspondientes flags y según lo que el programa necesite saltara o no de acuerdo a chequear la activación de uno o mas de dichos flags. También permite la comparación entre registros y posiciones de memoria utilizando DWORD, WORD y BYTE . Allí compararía EAX con el contenido de 405000 y como siempre la ventana de aclaraciones del OLLY nos da el valor de cada operando en mi caso Al apretar F7 en este ejemplo y EAX es menor que el contenido de 405000 que es 1000, dará un resultado negativo y activara el FLAG S.
  • 77. Existen en forma similar CMP AX,WORD PTR DS:[405000] Y CMP AL,BYTE PTR DS:[405000] En el caso de comparar 2 bytes o 1 byte del contenido de la memoria. TEST (Logical Compare) El principio de esta instrucción es, en cierto modo, el mismo de cmp, es decir, una operación entre dos valores que no se guarda, sino que puede modificar el estado de algunos flags (en este caso, SF, ZF y PF) que determinan si debe efectuarse el salto que también suele acompañar a esta instrucción. La diferencia está en que en este caso, en vez de tratarse de una resta, se trata de una operación AND. Esto nos dice nuestro amigo CAOS en su tute de ASM veremos ejemplos para aclarar la definición, generalmente el comando TEST lo veremos en este formato TEST EAX,EAX Ustedes dirán para que quiere testearse contra si mismo el valor de EAX o el registro que sea? Pues se usa esta instrucción, para saber si EAX en este caso es cero o no, y como funciona? Escribamos en OLLY TEST EAX,EAX La tablita de la operación AND era . El resultado es 1 si los dos operandos son 1, y 0 en cualquier otro caso. 1 and 1 = 1 1 and 0 = 0 0 and 1 = 0 0 and 0 = 0 Vemos que la única forma que el resultado sea cero es que ambos operandos sean cero (no interesan en este caso los casos de bytes diferentes pues EAX esta operando contra si mismo, por lo que ambos bytes siempre son iguales) pues si EAX en binario tiene algún bit que es 1, al hacer AND contra si mismo daría 1 y ya no podría ser cero el resultado. Pongamos EAX igual a CERO
  • 78. En el OLLYDBG eso sea realiza fácilmente haciendo CLICK DERECHO en el registro a modificar y eligiendo ZERO. Allí esta apreto F7 Vemos que se activo el flag Z o sea como sabíamos la operación AND entre dos valores que son cero es igual a cero y se activara. Si repito la operación con EAX diferente de cero Apreto F7
  • 79. Y el FLAG Z no se activa al ser el resultado diferente de cero. Si uso la calculadora puedo comprobar que 390 AND 390 da como resultado 390 En binario 390 es 1110010000 Como la operación AND si ambos operandos son CEROS dará como resultado cero y si son dos UNOS dará como resultado UNO, vemos que el resultado no cambiará o sea será 390 en hexadecimal, y no se activara el flag Z. Hay alguna instrucciones mas de comparación pero estas son las principales llego el momento de ver los saltos SALTOS Todos as instrucciones de salto tienen un solo operando que es la dirección adonde saltaría el programa, veamos los diferentes tipos aquí en la tabla y aclarémoslos. JMP
  • 80. Es el salto directo o incondicional, aquí no hay ninguna decisión SIEMPRE saltara a la dirección que nos muestra el operando por ejemplo veamos en OLLY Al ejecutar ese salto el programa ira a 401031 y seguirá ejecutándose desde allí. Tenemos un par de lindas configuraciones del OLLY para los saltos que les enseñare aquí, así son mas visibles los mismos. Si vamos a OPTIONS-DEBUGGING OPTIONS Y allí en la pestaña CPU Marcamos estas tres tildes Vemos que la información es mucho mayor ahora y mas visible
  • 81. Vemos que OLLYDBG ahora nos muestra con una flecha roja que va a saltar y además a adonde va a saltar, exactamente a 401031. Si ejecuto ahora con F7 Se realizo el salto y EIP es 401031 Ya que EIP apunta a la instrucción que se va a ejecutar a continuación, en este caso 401031. JE o JZ Ambos son el mismo tipo de salto condicional y pueden escribirse de las dos formas ya vimos que JZ saltara cuando el flag Z sea cero. Escribamos en OLLYDBG dos instrucciones una comparación y el salto así verificamos como funciona. Pongo EAX y ECX iguales
  • 82. Al ejecutar la comparación se realiza la resta y como ambos son iguales se activa el FLAG Z al ser el resultado CERO. La siguiente instrucciones es el salto condicional veamos OLLYDBG ya nos avisa la decisión y como el FLAG Z esta activado nos muestra en rojo que va a saltar, si la indicación estuviera en gris quiere decir que la decisión es no saltar, en este caso saltara, apreto F7.
  • 83. Allí vemos que salto y EIP ahora es 401031. Repitamos el ejemplo con EAX diferente de ECX Al apretar F7 en la primera instrucción como el resultado no es cero, el flag Z no se activa. Y vemos en OLLY Que como el JE salta si el flag Z es UNO, en este caso no saltara, y la flecha del salto esta gris, al apretar F7 nuevamente
  • 84. Vemos que no salto y siguió a continuación en 401004, esto que parece tan tonto es la base de la comparaciones y decisiones en todos los programas. Si repito el ejemplo anterior y llego al salto, nuevamente y no va a saltar Sabemos que no salta porque el flag Z esta a cero, ahora que ocurre si hago doble click en el flag Z y lo cambio a 1. Vemos que la flecha cambio a rojo y OLLYDBG saltara, independientemente de la comparación, manipulando directamente el flag, ya que la decisión se toma sobre el estado actual del mismo, si cambia el flag cambiara el salto. Los otros saltos los veremos rápidamente con un ejemplo cada uno JNE o JNZ Es el opuesto al salto anterior en este caso, salta si el flag Z no esta activo o sea si el resultado de la operación fue distinto de cero.
  • 85. Allí escribo la comparación y el JNZ Si EAX y ECX son iguales se activa el FLAG 0 al ser la diferencia CERO Y al revés que el JZ que saltaba al estar el FLAG Z activo este es el opuesto, salta cuando el FLAG Z es cero o esta inactivo. Se puede entender que si pongo EAX diferente de ECX, el resultado será diferente de cero y el flag Z quedara inactivo y allí si saltara. JS Como vemos en la tabla saltara si la comparación da un resultado negativo o sea si EAX en menor que ECX en el ejemplo anterior. Al apretar F7
  • 86. El FLAG S se pone a 1 y saltara al ser negativo, Allí vemos que la flecha roja nos indica que saltara, en el caso que EAX sea mayor que ECX el flag S no se activara al ser un resultado positivo y el salto JS no saltara. JNS Es el opuesto al anterior saltara cuando el FLAG S este a cero o sea cuando el resultado sea positivo, en el ejemplo anterior cuando EAX sea mayor que ECX. JP o JPE En esta caso el salto condicional JP saltara cuando el FLAG P este activo y esto ocurrirá como habíamos visto cuando el resultado de la comparación tenga paridad par o par cantidad de unos al verlo en binario. Ponemos EAX a 20 y ECX a 18 y apretamos F7
  • 87. Como la diferencia entre EAX y ECX es 2 y este pasado a binario es 10 que tiene 1 solo uno o sea una cantidad impar de unos, el flag P no se activa y el JPE no saltara. Ahora si cambio ECX a 17 y repito apreto F7 Vemos que al ser el resultado 3 que en binario es 11 y tiene un número par de unos, entonces allí si se activa el FLAG P y el JPE saltara. JNP o JNPE Es el opuesto del anterior o sea este salta cuando el flag P esta a cero o sea la paridad es impar, en el ejemplo anterior hubiera saltado la primera vez cuando el resultado era 2 y no hubiera saltado cuando el resultado era 3, al revés del JP. JO
  • 88. Este salta cuando hay overflow o capacidad excedida lo cual activa el flag O. Aquí cambiamos la comparación porque para activar el FLAG O hay que hacer OVERFLOW y esto es posible mediante una suma. Apreto F7 Y el JO saltara al haberse activado el FLAG O por OVERFLOW o capacidad excedida. JNO Es el opuesto al anterior este salta cuando el FLAG O esta a CERO o sea no hay OVERFLOW JB Salta si es mas bajo, veamos el ejemplo
  • 89. Vemos que EAX es mas bajo que ECX o sea que debería saltar, al apretar F7 El flag C se activa, ya que tiene que al hacer la diferencia que da un numero negativo, en el bit mas significativo o sea el primero habrá acarreo y eso activa el FLAG C, y según eso decide el JB en resumidas cuentas si EAX era menor que ECX. JNB Es el opuesto de JB saltara si el FLAG C es cero o sea no hay acarreo porque el resultado fue positivo, lo cual supone que EAX fue mayor que ECX y al revés que el anterior este saltara en ese caso. JBE Este salta si es mas bajo o igual o sea testea dos flags a la vez ve si el FLAG C esta activo en ese caso salta, y también verifica si el FLAG Z esta activo con el cual también salta, o sea si EAX es igual a ECX saltara y si es menor también. Ponemos como primer caso que EAX y ECX sean iguales
  • 90. Apreto F7 Al ver que el flag Z esta activo salta Si EAX es menor que ECX Apreto F7
  • 91. En este caso se activa el FLAG C al ser resultado negativo que usa un carry en el bit mas significativo, o sea salta cuando EAX es menor a ECX también En el ultimo caso que EAX es mayor a ECX repito el ejemplo apreto F7 Ambos flags Z y C están a cero por lo tanto no saltara O sea la conclusos es que JBE salta si EAX es mas bajo o igual que ECX en el ejemplo. JNBE Es el opuesto al anterior, salta si el flag Z y el FLAG C son cero ambos o sea solo en el ultimo ejemplo anterior cuando EAX es mayor que ECX, allí ambos flags están a cero y este JNBE saltara. JL en este caso JL salta si es menor, pero en diferente forma, veamos aquí mira si FLAG S es diferente a FLAG O y en ese caso salta Veamos en los ejemplos cuando se da esto si ambos EAX y ECX son positivos siendo EAX mayor que ECX
  • 92. Al apretar F7 no salta ya que EAX es mayor que ECX y el resultado es positivo lo que no activa el FLAG O ni el FLAG S. Si EAX es menor que ECX pero ambos son positivos repito el ejemplo Apreto F7 Y como S y O son diferentes salta o sea que salta cuando es menor si ambos son positivos, veamos otro caso. En este caso EAX es menor que ECX, ya que es un número negativo veamos que pasa Salta perfectamente porque es menor pero que pasa si usamos estos dos mismos valores con el otro salto que parece realizar el mismo trabajo el JB
  • 93. Al apretar F7 Vemos que el JB no salta quiere decir que JB compara ambos como si fueran positivos o SIN SIGNO mientras que si el salto debe considerar el signo de lo que compara se utiliza JL esa es la principal diferencia entre ambos. Aquí vemos en esta los saltos condicionales según queramos considerar el signo de lo que comparamos o no, Vemos que JA, JB JBE y JAE consideran ambos operandos positivos mientras que JG, JL, JLE y JGE consideran los operandos con signo, JE y JNE se comportan igual en ambos casos. Creo que con esto hemos aclarado el tema de los saltos condicionales y las comparaciones, en la práctica mas adelante veremos su utilización en los programas lo cual nos será mucho mas liviano que esta pesada tarea de revisarlos a casi todos. Queda en la ultima parte de ASM por suerte ver los calls y ret, y los modos de direccionamiento ya casi llegamos al fin de lo duro paciencia jeje..
  • 94. Hasta la parte 7 Ricardo Narvaja 16 de noviembre de 2005
  • 95. INTRODUCCION AL CRACKING CON OLLYDBG Parte 7 Los CALL y RET He dejado algunas instrucciones para esta ultima parte porque creo que a esta altura ya tienen claro algunas cosas, y es mejor explicar estas ultimas instrucciones ya teniendo una pequeña base, ahora explicaremos los CALL y RET. Esta instrucción aunque parezca su funcionamiento sencillo, muchos de los newbies no comprenden realmente su funcionamiento, por eso quería dedicarle un espacio importante e insistir en repasar toldo lo anterior, pero ademas mirar de entender muy bien el funcionamiento de los CALL y RET yo creo que es algo muy importante para el cracking. Carguemos nuevamente nuestro crackme de ejemplo el CRACKME DE CRUEHEAD en OLLYDBG, Para practicar hagamos click derecho en el listado desensamblado en cualquier línea y elijamos GO TO – EXPRESSION Y en la ventana que aparece tipeemos 401245 Nos llevara a dicha dirección en el listado desensamblado, donde hay un CALL para practicar.
  • 96. Allí vemos el CALL que elegí para practicar, para poder ejecutarlo hago CLICK DERECHO-NEW ORIGIN HERE con lo cual EIP apuntara a 401245 y dicha dirección será la próxima que se ejecutará. Allí vemos como cambiamos EIP Volvamos a nuestro CALL La instrucción CALL lo que hace es ir a ejecutar una subrutina o si quieren parte del programa cuya dirección esta dada por el valor del operando o sea en este caso del ejemplo: CALL 401362 significa que la próxima línea a ejecutarse será 401362 y cuando se termine de ejecutar la rutina que esta allí dentro, volverá a la instrucción siguiente a continuación del CALL que la llamo. En este ejemplo luego de ejecutarse el contenido del CALL 401362, volverá a 40124A y seguirá desde allí. Ahora hagamos unos ciertos movimientos con el OLLYDBG, que nos ayudan en los casos que estamos encima de un CALL como este. Si yo quiero mirar el contenido del CALL podría entrar al mismo con F7 y tracearlo por dentro, pero si quiero echar un vistazo a ver si el contenido me interesa para ser traceado o no, ya que también tengo como recuerdan la opción de tracear con la tecla F8, la cual en este caso ejecutara el CALL sin entrar al mismo y seguirá en 40124A sin ni siquiera enterarnos de lo que hizo el programa dentro del CALL.
  • 97. Entonces cada vez que llegamos a un CALL y estamos traceando un programa se plantea una disyuntiva, será importante para entrar a tracearlo con F7? O lo salteo con F8 porque es un call secundario que no hace nada que me importe? Bueno, lo que OLLYDBG nos permite hacer es mirar sin ejecutar, a ver que veo dentro del CALL y si me interesa. Para ello hago click derecho en el CALL y elijo FOLLOW. FOLLOW no ejecuta ninguna línea solo va a mostrarnos la próxima línea a ejecutarse, pero no cambia nada EIP seguirá en 401245, a la espera de nuestra decisión. Cuando entro a mirar veo la rutina interna que obviamente empieza en 401362 que era el operando del CALL y donde terminará, pues en el primer RET que vea en este caso OLLYDBG escribe los RET como RETN, pero es lo mismo dicha instrucción es la finalización de la rutina y la vuelta a 40124A a la instrucción siguiente del CALL que nos trajo aquí. Es muy importante entender esto, ahora que vimos como podemos mirar dentro sin ejecutar volvamos a la línea actual presionando la tecla - del teclado numérico o sea la tecla MENOS, esto siempre nos lleva al paso anterior sin ejecutar nada también. Pues estamos en el CALL Ahora si entraremos con F7, pero antes de entrar el CALL veamos el stack, esto es muy importante pues allí se almacenan los datos para que el programa sepa donde regresar cuando llega al RET.
  • 98. En mi maquina este es el stack, en la suya los valores pueden variar pero el mecanismo será similar. Apreto F7 ahora Allí entre en el CALL y estoy en 401362 pero a diferencia de la vez anterior que entre con FOLLOW ahora EIP cambio a 401362, lo cual quiere decir que estamos ejecutando esta rutina. Veamos que paso en el stack Allí en la imagen resalte el stack como estaba antes y veo que se agrego una nueva carta arriba o sea al entrar en un CALL el sistema automáticamente hace un PUSH con la dirección de retorno, o sea donde volverá al llegar al RET y salir de la rutina. Vemos que la línea tiene el valor 40124A que es como sabemos la dirección de retorno. Por si alguno lo olvido recordemos que es la dirección siguiente al CALL inicial, allí se ve. Bueno vemos que OLLY nos aclara aun mas el tema agregándonos información.
  • 99. Nos dice RETORNO A 40124A desde 401362 O sea OLLY aun no sabe donde estará el RET que nos devolverá, pero sabe que la rutina empieza en 401362 y lo marca como que aquí empieza y terminara en un RET y volverá a 40124A. Apretemos F7 una vez vemos que ejecuta un PUSH 0 lo cual pone un CERO en el stack y abajo del mismo queda el indicador para el RET de la dirección de retorno. El programa puede hacer mil operaciones dentro de la rutina hacer miles de PUSH, POPS lo que quiera, pero al llegar al RET deberá dejar arriba en el stack nuevamente el valor de la dirección de retorno, sigamos ejecutando con F8 para no entrar en los CALL y llegar al RET. Allí llegue al RET y veo que como dije el stack tiene arriba nuevamente el valor donde retornara. Como habíamos mencionado el RET es el final de la rutina y contrapartida de la instrucción CALL, si CALL nos trajo aquí, RET nos devolverá a la zona donde estábamos antes de entrar en esta rutina. Pero además RET quitara la dirección de retorno del stack que es un valor que al sistema ya no le interesa pues ya volvemos y luego la dirección ya no es útil más.
  • 100. Apreto F7 Y vuelvo a 40124A y el stack quedo como estaba antes de ejecutar el CALL en mi maquina en 12FFc4. Es de mencionar que si uno ejecuta un RET sin haber entrado en ningún call por ejemplo PUSH 401256 RET Lo que hará esto es poner en el primer lugar del stack el valor 401256, y como la siguiente instrucción es un RET, pues ella interpreta que el primer lugar del stack es una dirección de retorno de algún call anterior y aunque ello no haya ocurrido, al ejecutarlo nos llevara allí. Ahora reinicio el CRACKME DE CRUEHEAD Ahora haré otro ejemplo voy en el listado con GO TO – EXPRESSION a 401364 es una dirección que elegí para mostrar algo ya verán. Ahora no cambiare EIP ni nada si no que apretare F2 que es un BREAKPOINT los cuales ya explicaremos mas adelante en detalle, lo importante es que cuando el programa ejecute esa instrucción OLLYDBG parara allí. Allí esta puesto el BREAKPOINT ahora apreto F9 que es RUN para que el programa corra.
  • 101. Vemos que nos sale la ventana del crackme, si no la ven, pues búsquenla con ALT mas TAB entre los programas que están corriendo. Allí se ve, el programa no paso aun por nuestro BREAKPOINT, vayamos en dicha ventanita a HELP REGISTER Nos sale la ventana para poner un NOMBRE Y UN SERIAL Pongamos cualquiera
  • 102. Y apreto OK Nos sale una ventanita diciendo que no tuvimos suerte o sea que tipeamos el user y serial incorrecto (lo increíble seria que fuera el correcto jeje), y al aceptar dicha ventana para en nuestro BREAKPOINT. Si no les para prueben con el user y serial que puse yo. Allí estamos en el medio de la ejecución del programa pero algo de información tenemos Vemos allí unos cuantos RETURN TO …. Que el stack tiene almacenados allí, así que podemos pensar que el superior de todos, será donde volverá el programa al llegar a un RET ya que suponemos estamos dentro de un CALL (porque vemos que hay RETURN TO …… en el stack ) y al llegar a un RET ese RETURN quedara en la línea superior y volverá a 40124A . Como vemos también estamos en la misma rutina que analizamos antes cambiando el EIP, pero ahora dentro de la ejecución el programa, no suelta. Tratamos de llegar al RET apretando F8 como antes, en el call anterior al RET se para ya que nos debe mostrar algo que hace el CALL dentro que es una mensaje y que debemos aceptar para seguir.
  • 103. Presionamos ACEPTAR Y llegamos al RET y como supusimos el valor superior del stack es La diferencia entre la vez anterior y esta es que la vez anterior al cambiar EIP e ir directamente allí, ejecutamos el CALL solo aislado, no el resto del programa, ahora al poner un BREAKPOINT el programa se ejecuto normalmente, y al pasar por allí paro, y si apreto F9 seguirá corriendo como si nada. Además lo que quise mostrar es que a veces cuando estamos en el medio de la ejecución de un programa y paramos por algún motivo, la información del stack nos sirve para saber de donde fue llamado la rutina en que estamos y donde volverá, y si hay mas RETURN TO hacia abajo, también sabremos que son CALLS unos dentro de otros, o sea anidados, y que estamos dentro de un CALL que al llegar al primer RETURN TO, saldremos y al llegar al segundo pues saldremos de otro y así. Creo que esta claro, igual como es muy importante que entiendan esto aclararemos con otro ejemplo reiniciemos el OLLY y apretamos la barra espaciadora y escribamos como primera línea solo para entender esto CALL 401245
  • 104. Alli esta ahora podemos practicar hacer FOLLOW para la rutina por dentro Vemos que como modificamos el programa la rutina ahora empieza en 401245 y terminara en el RET de 401288 (que es un RETN10 un poco diferente a un RET común, pero no es eso el tema de esta explicación ya lo veremos mas adelante lo que quiero que vean es lo que pasa cuando entramos en un call como en este caso y dentro de la rutina entramos en un segundo CALL. Bueno ya hicimos FOLLOW y miramos ahora apretemos MENOS para volver y ahora si apretemos F7 para entrar ejecutando. Allí estamos y EIP apunta a 401245 que es la próxima instrucción a ejecutarse
  • 105. Y en el stack vemos que en el primer lugar esta el valor de retorno a la línea siguiente del call que escribimos a mano. Vemos que el valor esta, pero OLLYDBG no nos aclaro RETURN TO 401005, porque ocurre esto, es bueno entenderlo para saber como funciona OLLYDBG, como nosotros agregamos el CALL después del análisis inicial que el OLLYDBG había hecho, pues de esta forma, le hemos cambiado el caballo en el medio del río y lo hicimos ahogar jeje, por lo cual si queremos arreglarlo, debemos hacer en el listado en cualquier línea CLICK DERECHO- ANALICE CODE, con lo cual lo volverá a pensar después de los cambios que hemos introducido. Vemos que después de reanalizar el código Bueno nos dijo que volverá a MODULE ENTRY POINT + 5
  • 106. Dicho valor es 401000 que era el ENTRY POINT mas 5 =401005 Es muy importante esto porque muchas veces uno le dice a una persona que le pide consejo, fíjate los RETURN TO …… en el stack, pero resulta que uno mismo ha modificado cosas o el mismo programa se ha auto modificado al ejecutarse entonces el análisis inicial del OLLYDBG fallara en las aclaraciones y debemos actualizarlo al detenernos, o quitar el análisis como vimos si nos trae problemas en la parte 1. Bueno aclarado esto volvemos a donde estábamos Apreto F7 para entrar en el segundo CALL Vemos que arriba de donde guardo la dirección de retorno del primer call ahora guarda la segunda dirección de retorno de este, en este caso están consecutivos, pero podría haber valores numéricos intermedios productos de PUSH o operaciones diversas, lo importante es que el primer RETURN TO .. que hallamos de arriba hacia abajo es la dirección de retorno del ultimo CALL que entramos y la segunda que hallemos bajando será la dirección de retorno del call anterior que es el inicial que escribimos. Esta es la idea de calls anidados o uno dentro de otro, si yo por poner un BREAKPOINT o por algún motivo parara aquí en el medio de la ejecución del programa, aunque no haya venido traceando ni tuviera información de cómo se vino ejecutando el programa al ver el stack , puedo sacar como conclusión 1) CAI AQUÍ Y VEO UN RET un poco mas abajo, supongo que estaré dentro de un CALL para confirmarlo miro el stack 2) MIRO EL STACK
  • 107. Al mirarlo y buscar desde arriba del stack hacia abajo y hallar el primer RETURN TO se que el programa al llegar al RET volverá a 40124A. Y además de saber donde volverá se que estoy dentro de la ejecución del CALL ANTERIOR al punto de retorno, o sea que el programa llamo a la zona donde estoy desde 401245 usando un CALL que llama a la rutina de 401362. Y no solo se eso si no que se también que antes de llegar a ese CALL, había entrado antes en otro ya que hay otro RETURN TO …. Mas abajo Ese me informa que luego de ejecutar todo saldrá a 401005 y además se que el programa provenía del CALL de la línea anterior o sea Solo parando y mirando el stack ya determine que el programa provino de aquí que entro en ese call, luego fue a 401245, allí había otro call que me llevo a 401362 y de esa forma llegue a la zona donde estoy. Esa forma de pensar en el cracking es muy útil porque me hace reconstruir la forma que el programa fue llegando a cierto punto, que muchas veces no son dos calls uno dentro de otro si no que hay 30 calls uno dentro de otro y uno no puede tracearlos todos, así que si caigo en un punto, puedo hacer un análisis personal, y llegar a la conclusión de cómo el programa arribo al punto donde me encuentro en este momento. Espero que haya quedado claro, lo de los CALL Y RETS les sugiero practicarlos repasarlo, si tienen dudas preguntar porque esto es muy importante, iba a terminar a continuación con los métodos de
  • 108. direccionamientos y algunas instrucciones que quedaron en el tintero, pero preferiría que le den buena importancia a entender esto y en la próxima parte continuamos con los temas pendientes. Hasta la parte 8 Ricardo Narvaja 18 de noviembre de 2005 .
  • 109. INTRODUCCIÓN AL CRACKING EN OLLYDBG PARTE 8 Trataremos en esta parte de ver rápidamente algunas instrucciones importantes para el cracking que nos quedaron en el tintero para terminar con las mismas y empezar a crackear. INTRUCCIONES PARA LOOPS O CICLOS Ciertamente se pueden realizar ciclos en un programa con las instrucciones ya vistas o sea ejecutando varias instrucciones, poniendo un contador por ejemplo en ECX y al final una comparación de si es cero y un salto condicional que si no es cero vuelva a repetirse el ciclo se disminuya ECX y así se repetirá hasta que ECX sea cero seria algo así: Xor ECX,ECX Add ECX,15 Eso seria para inicializar el contador de nuestro loop que sera puesto a 15, aquí comienza el LOOP en si DEC ECX Para disminuir ECX cada vez que se ejecute el loop Luego la ejecución de las instrucciones que se deben repetir Y luego TEST ECX,ECX JNE salta hacia el inicio del LOOP O sea que al testear si ECX es cero la primera vez será 14 ya que lo decremente una vez y al no ser cero volverá a repetirse, y así se repetirá hasta que ECX sea cero donde saldrá fuera del LOOP y continuará con la instrucción siguiente. Escribámoslo en OLLYDBG Allí lo vemos la zona resaltada en amarillo es el loop en si, que se repetirá hasta que ECX sea cero, y entre 401008 y 40100C se deberían escribir las instrucciones que el programa desea repetir que aquí no interesan pues solo vemos el mecanismo de iteración del LOOP por eso dejamos NOPS alli. Si lo traceamos vemos que al apretar F7, ECX se pone a cero
  • 110. Apreto F7 nuevamente y le sumo 15 para establecer la cantidad de iteraciones en ECX. Luego apreto f7 hasta llegar al DEC ECX el cual al ejecutarlo pone ECX en 14 Luego llegamos hasta la comparación TEST ECX,ECX que sabemos que verifica si ECX es cero Al no ser cero no se activa el FLAG Z y el JNZ salta hacia 401007, donde vuelve a decrementar ECX quedando en 13, puedo tracear así haciendo los loops hasta llegar al momento que ECX vale CERO Vemos que al ejecutar la comparación con ECX igual a cero se activa el FLAG Z lo que hace que el JNZ no salte Recordemos que JNZ es el inverso de JZ que saltaba cuando se activaba el FLAG Z, el JNZ es el opuesto no salta cuando se activa el FLAG Z.
  • 111. Allí lo vemos la flecha en gris indica que no va a saltar, al apretar F7 nuevamente sale del loop a la instrucción siguiente Esa seria una forma sencilla de loop con las instrucciones ya vistas, aunque hay instrucciones especiales para eso. LOOP La instrucción LOOP nos ayuda a hacer algunas de las tareas que vimos en el ejemplo anterior, reemplazamos En donde estaba DEC ECX hacemos CLICK DERECHO – BINARY NOP con los cual NOPEARA esa instrucción, lo mismo donde estaban TEST ECX,ECX y JNZ 401007, todas esas instrucciones pueden ser reemplazadas por una sola que es la INSTRUCCIÓN LOOP la cual compara si ECX es cero, si no lo es salta al operando en este caso 401007 y además decrementa ECX . Hagamos en la primera línea, CLICK DERECHO-NEW ORIGIN HERE para ejecutar mi nuevo LOOP. Vemos que al apretar f7 pone ECX a cero luego le suma 15 igual que antes para marcar la cantidad de iteraciones o repeticiones. Ahora traceo y llego hasta la instrucción LOOP
  • 112. Vemos que igual que antes al no ser ECX igual a cero, salta a 401007, pero no solo compara si es cero y salta, también vemos que decrementa ECX ya que volvió siendo 14. Si traceamos hasta que llega a LOOP pero valiendo ECX igual a cero veremos como se repite el ciclo. En el momento que ECX vale cero ya no se repite mas el LOOP y al apretar F7 continua con la ejecución de la instrucción subsiguiente. Luego tenemos variaciones de la instrucción LOOP estas son LOOPZ salta o mantiene dentro del bucle mientras que el flag Z sea cero cada vez que se ejecute la instrucción LOOP, y la opuesta LOOPNZ mientras que el FLAG Z sea 1, en este tipo de ciclo hay ademas contador que se decrementa y se sale por alguna comparación anterior que ponga el FLAG Z a cero en el primer caso o a 1 en el segundo o porque ECX llegue a cero por cualquiera de ambos casos. INSTRUCCIONES PARA EL MANEJO DE CADENAS de BYTES Aquí vemos las mas importantes las aclaramos debajo MOVS Esta instrucción, lo que hace es mover el contenido de ESI al contenido de EDI, realmente no necesita ningún parámetro, pero al escribir en OLLY la instrucción MOVS y apretar ASSEMBLE, la completa (innecesariamente) al ensamblar y queda como