Anda di halaman 1dari 246

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 41

Continuaremos con el dsempacado del pelock que tenemos pendiente, ahora trabajaremos con la
IAT para lo cual veremos si existe algun salto magico o similar.

Para ello lleguemos nuevamente hasta el oep.

Bueno ahi llegamos al falso OEP, busquemos llamadas a las apis, miremos con click derecho
SEARCH FOR- ALL INTERMODULAR CALLS.

Alli vemos unas cuantas elijamos una y hagamos doble click en ella para verla en el listado.
Esto quiere decir que el call a la api toma valores de 460d38 que es una entrada de la IAT,
miremosla en el DUMP.

Alli se ve la IAT y alli veo todas entradas correctas subamos a buscar el inicio de la IAT.

Alli vemos el inicio de la IAT en 460818 ya que mas arriba si marco cualquier entrada y hago FIND
REFERENCES no hay referencias, ni van a ningun seccion code de dlls, lamentablemente toda la
IAT esta correcta por lo cual parece que no necesitaremos buscar el salto magico, (buaa con lo que
habia preparado el script de la parte anterior, pero bueno ya habra otras ocasiones), busquemos el
final de la IAT.

Alli tenemos el final de la IAT


hasta la parte grisada no hay problema hay referencias, la duda esta en la entrada de 460f24, para la
cual no hay referencias, sera una entrada de la IAT? Hasta donde tengo marcado con gris son
entradas que van a la seccion code de ole32.dll

Ahora vemos que haciendo click derecho en algunas de las entradas que van a esa dll, tampoco hay
referencias que ocurre aquí.

Si volvemos a mirar el OEP vemos un JMP raro que en mi maquina salta a una seccion en Axxxxx
que no pertenece a las secciones del exe (en su maquina puede estar en otra direccion), si miramos
el mapa de memoria.
Vemos que el programa salta a esa seccion y que el programa original arrancado desde el OEP no
puede saltar a una seccion afuera del exe sin haberla creado antes con VirtualAlloc o similares, por
lo cual concluimos que esa seccion fue creada por el packer y no es parte del codigo original del
programa asi como los JMPS que saltan a ella, como por ejemplo el que esta en el falso OEP y hay
muchos mas.

Por lo tanto es posible que en esa seccion el packer haya transladado algunos calls y jmps que
toman valores de la IAT y ya que el OLLYDBG si lo tenemos configurado asi.

Busca solo en la seccion que esta visible en el listado en ese momento, pues, como la seccion creada
por el packer no esta visible en el listado, no buscara alli.

Probemos buscar las referencias en otras secciones.


Alli tenemos una de las secciones creadas por el packer vemos como mi teoria funciona, no
hallamos referencias, porque los calls estan transladados a otras secciones (por eso yo insisto que
no hay que usar solo un metodo, en este caso, para ver si una entrada es de la iat o no, necesitamos
o bien buscar en las secciones creadas por el packer, o bien mirar si van las entradas a la seccion
code de una dll en el mapa de memoria y listo)

Pero bueno ahora tenemos visible una de las secciones creadas por el packer busquemos la
referencia en esta.

Nada, pero a no desanimar que hay mas secciones creadas por el packer, pasemos a ver la siguiente.
Ahora busuqemos referencias.

Nada pero como hay unas cuantas secciones y sabemos que un call que lee valores de la entrada
460f24 sera

CALL [460f24]

y los bytes del comando seran

FF 15 24 0f 46 00

por ejemplo si vemos este otro call a una api

Vemos que el la secuencia de bytes del call sera FF 15 y a continuacion los bytes de la direccion de
la entrada al reves, asi que podemos hacer un search de esos bytes por toda la memoria y asi
podemos buscar si hay una referencia en alguna parte sin tener que cambiar de seccion en seccion.
Vamos al mapa de memoria y alli hacemos click derecho

Y escribimos en laparte de HEX la secuencia de bytes que queremos hallar y apretamos OK y no


salen resultados grr, pero como somos persistentes y por supuesto hay muchas formas de llamar a
una api que no son call indirectos le quitaremos el FF 15 y buscaremos solo la direccion de
memoria.
Alli encontro algo y justo en una de las seciones creadas por el packer, vayamos al listado a ver esta
zona.

Alli hallamos la bendita referencia, claro nosotros probamos buscar con FF 15 que es un call
indirecto y no probamos con FF 25 que es un JMP indirecto, pero bueno, buscando de esta ultima
forma nos sale las referencias para cualquier comando que haya para llamar a la api.

Por lo tanto quiere decir que esa es una entrada de la IAT.


Y alli termnina la IAT ya que mas abajo antes de ponerme a buscar referencias ya veo que no hay
valores que vayan a la seccion code de ninguna dll con lo cual ya directamente no son entradas de la
IAT, la cual termina en 460f28.

Bueno los datos de la IAT son

LARGO=FINAL -INICIO= 460f28 - 460818= 710

Asi que poniendo en limpio

OEP=271B0
RVA o INICIO=60818
SIZE O LARGO=710

Ahora vemos que la IAT esta toda correcta asi que llegaremos nuevamente al falso oep, le
agregaremos los stolen bytes y dumpearemos.

Aquí llego al falso OEP.

Los stolen bytes eran

55 8B EC 6A FF 68 60 0E 45 00 68 C8 92 42 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 C4
A8 53 56 57 89 65 E8

Los pego en el dumpeado a partir de 4271b0 como habiamos visto en la parte 39.
Ahora dumpeare cambiando el OEP a 4271b0

Alli camble el OEP para que se corrija y le quito la tilde en REBUILD IMPORTS y apreto dump
para dumpear.
Alli lo guardamos como dumpeado pelock, ahora podemos repararle la IAT con este mismo que
tenemos detenido en el OEP ya que la misma estaba correcta, asi que abro el IMP REC.

Le colocamos los datos de la IAT que averiguamos y apretamos GET IMPORTS.

Vemos que dice que NO, pero si recordabamos no hay entradas redireccionadas el problema es que
el packer cambio los ceros que separan las diferentes entradas de cada dll por basura, si miramos.

Alli se ve claro en vez de haber ceros entre las diferentes entradas de cada dll, hay basura, esto el
IMP REC lo arregla facilmente, apretemos SHOW INVALID.
Ahi corroboramos lo que deciamos estan las entradas de advapi32.dll y la separacion con las de
comctl32.dll es basura, asi que como tenemos todas esas basuras marcadas al haber apretado
SHOW INVALID, hacemos click deerecho CUT THUNKS y anulara todas esas entradas.

Como vemos al anular las entradas basura en IMP REC ya no las toma en cuenta y la tabla se
arregla, quedando esas entradas basura sin efecto.

Ahora apreto FIX DUMP para arreglar el dumpeado.

Y alli creo el dumpeado pelock_.exe con la IAT reparada, , y ahora si corro el archivo reparado da
error que ocurre, abramoslo en OLLYDBG.sin cerrar el otro que tengo detenido en el OEP aun.

Como me da un error de formato lo paso en el LORDPE en la opcion REBUILDPE para que repare
el header, y ahora si podemos verlo en OLLYDBG correctamente.
Alli lo vemos parado en su EP en forma correcta miremos la IAT.

Alli se ve la IAT correctamente reparada por el IMP REC, vemos que el mismo reemplazo los
valores basura por ceros para que la separacion quede perfecta entre las entradas de las diferentes
dlls, sin embargo al correrlo aquí en OLLYDBG da error que ocurre.

Pues muy facil aquí viene el proximo punto que debemos estudiar, luego de reparar un dumpeado,
la IAT y arreglar los stolen bytes si tiene, aun nos queda un truco mas que tienen muchos packers el
ANTIDUMP.

Hay muchos tipos de antidump algunos son simplemente un chequeo de si el programa esta
dumpeado, chequeando la imagesize para ver el largo, o la cantidad de secciones, para ver si el IMP
REC, agrego la seccion que siempre coloca para reparar la IAT, pero en este caso, el antidump son
varias secciones que el packer creo en tiempo de ejecucion y que desvia ciertas partes del programa
alli, y al dumpear no tenemos dichas secciones, por lo cual el dumpeado no corre, lo vemos
claramente en el EP.
El programa comenzara a ejecutarse pero al llegar al JMP dara error traceemos hasta alli.

Vemos que si apreto F7 salta a una seccion inexistente.

Y no puede continuar mas si miro el original, veo que el JMP si nos lleva a una zona que creo el
packer en tiempo de ejecucion.

Hago click derecho-FOLLOW y me muestra donde saltara el JMP.


Alli vemos que ejecuta un CALL a una api y luego vuelve al codigo, hay muchas formas de reparar
esto, pero la mas sencilla es agregarle al dumpeado la seccion que le falta y ubicarla en la misma
posicion, como se hace esto, pues vamos a ver.

Miremos en el original la seccion faltante, primero le agregaremos esta que es la que nos da error al
inicio si llega a faltar alguna mas la agregaremos despues.

Necesitamos DUMPEAR solo la seccion que nos falta, para ello utilizaremos el PUPE que es una
muy buena herramienta para dumpear partes de procesos o secciones sueltas entre muchos usos, asi
que buscamos el pupe que estara adjunto al tutorial.

Cerremos el OLLYDBG con el dumpeado y dejamos el original que esta detenido en el falso OEP y
lo abrimos en el PUPE.

Hacemos click derecho- CAJA DE HERRAMIENTAS


Alli esta abierto el proceso ahora vayamos el mapa de memoria para dumpear la seccion faltante,
vamos a MAPA.

Recordamos que la seccion faltante empezaba en A80000 asi que la buscamos en el mapa del pupe.

Alli esta apretamos VOLCAR y la guardo con el nombre seccion.


Ahora abro el PE EDITOR y la agregare al dumpeado.

Busco el dumpeado reparado y lo abro en el PE EDITOR.

Apreto sections.

Alli vemos las secciones del dumpeado que son las mismas del original, mas la seccion mackt que
agrego el IMP REC para arreglar la IAT, pues bien agreguemosle la seccion faltante al final.

Hago click derecho y apreto COPY A SECTION FROM HD TO EOF (End of file)
Ahora solo nos queda cambiarle el VIRTUAL OFFSET a 0A80000 para que arranque alli ya que es
la direccion en la que arrancara.

Ahora debo cambiar la direccion del Virtual Offset a 0a80000 restandole 400000 quedaria.

680000 seria la direccion del virtual offset de la nueva seccion.


Ahora le hacemos una pasada para que repare el header el LORDPE nuevamente con la opcion
REBUILD PE.

Lo ejecutamos y vemos que funciona si lo abrimos en OLLYDBG.


Veamos el mapa de memoria

Vemos que el LORDPE para hacerlo al dumpeado funcional agrando la seccion anterior para
hacerlas contiguas con la que agregue, y luego viene la seccion que le faltaba que va desde 0a80000
en adelante y que tiene el codigo que dumpeamos con el PUPE.

Si miramos el salto vemos que ahora tenemos alli el codigo faltante.


Si la imagen quedo muy grande y se agrando mucho el archivo se puede parchear todo lo que
necesitamos y luego empacarlo con UPX que lo dejara pequeño y funcional y podremos
desempacarlo cuando querramos ya el GUIPEX tiene la opcion de empacar y desempacar asi que lo
tenemos bien dominado, aunque aquí no es necesario ya que el dumpeado, reparado y con la
seccion agregada y la memoria intermedia allocada quedo en menos de 500k.

Otra opcion para los que quieren estudiar otra forma de reparar el antidump, es agregar la o las
seccion faltante a continuacion de la ultima para que no se agrande mucho el exe, y luego cambiar
el oep en el dumpeado y hacer un injerto para ubicarla en su posicion creandola con VirtualAlloc y
copiando los bytes que agregamos alli, este metodo esta muy bien explicado por marciano en el
ultimo concurso de crackslatinos si alguien quiere mirarlo se los recomiendo pues cuanto mas
metodos conozcamos mejor, el link es.

http://www.ricnar456.dyndns.org/CRACKING/NUEVO%20CURSO/CONCURSOS%20Y%20CO
LABORACIONES/CONCURSOS/CONCURSOS%202004-
2005/CONCURSO%2078/PELock%20v1.06%20(All%20protections)%20-
%20por%20marciano.rar

user y pass:hola

En dicho unpackme de pelock que es parecido al que yo hice, la tabla esta redireccionada que era lo
que yo queria tambien reparar con el script, pero mi version no tiene la IAT redireccionada por lo
cual aplicaremos el script en una futura ocasión ya que habra miles de packers que lo necesiten.

Alli marciano utiliza el otro metodo que es hacer un injerto que cargue la seccion faltante en vez de
cambiar el Virtual Offset, muchas veces yo he utilizado ese metodo y es muy bueno, aunque si son
muchas las seccion faltantes es un poco cansador ya que hay que agregar una a una, con el metodo
de agregarlo con el lordpe nos queda habilitada toda la seccion de memoria entre la ultima seccion y
la seccion faltante.

De esta forma con el metodo del PeEditor conviene agregar siempre primero la seccion mas lejana,
ya que de esta forma, al reparar con el LORDPE, toda la memoria entre la ultima seccion y el inicio
de la seccion faltante quedara allocada sin problemas y podremos copiar del original detenido en el
OEP y pegar los bytes en el dumpeado y luego guardar los cambios en este ultimo de cualquier
seccion intermedia faltante.

Creo que es claro el ejemplo de que es lo que ocurre al agregar la seccion mas lejana, si esta empeza
en 0a80000 como vemos en la imagen de abajo del mapa de memoria del original, el lordpe agranda
la seccion anterior el dumpeado para que termine justo antes de 0a80000. Lo cual si nos falta alguna
seccion mas antes de a80000 como las que tenemos en rosado, la podemos copiar y pegar
facilmente y guardar los cambios.
MAPA DE MEMORIA DEL ORIGINAL

MAPA DE MEMORIA DEL DUMPEADO

Alli se ve que cualquier seccion del original anterior a A80000 existe en el dumpeado y esta
allocada ya que LORDPE agrando la seccion mackt, hasta hacerla contigua a la que agregamos, con
los cual abarcamos en forma continua y tenemos allocada toda la memoria desde 401000 hasta
A80000 + 3c0000 (largo de la ultima seccion)= 0E40000

O sea cualquier seccion que vaya entre 401000 y E40000 ya la tenemos allocada en el dumpeado si
necesitamos agregar bytes solo copiando y pegando del original detenido en el OEP al dumpeado y
guardando los cambios ya lo tendremos corriendo.

Veremos ejemplos usando ambos metodos, ya que ambos son muy buenos, asi que ahora tienen dos
tutes para leer, este y el de marciano, y practiquen ambos, porque hay veces que es mejor usar uno y
en otras es mejor usar el otro según las circunstancias.

Hasta la parte 42
Ricardo Narvaja
13/04/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 42

Bueno iremos introduciéndonos lentamente en packers mas difíciles y verán que los métodos
que utilizaremos son muy variables según el caso, por lo cual hay que tener la mochila bien
llena de trucos y practicar cada vez mas, el que nos ocupa ahora es el ACPROTECT 1.09 f el
unpackme con todas las protecciones habilitadas.
Dicho unpackme tiene un poco de todo, por lo cual iremos despacio y analizando cada parte
de la protección en varias entregas, no nos alcanzara con una sola parte para poder ir despacio
y claramente.
El unpackme esta adjunto a este tutorial, así que no hay problema, abramoslo en nuestro
OLLYDBG parcheado y con los plugins para ocultarlo.

Allí esta abierto en OLLYDBG, y ya que tiene de tiene de todas las protecciones,
chequeemos si corre en OLLYDBG, ya que si no lo hace debemos antes que nada ver como
solucionar eso.

Pues aquí en mi parcheado4 ,que adjunte en la parte anterior,con todas las excepciones
marcadas y usando el plugin HideOD 0.12 con la configuración que vemos abajo, no tiene
ningún problema y corre perfectamente, recuerdo que este packer verificaba mediante las apis
Process32Next cual era el proceso que lo había abierto y si descubría que no se habia abierto
por medio de una ejecución de doble click, o sea si lo había cargado un loader o un debugger,
no corría, pero el plugin HideOD, trae protección contra ese truco, por lo cual el antidebugger
del mismo queda completamente anulado sin ningun dolor de cabeza.
Bueno así que no debemos preocuparnos por eso, por lo cual nos concentraremos en llegar al
OEP.

De los varios métodos que vimos tanto usar el OLLYDBG para hallar OEPs, como utilizar el
buscador de OEPs incorporado que trae el OLLYDBG va perfecto, así que vamos a la
pestaña SFX, y ponemos la tilde en TRACE REAL ENTRY BLOCKWISE y aceptamos y
reiniciamos el OLLYDBG el cual luego de un rato parara aquí.

Ahora la cuestión es, es este el OEP real o tiene stolen bytes.

Miremos un poco el stack en este momento.

Si quitamos la tilde de buscar el OEP y reiniciamos

Vemos que el stack cuando esta detenido en el OEP, tiene dos valores mas de los que tenia
cuando arranca en el inicio, y salvo raros casos eso es un indicio de que hay stolen bytes, así
que nos prepararemos para hallarlos.

Pero antes debemos corregir el script para evitar que nos anulen los Hardware Breakpoints
que les enseñe en las partes anteriores ya que tiene un pequeño bug y lo necesitaremos en este
y en muchos packers mas.

Aquí lo podemos probar ya que si ahora queremos parar en el OEP que ya conocemos y
ponemos un HBP ON EXECUTION en el, vemos que no para ya que el programa lo
deshabilita, inclusive usando el script que les di, tampoco para, ya que este tiene un bug.
Antes que nada explicare donde estaba el error, para que se entienda como quedara el script y
porque hubo que modificarlo.

Arranco nuevamente el unpackme en el OLLYDBG, y le coloco los dos BP tanto en


KiUserExceptionDispatcher como en el CALL que nos lleva a ZwContinue como se ve en la
imagen.

Ahora colocare un Hardware BP on execution en la dirección del OEP, para probar si lo borra
o no, podría ser cualquier otra dirección, pero como sabemos que por allí pasara seguro y
llegara después de haber hecho todas las trapisondas del packer, pues que mejor que usar esa
dirección para probar el script.

Allí en el inicio, hago GOTO EXPRESSION y coloco la dirección del OEP que era 4271B5
Allí esta, le colocaremos el HBP ON EXECUTION.

Marco la primera linea y le coloco el HARDWARE BPX ON EXECUTION.

Ahora doy RUN.


Para en el BP y ahora miro el stack

Cuando para en KiUserExceptionDispatcher el puntero al context esta en el segundo lugar del


stack, miremos el CONTEXT en el dump.
Por supuesto no explicare todos los valores de la estructura CONTEXT, pero si los que
utilizaremos por ahora.

En los registros, cambio la vista para ver los DEBUG REGISTERS, si no aparece la opción
para cambiar es porque ya esta en la vista correcta.
Esos son los famosos DEBUG REGISTERS van desde Dr0 a dr7 , los correspondientes a los
HBP son Dr0, Dr1, Dr2 y Dr3.

Cuando el programa para en un BP, en ese momento los DEBUG REGISTERS del
OLLYDBG se actualizan con los valores de los HARDWARE BPX que estén vigentes en ese
momento, como vemos allí, paro en un BP y nos muestra los HBP actuales, en Dr0 esta
4271B5 que es el valor del hardware BPX que colocamos, Dr4 y Dr5 no se utilizan, el Dr6 no
nos interesa por ahora y el Dr7 indicara el tipo de hardware bpx que esta colocado segun una
tablita que veremos mas adelante, lo importante es que vemos que Dr0 tiene nuestro
HARDWARE BPX, ahora miremos el CONTEXT.

Ahí vemos la posición en el context de los registros Dr0 a Dr3, en amarillo esta la dirección
4271b5 que corresponde al HBP que colocamos y que esta activo, los otros tres en rosado
están a cero pues solo colocamos un HBP los otros están vacíos.

O sea cuando el programa llega al manejador de excepciones como dijimos, pondrá a cero
estos valores del CONTEXT, si nos fijamos, damos RUN para que llegue al 2do BP.
Vemos como al pasar por el manejador de excepciones puso a cero Dr0 y el error mio fue en
el script, volver a restaurarlo aquí, ya que si recuerdan al llegar a este 2do BP, el script iba a
restaurarlos, pero he aquí el error ya que lo que borro Dr0 es solo la preparación ya que
coloca el CONTEXT en la forma que QUIERE que quede, la verdadera actualización de los
HBP ocurre al salir de ZwContinue y entrar a RING0, antes de volver al programa, o sea que
por mas que yo aquí vuelva a colocar los HBP en OLLYDBG, no sirve, pues estando
preparados a cero en el CONTEXT, al salir de ZwContinue lo que hará sera borrarlos sin
mas.
Entonces aquí hay dos posibilidades, o bien cuando para el primer BP guardar los valores que
leo en el CONTEXT de los DEBUG REGISTERS y cuando llega al 2do BP, volverlos a
copiar al CONTEXT evitando lo que ha hecho de ponerlos a cero, poniendo en Dr0..Dr3, los
valores que tenían, los cuales actualizara normalmente al volver al programa.
Otra opción es hallar en el CONTEXT la dirección de retorno al programa, poner un BP allí,
y ahí si cuando para, restaurar los HBP ya que ya fueron borrados y ya volvió al programa,
así que es como ponerlos nuevamente, y luego borrar el BP de la dirección de retorno.

Esta segunda opción me pareció mas breve, pero donde esta ubicada en el CONTEXT la
DIRECCION DE RETORNO al programa?
Si a la dirección de inicio del CONTEXT le sumo 0B8 obtengo el puntero a la DIRECCION
DE RETORNO, en este caso en mi maquina.

12FC8c + 0b8 = 12FD44

O sea que 12FD44 en mi maquina apunta a la dirección de retorno al programa, si en el script


coloco un BP allí, cuando pare ya habrá vuelto al programa, luego de borrar definitivamente
los HBP y podre volverlos a colocar, veamos como quedo el script.

----------------------------------------------------------------------------------------------------------------
------------

var aux
inicio:

bphws 4271b5, "x"

trabajo:

eob pirulo
run

pirulo:
log eip
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
cmp eip,aux
je restaurar2
jmp final

quitar:
bphwc 4271b5
jmp trabajo

restaurar:
mov aux,esp
mov aux,[aux]
add aux,0b8
mov aux,[aux]
log aux
bp aux
jmp inicio

restaurar2:
bc aux
jmp inicio

final:
MSGYN "Continuar?"
cmp $RESULT,1
je inicio
ret

----------------------------------------------------------------------------------------------------------------
-------------

Estrictamente es el mismo script que antes veremos que cambia, al inicio

var aux

var es el comando para declarar una variable, declaro la variable aux, que me serviré de
auxiliar para guardar y calcular la dirección de retorno al programa desde la excepción.

restaurar:
mov aux,esp
mov aux,[aux]
add aux,0b8
mov aux,[aux]
log aux
bp aux
jmp inicio

Allí vemos la parte donde antes se restauraban los HBPs, ahora paso a aux, el valor de ESP.

mov aux,[aux]
Lo que hace es, ya que aux apunta a ESP, lo que necesitamos es el contenido de aux ya que
en el momento que para en el CALL, el contenido de ESP apunta al inicio de la estructura
context, o sea que luego de esta sentencia, aux queda con la dirección de inicio del context en
mi caso 12fc8c, luego le sumamos 0b8 con lo cual obtendremos 12fd44 o en sus maquinas el
puntero a la dirección de retorno y finalmente

mov aux,[aux]

Mueve a aux su propio contenido, quedando la dirección de retorno finalmente en aux y en la


linea siguiente Bp aux, coloca el Bp en la dirección de retorno al volver de la excepción y
luego vuelve a correr el programa y finalmente

pirulo:
log eip
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
cmp eip,aux
je restaurar2

al evaluar las excepciones ve si se produce alguna en la dirección de retorno con lo cual


sabemos que esta en el punto de retorno al programa.

restaurar2:
bc aux
jmp inicio

Por lo tanto al haber vuelto ya al programa, con el comando BC borra el breakpoint que
colocamos en la dirección de retorno y luego vuelve a inicio, donde vuelve a colocar los
HBP borrados y a dar RUN nuevamente con todo restaurado.

Bueno ya vimos los cambios realizados no son gran cosa, veamos ahora si funciona,
reiniciemos el programa.

Editamos el script para que ponga el HBP en la dirección del OEP


Allí editamos la dirección del HBP en el script que queremos que no nos borre, ponemos los
dos BPs a mano necesarios para su funcionamiento, borramos todos los HBP anteriores que
habia.

Corremos el script, no olvidemos de poner los dos Bps y poner todas las tildes en exceptions.
Allí nos avisa que se disparo nuestro HBP, le damos a que no continúe apretando NO.

Y evitamos que nos borre el HBP que colocamos y estamos detenidos en el OEP usando
HBPs.

Es muy importante en estos nuevos packers tener la forma de evitar el borrado de los HBP, y
ya lo hemos conseguido ya que para cualquier salto mágico o HBP que necesitamos colocar,
tenemos mas armas contra ellos ya que los podremos usar.

Ahora ya que podemos manejar perfectamente los HBP pasaremos a los stolen bytes.

Veamos si podemos llegar hasta la ultima exceptions y tracear desde allí.


En el LOG veo que esa es la ultima excepción antes de llegar al OEP, así que como veo que
es una ACCESS VIOLATION WHEN READING, quitare esa tilde para que pare en dicha
exceptions.

deshabilitare los Bps que coloque para usar el script.


Y ahora reinicio y doy RUN

Allí para en la ultima exceptions, pongo un BPM ON ACCESS en la sección que esta
ejecutándose, para que pare seguramente en el manejador de excepciones.

Paso la excepción con SHIFT +f9

Ahora traceo con f7 estas lineas del manejador de excepciones llegando al RET y al apretar
RUN volvemos al programa en

00471090 40 INC EAX


Ahora si ya pasada la excepción, pongo el BP en el OEP ya que esta ya desempacado allá y
me servirá para que pare cuando termine de tracear.

y desde 471090, iniciemos el traceo y vemos que tarda bastante ya que no saltea nada y pasa
por todas las instrucciones una a una.

Allí paro al fin en el OEP así que puedo mirar el listado de la fila txt.

00485EAE Main JL SHORT 00485ECA


00485ECA Main POPAD ; EAX=00000000, ECX=0012FFB0,
EDX=7C91EB94, EBX=7FFDF000, ESI=FFFFFFFF
00485ECB Main JMP SHORT 00485ECE
00485ECE Main JMP DWORD PTR DS:[485ED4]
Breakpoint at UnPackMe.004271B5

allí están las ultimas lineas del txt y si busco de allí hacia arriba PUSH EBP, que es
generalmente la primera instrucción de un programa.
00485AF3 Main PUSH EBP
00485AF4 Main MOV EBP,ESP ; EBP=0012FFC0
00485AF6 Main PUSH -1
00485AF8 Main NOP
00485AF9 Main PUSHAD
00485AFA Main PUSHAD
00485AFB Main CALL 00485B00
00485B00 Main POP ESI ; ESI=00485B00
00485B01 Main SUB ESI,6 ; ESI=00485AFA
00485B04 Main MOV ECX,35 ; ECX=00000035
00485B09 Main SUB ESI,ECX ; ESI=00485AC5
00485B0B Main MOV EDX,E3D6D5FD ; EDX=E3D6D5FD
00485B10 Main SHR ECX,2 ; ECX=0000000D
00485B13 Main SUB ECX,2 ; ECX=0000000B
00485B16 Main CMP ECX,0

Allí vemos los stolen bytes y luego empieza a hacer pavadas pero antes de hacerlas guarda
con PUSHAD el valor correcto de los registros que recuperara con POPAD justo antes de
saltar al falso OEP.

00485ECA Main POPAD ; EAX=00000000, ECX=0012FFB0,


EDX=7C91EB94, EBX=7FFDF000, ESI=FFFFFFFF
00485ECB Main JMP SHORT 00485ECE
00485ECE Main JMP DWORD PTR DS:[485ED4]
Breakpoint at UnPackMe.004271B5

Por supuesto vemos que los stolen bytes coinciden con los valores que nos sobraban en el
stack

Además el otro registro diferente al inicio es casualmente es EBP que varía al hacer el mov
ebp,esp

00485AF3 Main PUSH EBP


00485AF4 Main MOV EBP,ESP ; EBP=0012FFC0
00485AF6 Main PUSH -1

Vemos que el listado del txt nos muestra que EBP tomo el valor 12FFc0, que es el mismo
valor que tiene al llegar al falso OEP, todo lo que viene a continuación son solo volteretas
para despistar y podrían no existir perfectamente, ya vemos que luego de tanta vuelta, EBP
vuelve a valer 12ffc0, lo que demuestra que esos eran los stolen bytes correctos y todo lo
intermedio es pura cascara.

Bueno con eso obtuvimos los famosos stolen bytes, hicimos funcionar el script que evita que
nos borren los HBP y creo que por esta parte es suficiente seguiremos en la parte 43.

Hasta la parte 43
Ricardo Narvaja
miércoles, abril 26, 2006
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 43

En la parte anterior nos concentramos en reparar los stolen bytes ahora vamos por la IAT,
abramos nuevamente el unpackme en OLLYDBG y lleguemos al falso OEP con el script.

Alli estamos en el inicio del programa, ahora como tenemos el script para llegar hasta el OEP
que nos quedo de la parte anterior colocamos los dos Bps necesarios y lo usamos.
Y ahi estamos en el OEP mas adelante veremos como mejorar el script para que
automaticamente me coloque los dos Bps y me pregunte por la direccion del HBP, asi no hay
que estar editandolo, pero por ahora nos sirve.

Busquemos una llamada a una api, podemos ver haciendo SEARCH FOR
INTERMODULARS CALLS que es lo que vemos alli.
Vemos unas cuantos CALLs a apis que toman valores de la IAT y vemos alguna entradas
buenas, ya que figura alli el nombre de la api, la mayoria vemos que estan redireccionadas y
no muestran ningun nombre, tomemos la primera de las malas o redireccionadas y hagamos
doble click en ella para ir al listado.
Alli vemos el CALL y que toma valores de 460e80 la cual es una entrada de la IAT, miremos
la IAT en el dump.

Alli vemos un monton de entradas que en este caso estan redireccionadas no a una seccion
creada por el packer fuera del exe, si no a la misma seccion donde se ejecuto el packer,
veamos en el mapa de memoria.

Alli esta esa seccion, si recordamos o subimos y miramos la imagen del Entry Point donde
arranco el packer, recordamos que era 46b000, por lo tanto el packer no se preocupa mucho
de crear una nueva seccion donde desviar las apis, si no que lo hace en la misma seccion
donde se ejecuta.

La cuestion es que sabemos que esas son entradas redireccionadas, podremos tener suerte y
hallar el salto magico o alguna forma de repararla?
Usaremos dicha entrada 460aDC para tratar de hallar el salto magico.
Para no tener que cambiar el script del OEP que ya lo tenemos listo y quedo precioso, lo
copiamos a otra carpeta y lo renombramos OEP y lo copiamos de nuevo a su lugar original.

De esta forma ya tenemos guardado e identificado el que siempre usamos para llegar al OEP
y ahora podemos modificar el HBP para hallar el salto magico.
Alli esta cambiamos los HBP por los de la entrada mala, y le cambiamos el tipo W o sea de
escritura o WRITE.

Ahora borramos los HBP que teniamos anteriores, y reiniciamos.

Vemos que paro alli, miremos en el DUMP la entrada mala que estamos vigilando antes de
decidir si es el momento de terminar el script.
Alli ya esta colocado el valor malo, lo que pasa es que los HBP on WRITE, paran en la
instrucción siguiente a la que los dispara, asi que miremos la instrucción anterior.

Alli esta la instrucción que guarda el valor malo, y vemos que EAX tiene el valor que acaba
de guardar.

Fijemonos si ya esta escrita la zona redireccionada, si no deberiamos llegar hasta el OEP para
ver esto, miro 46b492.

Veo que la redireccion es muy tonta, lo que hace es pushear una constante 5bf11a9 y luego a
ese valor le hace XOR con 793e0502 y alli ira pues es el el primer valor del stack, y al llegar
al RET, se comporta como si fuera el retorno de un CALL.

Miremos si podemos calcular la direccion de la api donde va finalmente.

5bf11a9 XOR 793e0502=7C8114AB

Esa es la direccion de la api donde ira luego de ejecutar el redireccionamiento, volvamos al


OLLYDBG, miremos si la vemos por alli.
Si subimos un poco el stack vemos que esta alli la direccion de la api correcta, ahora lo que
debemos saber es si esto ocurre para todas las entradas redireccionadas, podemos parar el
script.

Y ver que pasa si ponemos un BPM ON WRITE en las entradas malas aun no llenas de la
tabla.
Demos RUN y para al guardar en la siguiente entrada

Y vemos que la api es MulDiv si nos tomamos el trabajo de ir a la zona redireccionada y


hacer el XOR, vemos que va hacia alli, asi que por aquí vemos una posibilidad de reparacion,
la api buena esta ubicada en el stack, exactamente en [ebp-0c]
Veamos ahora si cuando guarda alguna buena para en el mismo lugar o que hace, miro en la
imagen de la iat que habia tomado cuando habia llegado al OEP y una buena habia en 460ba8

Asi que le coloco un BPM ON WRITE en dicha entrada.

Doy RUN y para aquí


Vemos que es la misma direccion donde guarda las entradas malas , miremos si tambien en el
caso de las buenas en [ebp-0c] esta la direccion correcta.

Vemos que en el caso de las apis buenas, no guarda alli la direccion correcta, es una lastima
porque si no seria mas sencillo, pues cada vez que parara a llenar la IAT, hariamos que el
script guardara en la entrada el valor de [esp-0c] y listo, pero lo arreglaremos es sencillo.

No sera nada dificil, haremos el script modificando el mismo HBP.

Lo que haremos sera poner un HBP ON EXECUTION en donde guarda los valores en la
IAT, y cuando el script detecta que paro alli, lo que hace es testear si EAX tiene un valor
bueno o malo, y en el caso de ser malo, guarda el valor de [esp+0c] en [EDI] que apunta a la
entrada de la tabla que esta llenando.

Veamos el script.

var aux
var aux2

inicio:

bphws 4743d5, "x"

trabajo:

eob pirulo
run

pirulo:
log eip
cmp eip, 7c91eaec
je quitar
cmp eip, 7c91eb03
je restaurar
cmp eip,aux
je restaurar2
cmp eip,4743d5
je reparar
jmp final

quitar:
bphwc 4743d5
jmp trabajo

restaurar:
mov aux,esp
mov aux,[aux]
add aux,0b8
mov aux,[aux]
log aux
bp aux
jmp inicio

restaurar2:
bc aux
jmp inicio

reparar:
cmp eax, 500000
ja inicio
mov aux2, esp
sub aux2,0c
mov aux2, [aux2]
log aux2
mov [edi],aux2
jmp inicio

final:
MSGYN "Continuar?"
cmp $RESULT,1
je inicio
ret

-------------------------------------------------------------------------------------------------------

Esse es el script, primero que nada aclaro que coloco el HBP ON EXECUTION en la
instrucción siguiente o sea en 4743d5, pues los HBP ON EXECUTION si paran exactamente
en la linea donde se disparan, no asi como vimos los HBP ON WRITE o ON ACCESS.

El script es simple y esta basado en el que habiamos hecho antes, solo coloca un HBP ON
EXECUTION en 4743d5, que es la linea siguiente a donde guarda el valor malo.
cmp eip,4743d5
je reparar

En la parte purulo, donde el script toma el control al hallar una excepcion, le agregamos la
comparacion de EIP con 4743d5 para saber si verdaderamente estamos en el punto deseado y
de ser asi saltamos a reparar donde haremos la magia.

reparar:
cmp eax, 500000
ja inicio
mov aux2, esp
sub aux2,0c
mov aux2, [aux2]
log aux2
mov [edi],aux2
jmp inicio

En reparar lo que hacemos es primero verificar si en EAX hay un valor bueno o malo, como
vimos que todos los valores redireccionados van a la seccion del packer, su direccion es
menor a 500000, por lo cual si vemos que EAX es mayor a 500000, es porque alli hay una
api buena, y en ese caso no reparamos nada y volvemos al inicio, en caso contrario hay un
valor malo, y usamos la variable aux2, para hallar el valor de ESP al cual le restamos 0c y
luego hallamos su contenido el cual logueamos y luego lo guardamos en [EDI] que apunta
aun a la entrada que acaba de ser llenada con el valor malo en la linea anterior del programa,
y nosotros machacamos con el bueno, y luego retornamos, probemos el script.

Reinicio el programa, me fijo que no haya HBPs viejos, si es asi los borro, me aseguro que
esten los dos Bps para que funcione correctamente y lo corro.

Alli arranco el programa, veamos como quedo la IAT.


Una hermosura jeje, ya con este programa corriendo con la IAT reparada podriamos reparar
un dumpeado perfectamente, pues ya vimos que no es necesario estar detenido en el OEP
para usar un proceso en el IMP REC, mientras tenga la tabla corecta, pues reparara
perfectamente al dumpeado el cual si hay que realizarlo en el OEP siempre.

Ya tenemos los dos scripts el del OEP y el de la IAT, asi que este ultimo lo quitamos de la
carpeta y lo renombramos IAT y lo volvemos a traer asi ya vamos teniendo las soluciones
todas en scripts separados.
Lo unico que nos queda en el tema IAT es hallar el INICIO y largo de la tabla, para en su
momento llenar el IMP REC con esos valores.

El inicio subiendo en la IAT vemos claramente que comienza en 460818, el final tambien es
claro en 460f28 -
OEP=271b5
INICIO=60818
LARGO= 460f28-460818= 710

Podemos usar el falso OEP no hay problema luego se puede corregir a mano.

Ya casi llegamos amigos en la proxima parte solucionaremos los antidumps y armaremos


todo, no se la pierdan jeje.

Hasta la parte 44
Ricardo Narvaja
08/05/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 44

Bueno siguiendo con los pasos tradicionales, ya hemos hallado los stolen bytes, y tenemos los
scripts para llegar facil al OEP y para reparar la IAT, asi que realizaremos el dumpeado.

Lo abrimos en OLLYDBG y colocamos los dos Bps necesarios para que funcionen los scripts y
borro los hardware BPX que tenga de antes.

Ahora usando el script del OEP llegamos hasta el mismo.


Ponemos que no y estamos en el OEP.

Bueno ahora dumpearemos.


Le quitamos la tilde y lo guardamos como dumped.exe o el nombre que querramos, ahora reinicio
el OLLYDBG y utilizo el script para que corra con la tabla reparada.

Alli ya arranco, asi que abro el IMPORT RECONSTRUCTOR y busco el proceso en la lista de
procesos en el menu desplegable.

Ahora busco lso datos de OEP, RVA Y SIZE de la IAT que hallamos en la parte anterior.

OEP=271b5
INICIO=60818
LARGO= 460f28-460818= 710

alli veo que estan todas las apis correctas menos una, se me habia pasado?

Pues tendre que ir a ver que paso si no me dara error, reinicio el OLLYDBG y pongo un MEMORY
BREAKPOINT ON WRITE en dicha entrada.
Y doy RUN hasta llegar al lugar donde guarda el valor malo.

Alli vemos el valor que va a guardar y que en ESP-0C del stack no hay ninguna api, si no el valor
46e5cB.

Vemos que el script lo cambia por un valor, que en este caso es 46e5CB asi que miremos el valor
que guardo realmente en la IAT sin usar el script, apretemos f7

Ese seria el valor malo que guarda el packer sin usar el script, asi que veamos donde va, vayamos a
46bd5B.
Bueno como antes vemos que manda un PUSH con una constante y le hace XOR con otra y el
resultado de esta operación sera la direccion de la api donde va, calculemos.

942c0892 xor 946aed59

Si no tengo ganas de usar la calculadora puedo hacer que el OLLYDBG ejecute esas lineas y tendre
el resultado jeje

Vemos que el resultado del XOR es 46e5CB que es el valor que el script coloca en esa entrada, por
lo tanto el script no se equivoca, el tema es que esta entrada es algo especial, asi que reiniciemos y
lleguemos al OEP a ver si hallamos a que api pertenece dinamicamente o sea cuando se ejecuta.

Ahi llegue al OEP con el script para ello y ahora pondre un BPM ON ACCESS en la entrada de la
IAT que quiero investigar a que api va, para que pare al acceder a dicha entrada.
Alli paro traceo

Por supuesto llega al RET y de alli salta

Veamos si va a alguna api empiezo a tracear con F7 y veo que esto va para largo asi que aplico el
metodo del pushad, ahi en ese pushad del inicio y para en un POPAD donde tengo que tracear pocas
lineas para llegar aquí.

Y ver que la api que falta es la MessageBoxA.


Otro metodo mas rapido seria poner a hacer RUN TRACE con la condicion de que pare cuando EIP
sea mayor que 500000 por ejemplo, o sea cuando este saliendo de esta seccion a una api, veamos.

Alli parara cuando EIP este fuera del rango 0 -500000 probemos a ver si va.
Paro justo en la api MessageBoxA la ultima verificacion para ver si es la api correcta y no un
engaño es que vuelva al ejecutable a continuacion del call de donde partio eso se puede ver en la
primera linea del stack alli veo.

Que la direccion de retorno es 40e51B si voy alli

Retorna justo en la siguiente linea del call que lo llamo, asi que ya tenemos todos los datos,
reiniciamos el proceso con el script de la iat, le ponemos los datos como antes al IMP REC.

Y en la entrada invalida hacemos doble click y la cambiamos por MessageBoxA


Ahora si estan todas correctas voy a reparar el DUMPEADO, con FIX DUMP lo busco.

Y lo guardara como dumped_.exe aun nos queda arreglarle el OEP por los stolen bytes lo abrimos a
este reparado en OLLYDBG.

Debemos copiarle los STOLEN BYTES y cambiar el OEP.

00485AF3 Main PUSH EBP


00485AF4 Main MOV EBP,ESP ; EBP=0012FFC0
00485AF6 Main PUSH -1
Los stolen bytes eran estos puedo escribirlos con assemble.

Veo que los ecsribi muy arriba, pues son solo 5 bytes asi que deberia calcular:
4271b5 que era el falso OEP menos 5 bytes de stolen nos da el verdadero OEP o sea 4271b0, desde
alli escribo.

Ahora si guardo los cambios con COPY TO EXECUTABLE – SAVE FILE y aun me queda
cambiar el OEP, reinicio y voy al header en el dump hago GOTO EXPRESSION 400000.

Lo cambio al modo SPECIAL-PE HEADER busco el valor ADDRESS OF ENTRY POINT y lo


modifico y guardo los cambios.
Bueno luego de reparado si le damos a correr da error, quitemosle todas las tildes de las
excepciones y veamos que truco aun nos guarda.

Vemos en el LOG que ocurrio un error miremos el CALL STACK o sea el boton con la letra K los
ultimos calls que ejecuto (tambien puedo mirar en el stack los RETURN TO...)

El ultimo CALL que ejecuto fue desde 429806 vayamos alli


Sigamos con FOLLOW a ver donde va el CALL

jeje una tabla de saltos indirectos que provocan error ya que la seccion de memoria que posee
177658 o las direcciones contiguas de esa tabla, no estan en el dumpeado y debe ser una seccion
creada por el packer mientras se desempaca el original, asi que nos queda resolver esto, que es uno
de los tantos metodos antidumps, o sea que al dumpeado le falte algo que el original tiene pero que
fue creado en tiempo de desempacado y fuera de las secciones del exe, lo por lo cual al dumpearlo
no estara dentro del mismo dicha seccion.

Estudiemos esto arranquemos el original en otro OLLYDBG y lleguemos hasta el OEP con el script
borrando los HBP anteriores y poniendo los 2 BP correspondientes.

Alli llegamos vamos a mirar la zona de esos saltos indirectos aquí


Si vemos en el DUMP es una tablita de donde toma los valores adonde saltara.

Bueno hay muchas formas de resolver esto la clasica es hacer un injerto y que cree la seccion en el
mismo lugar y que copie todos los bytes a dicha seccion, desde otra donde lo habiamos guardado y
luego saltar al OEP ya con todo reparado, veremos si podemos buscar otro metodo alternativo en
este caso que sea mas sencillo ya que el de crear la seccion lo usaremos muchisimo, en otros
packers mas adelante.

Busquemos el primer salto esta en 46c0F5


Y ocupa 6 bytes el largo de la misma instrucción JMP y va a 178250 donde ejecuta 6 bytes y vuelve

La idea que se me ocurre es reemplazar los 6 bytes del JMP INDIRECTO por los 6 bytes que
realmente debe ejecutar probemos.

Marco las tres lineas que se ejecutaran y hago BINARY COPY

Vuevo al salto y hago BINARY PASTE.


Pues deberia funcionar pues estos JUMPS INDIRECTOS eran llamados desde calls del programa
asi que vendra aquí ejecutara los 6 bytes y volvera a continuacion de donde llamo al llegar al
RETN.

Como estan todos los JUMPS ordenados uno a continuacion de otro y los bytes a ejecutar tambien y
siempre son de 6 bytes de largo en ambos casos, podemos copiar toda esa seccion y que reemplace
directamente a los JUMPS.

Los bytes a ejecutar empezarian en 178256 que es la primera entrada de la tabla y terminarian en la
ultima o sea en 1799ba

Asi que hago BINARY COPY toda esa zona de los bytes a ejecutar y le hago BYNARY PASTE en
los saltos.
Vemos que quedo, tambien vemos que al final algunos saltos iban a partes que no teniann RET

Supongo que seran saltos no usados, asi que calculo que no habra problema, bueno ya tenemos
reparada la seccion esta podemos hacer BINARY COPY de la seccion completa y pegarla en la
misma del dumpeado con BYNARY PASTE.
Ahora guardo los cambios en el dumpeado con COPY TO EXECUTABLE etc etc.

Para guardarlos y que no diga que no puede, hacemos asi, desde el fin de la seccion subimos hasta
donde es la ultima linea donde hay datos.
Marcamos desde alli hasta el inicio e la seccion hacia arriba y guardamos los cambios reiniciamos y
probamos.

Funciona perfectamente hemos vencido los stolen bytes, la IAT redirigida, los antidumps, las
protecciones contra HBP jeje lo dejamos por el piso que vamos a hacer, pobrecito.

Hasta la parte 45
Ricardo Narvaja
15/05/06
file:///C|/FTP%20Ricardo%20Narvaja/Introduccion%20desde%20C...LYDBG%20PARTE%2044%20-%20ACProtect%20-%20AntiDump/Anexo.txt

Bueno me preguntaron como se hacia para injertar si la seccion que debes


crear ya esta ocupada como en este caso, en mi maquina la seccion del
antidump empieza en 150000 y alli el sistema creo un heap y tiene valores
necesarios para correr el programa si solo borramos y copiamos lo del
antidump no correra

0046B017 60 PUSHAD
0046B018 90 NOP
0046B019 68 00400000 PUSH 4000
0046B01E 68 00800200 PUSH 28000
0046B023 68 00001500 PUSH 150000
0046B028 FF15 A4094600 CALL NEAR DWORD PTR DS:[4609A4] ; kernel32.VirtualFree
0046B02E 90 NOP
0046B02F 6A 04 PUSH 4
0046B031 68 00200000 PUSH 2000
0046B036 68 00C00300 PUSH 3C000
0046B03B 68 00001500 PUSH 150000
0046B040 FF15 A8094600 CALL NEAR DWORD PTR DS:[4609A8] ; kernel32.VirtualAlloc
0046B046 90 NOP
0046B047 6A 04 PUSH 4
0046B049 68 00100000 PUSH 1000
0046B04E 68 00C00300 PUSH 3C000
0046B053 68 00001500 PUSH 150000
0046B058 FF15 A8094600 CALL NEAR DWORD PTR DS:[4609A8] ; kernel32.VirtualAlloc
0046B05E 61 POPAD
0046B05F 90 NOP

Con esto se borra la seccion 150000 y luego sse le puede copiar la del
dumpeado, hay que tener especial cuidado con los valores del heap que
necesita el programa para correr, eso que cuando arranco y estas parado en
el entry point del dumped ya estan alli, pues hay que asegurarse que al
copiar toda la seccion sigan alli y que no haya cambios, de ser asi
correra, creo que no vale la pena hacer un tute de esto solo hay que
agregar una api adelante que borre la seccion y luego si allocar y copiar
lo necesario, cuidando que no borrar datos de los que estan cuando solo
arranco el exe y duche seccion era un heap que usa el sistema.

Se entiende?

file:///C|/FTP%20Ricardo%20Narvaja/Introduccion%20de...0PARTE%2044%20-%20ACProtect%20-%20AntiDump/Anexo.txt16/05/2006 20:59:33
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 45

Aquí miraremos un unpackme de un packer duro para hacerlo en OLLYDBG, ya que no


corre en el ni con todos los plugins que lo ocultan, hay una parte del packer que no corre en
OLLYDBG y da error, veremos como podemos desempacarlo en OLLYDBG, jeje lo usaremos a
pesar de todo, podríamos usar otro debugger pero para que es una INTRODUCCION AL
CRACKING EN OLLYDBG, para hacerlo en otro debugger? Jeje.

Así que como somos cabeza duras, lo haremos en OLLYDBG a pesar de todo, el unpackme
esta adjunto y parece una verdadera fortaleza ANTI-OLLYDBG, antes que nada lo hacemos correr
sin debugger.

Ahí esta, mientras corre consume el 99% de los recursos de mi maquina de todas las pavadas que
hace para protegerse o vaya a saber porque.

Si intentamos atachearlo para mirarlo, vamos a FILE- ATTACH y buscamos el proceso.


Pues no se deja atachear, jeje, esto se esta nublando.

Si lo arrancamos en el OLLYDBG PREAPARADO PARA BUSCAR OEPs o PARCHEADO 5


que vimos en las partes anteriores.

Y luego si aceptamos

Y si damos RUN

Reiniciamos y llegamos nuevamente al SYSTEM STARTUP BREAKPOINT y cuando para vamos


a la ventana M.
Vemos que tiene una sola sección y eso es producto del conocido error de cambiar el numero de
RVA AND SIZES que es un valor del header, pero por ahora pongamos un BPM ON ACCESS en
dicha sección sabemos que este OLLYDBG es especial y solo parara al ejecutar código, no cuando
lee o escribe.

Ahora si quitamos el BPM y damos RUN

Bueno si miramos en el HEADER el valor de NUMBER DE RVA AND SIZES


Allí bajamos hasta buscar el valor

Bueno ese valor para que arranque sin error en OLLYDBG, debería ser 10 hexa, pues veamos que
pasa si lo modificamos.

Tratemos de guardar los cambios

GRR tratemos de cambiarlo en un editor hexadecimal


Cambiemoslo por 10.

Ahora guardemos los cambios.

Lo guardo con otro nombre por si acaso (bah porque ya se que esto no servirá en este caso, jeje que
sincero)
Veo que al abrirlo en el OLLYDBG ahora para correctamente en el ENTRY POINT, la reparación
de ese truco esta correcta, ahora demos RUN.

GRRRRRR, arranquemoslo de nuevo pero ahora cuando estamos en el ENTRY POINT cambiemos
en la memoria el valor del NUMBER DE RVA AND SIZES por si lo usa al valor original para
desempacarse.

Como ya arranco bien en OLLYDBG ahora le coloco el valor que tenia para ver si corre.
Allí lo puse ahora doy RUN

Evidentemente hay una parte que no pasa el OLLYDBG, probamos traceandolo pero no se ve nada
extraño llega a un punto que salta a una sección inexistente y bye bye, en OLLYDBG no corre ni a
patadas.

De todas formas quise mostrar los métodos que normalmente se usan en estos casos, para que vean
como se intento lo mas posible por los métodos convencionales, aquí necesitamos inspiración, nos
retiramos a pensar algo fuera de las normas jeje.

PENSAR

PENSAR

PENSAR

jeje

PENSAR MAS

Bueno, yo les muestro todas las posibilidades para que vean que así nomas no se puede con
OLLYDBG, la que me faltaba y tampoco sirve es la siguiente. (igual ustedes agenden todos estos
métodos porque muchas veces SI SIRVEN y los pongo para que los conozcan)
Abro el PARCHEADO 5 y lo coloco como JUST IN TIME DEBUGGER, o sea que cuando un
programa produzca un error, se atachee automáticamente al programa.

Aprieto ese botón para poner a OLLYDBG como JIT, cuando terminemos de trabajar con
OLLYDBG conviene quitarlo con el botón de abajo que dice RESTORE OLD JUST IN TIME
DEBUGGER, sino cada error que haya en su maquina se abrirá solito el OLLYDBG y sera muy
aburrido.

Ahora cierro el PARCHEADO 5 y hago click derecho encima del archivo original del unpackme,
ya borramos el que le habíamos modificado el NUMBER DE RVA AND SIZES porque no lo
usaremos mas no sirvió.
Los que usamos alguna vez el LORD PE DELUXE, tenemos en el menú del botón derecho de
nuestro sistema , la opción BREAK AND ENTER, que coloca un INT3 en el ENTRY POINT de un
programa, y provoca un error allí con lo cual arranca el debugger que esta como JIT, y se atacheará
al proceso que queremos debuggear, probemos.

Allí arranco el OLLYDBG y se atacheo al proceso, y vemos el INT3 que puso el LORDPE,
reemplazamos el INT3 por el PUSHAD que debe ir allí.
Ahora damos RUN

GRRRRR, y si ni a patadas corre en OLLYDBG, deberíamos tracearlo linea a linea y verificar que
es lo que hace, pero la verdad yo no tengo ninguna gana, lo mejor es PENSAR, PENSAR;
PENSAR, jeje.

Usaré siempre el archivo original, lo abro en el PEEDITOR.

Ahora miremos las secciones.


Con el PEEDITOR se pueden ver las secciones perfectamente y allí se me dispara una idea que
espero que no sea una IDEOTA media IDIOTA, jeje

No sabemos nada del programa, pero es muy posible que dado el funcionamiento de la mayoría de
los packers, que el mismo se desempaque en la sección que comienza en 401000, o sea la primera
linea que vemos allí, ya que aquí no se muestra el header, que pasa si le cambiamos el permiso a
alguna sección, para quitarle el permiso de escritura, de modo que cuando intente guardar allí, dará
error y se abrirá el PARCHEADO 5 que esta como JIT, jeje, sera posible? Intentemos, podría
probar con la primera sección, pero pienso que después de desempacarse, el programa guardara las
apis de la IAT y eso podría ser en la sección siguiente y como en la vida todo es intentar empezaré
intentando eso, total si falla puedo luego intentar con la primera.

Allí tenemos el WIZARD para cambiar el permiso de la sección


allí esta le debemos quitar la tilde de WRITABLE.
allí esta el permiso de la sección ya cambiado, comentemos que el autor puede ser mucho mas
inteligente que yo y a pesar de inicialmente la sección no tener permiso de escritura, podría
cambiarla en tiempo de ejecución con la api VirtualProtect, pero bueno, veremos.

Ahora corramos fuera de OLLYDBG este unpackme que le modificamos el permiso de la sección,
teniendo aun como JIT el parcheado 5.

Vemos que el programa para cuando esta tratando de guardar el valor de una api en dicha sección
(jeje mi pensamiento fue correcto), y eso produjo un error que abrió el OLLYDBG y lo atacheo
automáticamente.

Ahora para que pueda seguir corriendo debemos cambiar a mano el permiso de la sección para que
permita escribir en ella, vamos a M.

.
No importa que el OLLYDBG nos muestre una sola sección, lo que hacemos es hacer click derecho
y darle permiso de acceso total o FULL ACCESS.

Ahora probemos pasando la instrucción con f7, veamos si la guarda correctamente o vuelve a
producir error.

Vemos que la guarda sin ningún problema, ahora si recordamos como estaban dispuestas las
secciones en el PEEDITOR, ya que OLLYDBG no nos la muestra bien.
Vemos que la primera sección, ocupa 1000 bytes en la memoria ya que el VIRTUAL SIZE es 1000,
o sea que va de 401000 hasta 402000, la sección siguiente que le habíamos cambiado el permiso va
desde 402000 hasta 403000, jeje.

Si miramos que hay en 401000 vemos que el programa esta ya desempacado.

Así que aunque no podemos ponerle un BPM a toda la sección por medio del mapa de memoria ya
que el OLLYDBG nos lo muestra incorrecto, podemos marcar en el dump los bytes desde 401000
hasta 402000, que es la sección completa y ponerle un BPM ON ACCESS en todos esos bytes que
es lo mismo.
Sombreo todo desde 401000 hasta 402000 y le coloco el BPM ON ACCESS.

Ahora si doy RUN


Allí paro en el OEP que es justamente 401000.

Bueno lo mas difícil lo logramos ahora realizaremos el dumpeado.

Y guardamos el dumpeado, ahora buscaremos la IAT y los datos para el IMP REC.
Allí nomas debajo del OEP hay un call a una api

Y si le hacemos FOLLOW nos lleva a los saltos a las apis

así que la IAT esta muy fácil de localizar, mirando cualquiera de esos saltos por ejemplo el que va a
GetModuleHandleA toma valores de 402000, así que dicho valor pertenece a la IAT.

Es una IAT muy pequeña, así que el INICIO es 402000 y termina en 40201C, así que el largo es
1C, abro el IMP REC y restando le la imagebase que es 400000.

RVA O INICIO: 2000


SIZE: 1C
OEP: 1000
Allí vemos como llenamos con los valores del OEP y RVA and SIZE y apretando GET IMPORTS
nos dice que esta todo YES jeje.

Arreglamos el dumpeado con FIX DUMP y al correrlo nos da un error.

Lo arrastramos y soltamos en un LORDPE abierto para que le haga el REBUILDPE


Lo ejecutamos y bye bye packer jeje.

Y si pensar da sus frutos y los métodos inusuales también ya que los unpackers nos acostumbramos
a hacer las cosas siempre igual, ellos también protegen contra los metodos comunes y no contra
IDEOTAS IDIOTAS jeje.

Hasta la parte 46
Ricardo Narvaja
24/05/06
Anexo a lección 45 de Ricardo
INTRODUCCION AL CRACKING CON OLLYDBG

Lisa && Alquimista

El siguiente ensayo mostrara otra forma de enfrentarnos al paker de dicha


lección solo a golpes de ratón sin hacer nada de nada.

Nota: El Ollydbg usado será un olly normal solo modificado con Ollyghost y el
plugins Ollydump para dumpear el proceso.

• También se usara un editor PE, lord PE y dos herramientas de la lista,


Estricina y Pokemon Anti_Attach.

*** Recopilando información ****


Primero de todo como vamos lo atacaremos en memoria veamos unos datos del
archivo, para lo cual abrimos el programa con Lord PE.

Esos datos serán importantes, pues el paker puede cambiarlos en tiempo de


descompresión y no podremos hacer nada, como vemos el dato de
NumberOfRvaAndsizes esta cambiado pues sabemos que tenia 10 Hex, eso lo
cambiaremos, para lo cual necesitamos su Offset si abrimos con un editor P
vemos que el Offset esta en B4
Otro dato que necesitaremos es su OEP que nos lo da el plugins de PEID.

Bueno ya tenemos todos los datos necesarios para atacarle... así pues al ataque.

Los datos obtenidos son :

1. OEP  00401000
2. SizeOfImagen  00006000
3. NumberOfRvaAndSizes  Esta en el offset b4 y será cambiado a 10

*** Atacando ****


Ejecutamos el paker fuera de Olly y este funciona, pero vemos que nos come
todos los recursos.
Para trabajar un poco mas a gusto, usaremos una herramienta de Marciano,
Estricina, con la cual paramos los tres thread que contiene el paker. ( Este paso
no es necesario pero se trabaja mucho mas cómodo con el ordenador, liberado
de un proceso que lo relentiza enormemente) .

Si nos fijamos suspendiendo los thread el consumo de la CPU es cero, antes era
99.

Con esto ya podemos usar tranquilamente nuestra maquina.


*** Atacando en memoria para no ser detectados ****

Después usamos el Pokemos, para evitar posibles anti Attach y de paso también
recomponemos el dato de NumberOfRvaSizes, que si recordamos estaba en el
offset B4. ( NO es necesario restaurar el dato de NumberOfRvaAndSizes, pero
así le facilitaremos la tarea o Olyydbg)

Bueno si tenia protección Anti_Attach, esta ha desaparecido, seguiremos


atacando al paker en memoria, abriremos lordPE y lo buscaremos en la lista de
procesos.

Como vemos tiene el imagenSize a 0001000 y nosotros sabemos que tiene


que estar en 0006000, eso confundirá a Olly y a cualquier dumpeador con lo
cual no obtendremos un ejecutable en buen estado, además impedirá que
usemos el programa Import para restaurar las tabla de importación.

Conclusión: Hay que repararlo, eso esta claro, el mismo lordPE lo realiza botón
derecho y corregir ImagenSize.
Y como vemos en la captura de la derecha la ha quedado en 00060000 que es
la que tenia que tener, como sabemos desde el principio.

Ya hemos reparado parte del programa en memoria ahora lo attacharemos con


Olly y vemos que nos informa que la cabecera esta errónea.

Damos a aceptar y el programa queda Atacado, y parado en la API

ahora como conocemos su OEP en la ventada de código le damos a ir en


00401000 y estaremos en el OEP del programa.

y vemos que esta perfecto.... botón derecho

Y vemos en registro EIP que estamos parados en el OEP, así que ahora a
dumpear con el pluging.
solo queda añadirle la tabla cosa que aremos con el Import introducimos el OEP
y apretemos a los tres botones en orden, elegimos el archivo anteriormente
dumpeado y no sale la pantalla de que la cabecera esta en mal estado, eso ya
nos lo había informado antes Ollydbg,

Recontruimos la cabecera con cualquier programa que tenga esa opción, en este
caso Lord PE y el programa queda perfecto.
y si lo miramos con el administrador de tareas de windows, vemos que no
consume recursos, el paker ha desaparecido.

Bueno pues basta de paker raros por hoy.


INTRODUCCIÓN AL CRACKING CON OLLYDBG PARTE 46

En esta parte continuaremos con los métodos que improvisamos cuando las cosas empiezan a
teñirse de castaño a oscuro, para ello tenemos un gran crackme protegido por Fatmike, llamado
PATRICK.exe que ha hecho del mismo una verdadera fortaleza y creo que antes de adentrarnos en
packers mas difíciles, pues estos métodos alternativos inclusive los que muestro que no sirvieron,
muchas veces nos enseñan la forma de adaptarnos y muchas veces buscar un agujerito entre las
marañas de protección de un programa, como es el caso de este crackme al cual vamos a
desempacar.

Por supuesto hay que mencionar que un packer comercial no siempre puede tener todas las
protecciones de un packer hecho a medida, como es este caso, ya que si es un packer comercial,
tiene que estar preparado para agregarle las protecciones a cualquier programa, mientras que un
programa empacado y protegido a medida por su autor como este, puede tener trucos que le agrega
especialmente para la ocasión.

Bueno abramos nuestro OLLYDBG, como siempre uso el famoso ya OLLYDBG modificado y
ocultado con los plugins, llamado parcheado 4.

Según el autor el reto no solo es desempacarlo, si no también hacer que corra sin que necesite la dll
de protección que vemos allí junto al exe.

Bueno supuestamente nos dice que esta dll es la culpable de todo si la quitamos de la carpeta el
patrick no funciona pues nos pide la dll y se cierra.

Bueno arranquemoslo en el parcheado 4.

Vemos que antes de ni siquiera llegar al entry point ya se cierra y se termina en OLLYDBG.
Bueno veamos si cambiamos que el OLLYDBG pare antes del EP o sea en el System Breakpoint
que es un punto un poco anterior, en que el sistema puede detenerse un poco antes del EP..

Para ello en las opciones del OLLYDBG cambiamos en DEBUGGING OPTIONS-EVENTS

Que haga la primer pausa en SYSTEM BREAKPOINT y el tema es alguna dll que se ejecuta antes
de llegar al EP y que detecta que el programa esta corriendo bajo OLLYDBG y por eso lo cierra.

Bueno aquí no hay que ser muy original para darse cuanta que la culpable de todo es la dll esa, ya
que una dll de sistema no protegerá a un programa en particular contra OLLYDBG.

De cualquier manera es bueno saber que todas las dll ejecutan código antes de llegar al OEP, lo que
pasa es que cuando es una dll normalita y no nos afecta, y como OLLYDBG no para en ella, pues
no nos damos cuenta ni nos interesa mucho, pero si vemos en el programa.

Vamos al header con GOTO EXPRESSION-400000


lo cambiamos el modo SPECIAL- PE HEADER.

Ahora bajamos y veamos el puntero siguiente.


Que como sabemos es el puntero a la IMPORT TABLE o IT ( no confundir con la IAT esa es
IMPORT ADDRESS TABLE lamentablemente tienen nombres muy parecidos jeje)

Bueno esto ya lo vimos si vamos allí a 6F3C mas la imagebase o sea 400000, veremos la IT.

Le quitamos el modo SPECIAL y volvemos a visualizarlo en HEX.

Si recordamos un poco los primeros 5 DWORDS correspondían a la primera dll, los segundos 5 a la
segunda en la forma que se irán cargando en la IAT.
Para saber el nombre de la primera DLL el 4to DWORD es el puntero al nombre o sea que en
40712e estaría el nombre de la primera DLL que se carga en la IAT veamos cual es.
Allí esta la WINMM.dll seria la primer dll con que trabaja el sistema, pero se ejecuta antes de llegar
al EP en el cual para el OLLYDBG?.

Veamos abramoslo y que pare en el SYSTEM BREAKPOINT.

Allí paro, ahora sabemos que este crackme no llega al EP, pues se cierra antes, alguna de las dll se
ejecuta y lo cierra, igual sabemos que es la dll que esta conjunta con el crackme, pero miraremos ya
que estamos, si se ejecutan las dll antes de llegar al OEP, así que vayamos al mapa de memoria M y
coloquemosle un BPM ON ACCESS en la sección CODE de dicha dll.
Bueno allí lo colocamos ahora para ver si se ejecuta, demos RUN varias veces y fijemosnos abajo
en el OLLYDBG si alguna vez para por EXECUTION, y si para por READ O WRITE continuamos
apretando RUN.

La primera vez que para lo hace leyendo esa sección sigamos hasta que pare por ejecución.

allí paro por ejecución de la dll.


Quiere decir que no es nada extraño que las dll se ejecuten, ahora repitamos el método, pero con la
dll que vamos a investigar directamente, reiniciemos el OLLY y cuando para vayamos a M y
pongamos un BPM ON ACCESS en la sección code de la AntidebugDll.dll.

Ahora doy RUN y a la primera se detiene por ejecución en la DLL.


Aquí empieza el problema jeje.

Lo primero que tenemos que hacer es correrlo en OLLYDBG para ello antes que nada veamos
algunas cositas.

Bueno quitamos el BPM que habíamos colocado y ya que no detecta el OLLYDBG por el nombre,
ni por la ventana ni por todos los trucos que cubre el HIDEOD pues calculo yo que debe ser que
intenta mirar que proceso lo abrió, para eso utiliza lo que ya vimos, el truco con Process32Next
pero esto supuestamente esta cubierto con el HideOD, que pasa aquí?
De cualquier manera si hago algunas pruebas extra, me doy cuenta que el crackme no corre si no lo
arranca el EXPLORER.exe, o sea debe arrancar con doble click normalmente, por ejemplo si lo
tengo al crackme comprimido dentro de un rar con su dll dentro, pues si lo ejecuto desde allí
debería correr, pero no corre se cierra al igual que cuando lo arrancamos de cualquier otra tool o
programa que no sea el explorer.exe.

Así que el chiste debe ser que mira cual es el proceso que lo abrió y si no es el explorer.exe se cierra
sin mas, pues eso se realiza con la api PROCESS32NEXT así que pongamos un BP en ella y
miremos.

Demos RUN

Allí tenemos el parámetro que nos muestra el reporte, en mi maquina esta en 12EEc8.

Usaremos el pupe que nos muestra los procesos en orden y con su PID, para poder ir siguiendo
mejor el tema.

Allí tenemos el primer proceso y tenemos el PID que es cero, si miramos el WINAPI32
Allí esta la api Process32Next y vemos que esta el parámetro que apunta al reporte, allí llamado
PROCESSENTRY32 structure, si cliqueamos en el link ese para que nos aclare vemos lo siguiente.
Allí vemos que el 3er DWORD es el PID del proceso estudiado y el 7mo el PID del proceso que lo
arranco al mismo, en este caso son ambos cero pues es el proceso originario del sistema.

Allí están ambos en rosado el PID del proceso y en verde el PID del que lo arranco, pues aquí no
hay nada raro demos RUN nuevamente.
Hey ya se cerro, pero con solo estudiar el proceso del sistema no puede sacar ninguna conclusión
para cerrarse, aquí algo falla, y es la protección del HIDEOD sobre esta api la que genera conflictos,
probemos quitandole la tilde al HIDEOD relativa a Process32Next y repitiendo.

Ahora al reiniciar no necesitamos colocar nuevamente el BPM en la sección code, porque se


mantiene el BP en la api y vuelve a parar.

Allí paro y vemos el reporte igual que antes los dos PIDs son cero

Ah ya veo el problema cuando tenemos colocada la tilde en Process32Next con el HideOD, al


retornar de la api, EAX vale cero lo cual significa que hubo un error al ejecutarla y el programa se
cierra directamente, mientras que sin la tilde vuelve siendo EAX igual a uno, con lo cual busca el
siguiente proceso para seguir investigando, así que ya sabemos para este caso debemos manejarnos
sin la tilde esa.

Bueno ya sin la tilde entonces podemos llegar al segundo proceso del snapshot, que es el SYSTEM
cuyo PID es 4 lo vemos marcado en rosado y que fue arrancado por el de PID cero o sea el
anterior.
Bueno conviene quitar el BP del inicio de la api y colocarlo en el RET de la misma para ver
exactamente cuando nos devuelve el reporte del PATRICK a su salida y modificarlo antes que el
programa lo pueda leer.

Ahora si seguimos hasta que en el reporte aparece el PATRICK.exe

Allí esta vemos el PID del patrick que dice que es AE4 y que fue arrancado por el proceso con PID
8AC, miremos en el PUPE recordemos que si reiniciamos el crackme debemos actualizar la
información del pupe apretando el botón actualizar si no quedara con info vieja.
Pues allí esta el patrick de PID AE4 fue arrancado por el parcheado4 de PID 8AC.

Pues aquí esta la madre del borrego el crackme se fija que no fue arrancado por EXPLORER.exe y
se cerrara, veamoslo, pongamos un BPM ON ACCESS en el PID del parcheado 4 a ver si lo
compara.

Si damos RUN para aquí.

Donde lee el PID y lo guarda en otro lugar veamos donde lo guarda así podemos ponerle un HBP
ON ACCESS allí también.
Al apretar F7 lo guarda en otra dirección.

Así que si le ponemos un HBP ON ACCESS allí también y lo vigilaremos por si lo lee alguna vez.

Si damos Run vemos que borra el valor inicial del reporte dejando guardado el que tenemos
vigilado por el HBP.

Como paro en un BPM ON WRITE al apretar F7 lo borra, quiere decir que ya no necesitamos el
BPM allí, ya que el único valor quedo protegido por el HBP, en la otra posición, quitamos el BPM.
Damos RUN nuevamente y llegamos a la comparación, allí compara el 08AC que es el PID del
parcheado4 en este caso, o del programa que lo haya arrancado y lo compara con C7C.

Que es el PID del explorer lo que sospechábamos se cumplió

Vemos que si al programa lo arranco el explorer ambos PID son iguales y salta evitando el
ExitProcess, al ser diferentes, pues no salta y se cierra jeje, primer truco fuera, el tema es que si
cambiamos la dll y guardamos los cambios tiene tantos chequeos que les aseguro que no arrancara,
Así que lo mejor que podemos hacer para no cambiar nada es quitar el HBP anterior y poner
solamente un HBP ON EXECUTION en este linea de la comparación.

De esta forma cada vez que lo arranquemos el programa parara aquí y podremos cambiar a mano el
PID del parcheado 4 por el PID del explorer y hacerlos iguales y no habrá problemas.

En realidad mas cómodo es ponerlo en la linea anterior a la comparación, ya que allí es donde lee
el PID del parcheado 4 y lo pasa a EAX, de esta forma aunque no tengamos el reporte a la vista, ni
sepamos donde esta veremos de donde lo lee fácilmente, probemos.

Ahora reiniciemos y veamos si podemos editar directamente el PID sin tener que poner el BP en
PROCESS32Next y pasar las apis una a una, borramos los BPs y reiniciamos.
Allí paro y tenemos la información de donde editar, que es 12eeb8 en mi maquina voy allí y cambio
el PID 8AC por C7C.

Ahí esta ahora si apretamos F7 y como ambos PIDs son iguales, salta y no se cierra.

Esto es solo el primero de los trucos que debemos sortear, al menos con el HBP puesto es sencillo
que pare allí cambiar el PID y continuar.
Traceaando un poquito a partir de allí vemos que ahora lo que el crackme quiere hacer es una
snapshot del proceso de PID C7C en mi maquina para ver si es el explorer, verificando algunas
características, como el C7C es realmente el explorer no encontrara nada raro, esto es para cuando
alguien renombra otro programa como EXPLORER.exe para arrancarlo desde allí y que pase la
anterior comprobación, lo cual puede ocurrir, pero la que no pasara sera esta segunda en ese caso
jeje.

Y si traceamos un poquito mas vemos que llega a Module32First o sea que trabajara con esa api y
Module32Next para verificar los módulos del proceso que lo arranco.

Bueno aquí tenemos lo que nos muestra el reporte, en el caso de la información de los módulos, no
sabemos exactamente que chequeara, pero al estar buscando la info sobre explorer.exe sabemos que
sera toda correcta, igual allí vemos los datos del primer modulo que es el mismo ejecutable.

Lo mas importantes datos los vemos allí en rosado un identificador 01 que solo sirve dentro del
snapshot e identifica que son módulos todos dentro del mismo proceso, en realidad es un numero
interno del snapshot que no tiene mucha importancia, luego en verde el PID del proceso a que
pertenece este modulo, luego en celeste, la dirección base del modulo que en mi caso es 1000000 o
sea la imagebase de dicho modulo, y en amarillo el tamaño del modulo ademas, vemos que muestra
el nombre del modulo, y mas abajo fuera de la imagen anterior, el path del mismo.

Bueno con eso tenemos suficiente información así que veamos que hace con ella.

Traceando un poquito vemos que lee el C7C y lo compara con el que lee ahora desde este reporte
para ver si los modules también corresponden al explorer.exe.

Pues sigamos paso a paso

Allí vemos que va a GetWindowsDirectory esa api le dará el path a donde esta la carpeta
WINDOWS o donde se instalo el sistema, siempre dentro de ella debe estar el explorer.exe, así que
ya me veo venir que chequeara el path del reporte con el que le de esta api como resultado.

Miremos el buffer donde guarda el path.

allí lo guardo así que esta listo para comparar con el path que saco del reporte, igual en nuestro caso
no habrá problema ya que tiene en el reporte el path del explorer.exe así que seguimos tranquilos.

Vemos que allí un poquito mas abajo le esta por completara C:/WINDOWS, le agregara el / y luego
explorer.exe para poder compararlo con el del reporte.

allí lee y completara el path


jeje es lindo ir viendo que hace.

Y se viene la comparación allí empieza a leer el path del reporte.

Llega a CharUpperBuffA

BUFF diría yo pero seguimos esta api pasa a mayúsculas la string que esta en el BUFFER.
Allí esta nada del otro mundo jeje, así que el path del reporte esta en mayúsculas, esto lo hace para
poder comparar bien porque ya vimos que el path que le entrego la api GetSystemDirectory al que
le agrego el / y el EXPLORER.EXE esta en mayúsculas también, así que vamos directo a una
comparación.

Allí llega a un CALL donde comparara ambas strings, seguramente dentro y al salir sera EAX, cero
o uno según si son iguales o no, con una simple mirada dentro del call y sin tracearlo dentro me doy
cuenta que es solo eso.

Allí vemos la linea donde comparara ambos paths así que si alguien renombra un OLLYDBG como
explorer.exe tiene que correr dentro de la carpeta WINDOWS o donde haya instalado su sistema y
el problema es que allí esta el verdadero EXPLORER.exe corriendo así que se complica mucho ese
método.

Pues con el nuestro seguimos caminando y pasamos ese CALL con F8.

Vemos que EAX se hace cero y saltara al llegar al JE.

Si vieran como solucione esto finalmente y como no fue necesario nada de esto se agarrarían de los
pelos, pero es bueno aprender y ver que hace si no se hace muy largo, no viene nada mal, ademas
vemos de esta forma cuales son las limitaciones de lo que podemos hacerle y lo que no.

Veo que aun no esta convencido y quiere seguir hallando datos sobre mas módulos del proceso que
lanzo el crackme, allí llega a Module32Next a ver el reporte del segundo modulo.

En este caso es la ntdll.dll, vemos los mismos datos que en el caso anterior, el identificador 01, que
usa para determinar que son todos módulos del mismo proceso, luego el PID del proceso al que
pertenecen los módulos 0C7C en mi caso, y los demás datos como base y tamaño.
Sigue comparando si todos los módulos pertenecen al explorer.exe este muchacho es difícil de
convencer, si la novia le dice que no lo engaña, la hace seguir con 20 detectives por si acaso falla
alguno jeje.

Ugh otra vez a GetWindowsDirectoryA, una pregunta FATMIKE aceptara cheques?, jeje porque
me parece que no confía ni en su propia sombra jajaja.

Apostemos seguro comparara el path que saca del reporte, con el path que lee de esta api, jeje, no es
muy original en esta parte, sigamos mirando.
Allí vuelve a obtener el path del directorio donde esta instalado windows y vemos que repetirá lo
mismo que hizo con el primer modulo, no lo detallaremos tanto, traceemos hasta el call de la
comparación.

Al llegar al call de la comparación aquí vemos que compara el path del explorer con el de la dll, los
cuales evidentemente no son iguales, pues las dlls de sistema no están en el mismo directorio que el
explorer, así que no serna iguales de ninguna forma.

Por lo tanto a la salida del call EAX vale 1 ya que no son iguales y ahora no salta.
Antes de seguir aclaremos que la ofuscación para ocultar el código que se ve en el programa.

Como vemos se ve claramente que mueve a EAX una constante y luego compara esa constante con
otra que nunca serán iguales, por lo tanto el salto JE no se produce, luego va a un MOV
EAX,XXXXX allí vemos marcados con rojo esas direcciones, que al moverlas a EAX y luego hacer
un JMP NEAR EAX lo que esta haciendo realmente es saltar a esa dirección, por supuesto si
traceamos, veremos todo el código, el ofuscamiento no puede evitar que traceemos y veamos el
código real, pero si no traceamos y queremos ver el código rápidamente que esta enmarañado, solo
con situarnos en cualquiera de esos MOV que están marcados con la flecha y hacer click derecho –
FOLLOW INMEDIATE CONSTANT
Podremos ver el código ofuscado debajo, sin necesidad de ejecutarlo.

Allí se ve claramente sin ejecutar y si quiero mirar en el próximo MOV que esta allí abajo repito lo
mismo y
Y vemos el código ofuscado sin necesidad de tracearlo.

Igual esto es a nivel informativo por ahora seguimos traceando.

Seguimos traceando y vemos que sigue jugando con los paths, aquí apunta a
SYSTEM32\NTDLL.DLL sigamos
Vuelve a leer el nombre EXPLORER.exe

Luego vemos que compara la E de EXPLORER.exe con la N de NTDLL.DLL

Y luego salta evitando el ExiProcess, veo que aquí no hay problema pasamos el ExitProcess, porque
obviamente no serán iguales esos nombres, así que seguimos.

Veo que este muchacho me va a hacer recorrer todos los módulos uno a uno ahí va por mas jeje, no
le veo mucho el sentido a esta parte realmente si el proceso que lo creo tiene su modulo principal en
el path correcto, que sentido tiene estas verificaciones modulo a modulo, no olvidemos que el
explorer tiene muchos módulos y este trabajo sera insalubre si seguimos así.
Pero bueno ya veremos seguro se nos aclarara a medida que sigamos, paciencia..

Traceemos hasta la comparación.

Vemos que por ahora va mirando uno a uno los módulos y todos son chequeados contra
EXPLORER.exe y se fija que solo el primero se llame así, y que el resto no vuelva a repetir el
mismo nombre nuevamente pues seria falso todo, no hay explorer.exe con dos módulos llamados
así.

Bueno para ahorrar traceo podemos poner un HBP ON EXECUTION aquí en el CALL
COMPARADOR, así vamos viendo las comparaciones mas rápidamente.

En el PUPE tenemos también la lista de MÓDULOS del EXPLORER así podemos ir siguiendo uno
a uno y parar antes que termine de compararlos todos, en el PUPE entrando a CAJA DE
HERRAMIENTAS, vemos los módulos.

Como están en orden no nos cuesta nada seguirlos.

El ultimo que me muestra el PUPE abajo de todo es en mi caso el idle.dll


así que debo pasar todos hasta llegar allí.

Ya faltan tres UF son unos cuantos, ya casi llegamos.

allí llegue al ultimo ahora puedo seguir traceando a ver que hace.

Vemos que vuelve a saltear el ExitProcess y se encamina a Module32Next nuevamente.

Aun lee el ultimo si ven el PID del explorer que cambio, es que en el medio del tute tute que
reiniciar la maquina y allí me cambio el PID del EXPLORER, pero sigue todo igual solo que con un
PID diferente.

Vemos allí que hay una ultima comparación y que si salta va también por medio de ese JMP a
ExitProcess como ven el chico te tira afuera a cada rato jeje.

Bueno parece que se canso de repetir y aquí empieza otra variante llegando a la api
GetModuleFileNameA.

Con el cual obtiene el path del crackme.

Bueno ahora llega a CreateMutexA que no se si en alguna parte anterior lo explique, se utiliza para
que cuando un programa arranca una segunda instancia o segundo proceso de si mismo, con esta api
puede verificar si es la primera vez que se ejecuta o es el segundo proceso el que llego aquí veamos
su funcionamiento.

allí están los parámetros


Al pasar la api con F8 vemos que el sistema le otorgo un HANDLE que es 50 y ademas el
OLLYDBG nos dice que hay un ERROR SUCCESS que traducido al castellano es que pudo crear
el mutex perfectamente o sea con suceso.

Vemos que hay dos MUTEX uno llamado MYFIRSTINSTANCE y otro WAIT, los podemos
apreciar si vamos a la ventana H de handles.

El otro seguramente habrá sido creado al inicio en la parte que no traceamos y se nos paso, pero allí
esta.

Luego llega a la api que determina el ULTIMO ERROR y este ocurrio al crear el Mutex como
vimos el OLLY nos informo que fue ERROR SUCCESS, ahora el programa por medio de esta api
se informa también de ello.

Como vemos al retornar de la api, EAX vale cero por lo tanto al igual que nos dijo el OLLY ese
cero corresponde a SUCCESS.
Aquí vemos una trampa y suponemos porque se llama WAIT, el primero de los dos MUTEX es
llamado MY FIRST INSTANCE es el que decide si estamos en el primer o segundo proceso, y este
llamado WAIT casualmente, vemos que en este caso al ser el resultado SUCCESS el programa no
va a EXITPROCESS, pero en el caso del segundo proceso si llegara hasta aquí y chequeara el
MUTEX y el primer proceso aun existiera, el resultado ya no seria 0 sino B7 con lo cual se cerraría,
solo seguiría corriendo si la primer instancia ya se cerro, estos son juegos de tiempos muy precisos
que ya nos ocuparemos de investigar, por ahora sepamos que un MUTEX cuando un proceso lo
crea, la primera vez da SUCCESS y si aun existe y un segundo proceso lo vuelve a crear da
ERROR ALREADY EXISTS y esa es la forma de decidir si esta en el primer o segundo procesoen
la mayoría de los casos.

Sigamos adelante.
Pues allí vemos que el programa va a crear el segundo proceso mediante la api CreateProcessA.

Allí están los parámetros, el tema es que supongo que si yo apretó F8 el segundo proceso va a ser
creado, pero antes que se cierre este, el segundo proceso va a llegar a chequear el MUTEX WAIT y
al existir este aun, porque el primer proceso no se cerro, se va a cerrar el segundo proceso
(SUPONEMOS).

Obviamente si uno esto se hace cuando se ejecuta el programa este primer proceso crea el segundo
y enseguida se cierra, mucho antes que el segundo chequee todas las pavadas de módulos y llegue a
chequear el MUTEX WAIT.

O sea que apretar F8 no me sirve pues el otro proceso se cerrara, que podemos hacer, y no mucho,
intentar crearlo suspendido, para ello hay que cambiar el parámetro CreationFlags a 4 veamos.

Veamos que pasa.

Como vemos al ejecutar el segundo proceso, al retornar EAX=0, eso quiere decir que no lo pudo
crear y porque puede ser eso, aquí si que me dejo perplejo.

Voy a poner un HBP ON EXECUTION aquí en la llamada a CreateProcessA y voy a probar


algunas cositas para ver porque no se crea el segundo proceso, o sea que dejo solo dos HBP el que
me permitía cambiar el PID del parcheado 4 al del explorer y ya cambiando eso, llego hasta el
segundo HBP que coloque aquí en CreateProcessA

Ah otra vez el HideOD, probando me di cuenta de que esta interfiriendo de alguna forma con los
privilegios del crackme, y no le permite crear otro proceso.

Así que les muestro, le quite las siguientes tilde al HideOD y ahora si crea el segundo proceso.

Poniendo las tildes en esta forma al pasar con F8 crea el segundo proceso y marca EAX=1, así que
ya estamos en la pista.

Ahora vuelvo a llegar con las tildes del HideOD bien puestas y coloco nuevamente en 4 el
parámetro para que se cree suspendido.
Ahora si que estamos mejor si vemos en el pupe.

Ya tenemos los dos patrick.exe creados y el segundo suspendido jeje.

Ahora el tema complicado, es como parar y atachear el proceso ya que al darle que continúe ya
vimos que chequea de todo y por lo tanto detectara cualquier cosa y se cerrara, o no se
descomprimirá bien.
El tema es que ahora lo tenemos como congelado y no esta aun la dll cargada por lo cual no lo
podremos parar fácilmente.

Haremos el siguiente método reiniciamos el parcheado 4 y cuando para en system breakpoint,


ponemos el BPM ON ACCESS en la sección code de la antidebug.dll y cuando para en el EP de la
misma miremos este valor en nuestra maquina.

Ahora nosotros necesitamos buscar un punto para parar la ejecución del segundo proceso antes de
que se ejecute la dll, pero la dll no esta aun cargada, como podemos hacer un loop infinito en esta
misma dirección, pero en el segundo proceso, así que miremos el stack a ver de donde llega al EP.
Vayamos a mirar esa zona

O sea ese call es el que desde allí salta al EP de la dll, ahora estas direcciones si están allocadas
pues pertenecen a la NTDLL.dll que es lo que arranca todo así que volveremos allí y lo crearemos
suspendido y cuando este suspendido le colocaremos un loop infinito en ese call, así cuando lo
ponemos a correr nuevamente quedara loopeando allí.

Así que anoto la dirección en mi maquina para el loopeo 7c9111a4 y los bytes originales son FF 55.

Llego nuevamente hasta CreateProcessA recuerdo de parar en el HBP ON EXECUTION para


cambiar el PID por el del explorer para que no me eche afuera.
allí reemplazo el PID del parcheado 4, por el PID del explorer y luego llego a CreateProcessA

Reemplazo el 20 por el 4 de CREATE SUSPENDED

Apreto f8 y se crea bien el segundo proceso.

Allí están en el PUPE los dos procesos.

Ahora abro el de mas arriba que es el segundo y elijo PARCHEAR.


Escribo la dirección donde pondré el LOOP y cambio los bytes originales por EB FE que es un
LOOP INFINITO.

Luego apreto PARCHEAR y ya esta colocado el LOOP, ahora antes de atachear debo quitar la
suspensión del proceso si no no se atacheara bien, debo ponerlo a correr total quedara allí en el
LOOP INFINITO ciclando.

Para eso uso la gran herramienta de ARAPUMK llamada ESTRICNINA


Bueno busco el segundo proceso por el PID, en este caso es ese, aquí no están en orden así que
debo chequear bien que sea el segundo, y hago click derecho INFO THREADS.

Y apretamos REANUDAR
Con eso el proceso dejo de estar suspendido y al estar corriendo aunque sea loopeando se puede
atachear.

Para atachearlo hay quien puede probar atacheandolo directamente con el attach del OLLYDBG
pero haciéndolo así a mi no me aparecían los módulos y no terminaba de correr, pueden probar
igual quizás sea cosa de mi maquina o del HideOD vaya a saber, pero en este punto para atachearlo
la única forma en que lo logre, fue poner el PARCHEADO 4 como JIT, y hacer CTRL
+ALT+DEL, y allí elegir el segundo proceso del patrick, teniendo cuidado que los PID no están a la
vista y que hay que ir a agregar columna para que se vean.

Con eso se verán los PID, lo malo es que el PID esta en decimal, pero bueno, me fijo en el pupe
cual es el mal alto de los dos y así localizo el segundo proceso.
En mi caso el segundo proceso es el mas alto PID así que busco el mas alto PID en la lista de
procesos y elijo DEPURAR con eso se atacheara el OLLYDBG que esta como JIT.

allí queda RUNNING, luego pauso

parece que el OLLYDBG esta todo blanco pero a no asustarse, vamos a la T de THREADS

Y haciendo doble click en uno de los dos threads, estaremos en el loop infinito que provocamos, si
hacemos doble click en uno y no estamos en el loop, probamos el otro.

Ahh ali estamos ahora veamos esta parte en el dump para quitarle el LOOP
Los bytes originales eran FF 55 los restablecemos

Si se atacheo bien, veremos en la ventana E de los ejecutables, algunos ya cargados, si cuando


paramos aquí sale vacía, pues es que fallo el attach a mi me paso varias veces sobre todo
atacheando directamente con el OLLY, sin usar el CTRL mas ALT mas DEL.

Vemos que aun no va a saltar a la dll, porque se ve que para varias veces en la misma dirección, así
que ponemos un BP allí y damos RUN.

Cada vez que para me fijo si ya apareció la antidebugdll.dll en la lista de módulos, allí la veo así
que ahora puedo ponerle el BPM ON ACCESS en su sección code
Quitar el BP y doy RUN

Y para en el EP de la dll, uf que terrible esfuerzo pensar que nada de esto es necesario para
solucionarlo jeje, pero todo es practica que nos sirve para manejarnos.

No creo que nos tire fuera por el hecho de quien creo al proceso pues fue el mismo primer proceso
del patrick el que lo creo, probemos poniendo un BP CreateMutexA

Y damos RUN

Vemos que como dijimos para nuevamente para crear el MUTEX - MY FIRST INSTANCE, pero
este ya fue creado por el primer proceso así que lleguemos hasta el RET
Allí vemos que cuando el primer proceso creaba un MUTEX como no existia, el resultado era
ERROR SUCESS y el valor era cero, aquí el resultado es ERROR ALREADY EXISTS o sea que
ya existe y el valor que retorna es un B7.

Por supuesto a continuación va la api que lee el ultimo error, y al ejecutarla ve que EAX=B7.

O sea ahora vemos la diferencia cuando se corre el proceso por primera vez y cuando corre por
segunda vez tomando los errores al crear los mutex.

Bueno hasta aquí llegamos con esta primera parte aun queda el análisis de ver que hace cuando
arranca como segundo proceso, para estudiarlo nada mas porque como les dije la solución no
necesita nada de esto jeje, ni siquiera tracear ni una sola linea jeje, esto es todo aprendizaje nada
mas y de molesto que soy yo, que me gusta destripar las cosas hasta las ultimas consecuencias.

Hasta la parte 47
05/06/06
Ricardo Narvaja
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 47

Bueno aquí estamos con la segunda parte del PATRICK llegando hasta el punto donde quedamos
en la parte 46, vi que en la instrucción que colocabamos el loop infinito para atachear, una vez que
reemplazamos los bytes por los originales es conveniente colocar un Hardware Breakpoint y no un
BP comun, pues este ultimo es detectado y la dll no arranca bien, asi que con un HE colocado
paramos alli unas cuentas veces mas y cuando vemos que ya esta la antidebugdll.dll a la vista en la
lista de modulos cargada, le colocamos un BPM ON ACCESS en la sección code y listo, llegamos
hasta su Entry Point.

Pues alli estamos parados en el Entry Point y con todos los modulos cargados.

Bueno empecemos y vamos por partes como dijo JACK, tenemos que llegar al OEP del patricio con
OLLYDBG y no sera una tarea sencilla, ya que como les dije hay un truquito con el cual se llega
facilmente sin OLLYDBG, pero aquí estamos crackeando con OLLYDBG así que este truquito lo
dejare para el final y seguiremos el espinoso camino de verificar cada cosa que hace.

Bueno lleguemos nuevamente hasta el punto donde se crea el segundo proceso y como explicamos
cambiando el PID por el del explorer y luego cuando llegamos a CreateProcessA, cambiamos el
parámetro por suspendido, llegamos hasta el ret de dicha api, y allí aplicamos el truco de poner un
loop infinito en la ntdll.dll como vimos en la parte anterior, atacheamos y luego el hardware bpx en
esa linea, luego de quitar el loop infinito y parar varias veces allí hasta que se cargue la
antidebugdll.dll y allí ponemos un BPM ON ACCESS en la sección code de la dll y estamos en su
EP, esto es un breve resumen de todo lo que se hizo en la parte 1, la cuestion es que estamos con
dos OLLYDBG abiertos, uno el que llamaremos proceso PADRE que fue el primero que se inicio,
esta justo cuando retorno de la api CreateProcessA y el otro que llamaremos proceso HIJO, esta en
el EP de la antidebugdll.dll.

Si no entendieron algo de todo esto, pues les aconsejo que antes de ahondar en lo que sigue repasen
practiquen y entiendan lo que se hizo, pues lo que viene es duro también (o peor jeje)
Bueno por lo tanto en el PADRE estamos aquí al retornar de la api CreateProcessA

Y en el HIJO estamos en el EP de la antidebugdll.dll como veran en el HIJO use un OLLYDBG de


distinto color que es un truco que no solo hago para que los que leen sepan a cual de los dos
procesos me estoy refiriendo, si no que para mi mismo al crackearlo, me ayuda a saber en donde
estoy y no confundirme.

Bueno aquí tenemos que emular que los dos procesos corren a la vez lo cual no es posible, pero ya
que sabemos que un proceso se ejecuta hasta un punto donde se queda esperando que el otro
proceso haga algo, pues con eso podemos ir guiandonos y hacer el trabajo de uno, hasta el punto
donde espera y allí seguir con el trabajo del otro.

Comenzaremos mirando el hijo, por las veces que lo ejecutamos sabemos que el proceso HIJO, en
unos segundos luego de ejecutarlo si ve algo malo se cierra, por supuesto antes de eso, debe existir
la comprobacion de si es realmente la primera vez que corre o la segunda o sea si es el padre el
proceso que esta corriendo o el hijo, y según esa decision ira a seguir realizando las tareas como
padre o como hijo, o sea es importante que entiendan que los dos procesos son similares ya que
parten de la misma fila, lo que los diferencia es que uno detecta que es la primera vez que corrio y
el segundo detecta que es la segunda vez que corre y según eso deciden y encaran tareas diferentes.

Como vimos la api encargada de determinar si es la primera vez que se corre el proceso es la api
CreateMutexA, así que en el hijo pongamosle un BP en dicha api.
Allí paro recordamos que el PADRE habia parado en el mismo lugar y creo este Mutex, así que
ahora el Mutex ya existe por lo cual el retorno de la api que era 00, ERROR SUCESS cuando el
padre creo el Mutex, ahora sera 0B7, ERROR ALREADY EXISTS, lleguemos al RET de la api y
verifiquemos.

O sea al tratar de crear algo que ya existia, nos devuelve el mensaje de que ya existe, pues fue
creado por el padre, es muy importante darse cuenta que aquí al detectar el programa que el retorno
de esta api es el tipo de error provocado que es b7,en este caso, y por lo tanto este proceso comienza
a realizar cosas completamente diferentes al padre, por lo cual hay que estudiarlo tranquilamente
como hijo.

Vemos que luego va a la api que le devuelve el ultimo error que ocurrio,con esto el programa
obtiene lo que el OLLYDBG ya nos mostraba el ERROR ALREADY EXISTS de valor B7.
Luego guarda ese valor pero si le colocamos en donde lo guarda un BPM ON ACCESS y damos
RUN, vemos que parara donde lo lee para compararlo.

Allí esta la comparación con 0b7

Allí vemos que si la comparación es verdadera pone EAX a 1 con el SETE, por lo tanto llegamos al
salto desicivo si el proceso es hijo valdrá EAX=1, y si el proceso es PADRE valdrá EAX=0.

En este caso como es el hijo, llega a la comparación y no salta, si fuera el padre en alli saltaria, de
esta forma se explica que este es el punto de bifurcacion de comportamiento de los procesos, hasta
aquí hacen ambos todo igual, pero en este salto, cambian, a partir de aqui el padre va a comprobar si
fue creado por el explorer y luego a CreateProcessA a crear al hijo, y el hijo pues ya veremos que
hace a partir de aquí eso es lo que vamos a estudiar.

Muchos conocen las herramientas de espiar las apis que usa un programa como KAM, APISPY, son
muy utiles pues nos loguean las apis que usa un programa y así podemos tener una idea de lo que
esta tratando de hacer sin tracear tanto, bueno haremos una expecie de KAM casero con el OLLY,
que nos permitira ir saltando de api en api, así ganamos tiempo y es una ayuda en el estudio de este
tipo de programas largos y densos.

Como hacemos esto, pues en el HIJO buscamos la IAT de la dll, buscamos por allí sin tracear, un
CALL a una api subiendo en el listado.
Allí tengo el CALL a una api, veo que toma valores de 1000c034, la cual sera una entrada de la iat,
la busco en el DUMP.

La IAT es esta busco el INICIO y FINAL y le coloco un BPM ON ACCESS que abarque toda la
IAT.

Listo y busco la IAT en el padre y también allí hare mi KAM casero, por supuesto esta ubicada en
la misma dirección.
Bueno ya tengo ambos hechos unos KAM caseros, cabe señalar que con este metodo parara en las
apis de la IAT de la dll, si llegara a leer apis con GetProcAddress que no están en la IAT, y vemos
que son importantes, pues en ese caso deberiamos colocarle un HARDWARE BPX ON ACCESS
en las que consideramos importantes, igualmente este no es el caso, lo importante lo realiza con las
api de la IAT así que mis KAM funcionaran sin agregar nada jeje.

Volvamos al hijo y vamos apretando F9 y mirando en que apis para, y ademas cada vez que para
podemos mirar los parámetros que usa, mi OLLYKAM esta que arde jeje.

Jeje cuantas horas de traceo ahorra esto, la primera vez que para el hijo lo hace en CreateMutexA
nuevamente a crear un Mutex que no existe aun llamado.

Recordemos que el anterior que estudiamos y que fue creado por el padre se llamaba
MYFIRSTINSTANCE.

Así que este sera MYMAININSTANCE, pues casualmente los nombres nos dicen todo el
MYFIRSTINSTANCE o sea mi primera instancia, fue creado por el padre y
MYMAININSTANCE o sea mi instancia principal que es donde correra el programa, por eso lo de
principal, fue creado por el HIJO.

Apretamos f8 para pasar la api y sera logicamente


Pues allí tenemos el resultado, no creo que esto influya mucho creo que es una segunda
comprobacion de que estamos en el proceso HIJO así que como mas procesos no crea, no
perseguiremos el valor hasta la comparación creo que no es importante en este caso, demos f9
movamos nuestro OLLYKAM hasta la siguiente api jeje.

La siguiente api sera logicamente la que da como resultado el ultimo error, para ver el resultado del
CreateMutexA, sigamos con f9 saltando de api en api.

Para hallar el handle del proceso actual seguramente para hacer algunos cambios en el, sabemos que
esta api devuelve FFFFFFFF que es el handle del mismo proceso, apretamos f8 y

jeje apretemos f9 sigamos con el OLLYKAM

El que aun no esta bien familiarizado con las apis este es un buen ejercicio, si estuvieramos en un
examen oral y yo fuera el maestro, le preguntaria que devuelve esta api? Jeje a esta altura debemos
saberlo y si no miramos el wainapi32 y lo vemos, y si no apretamos f8 y aprendemos jeje.

Y si como el parámetro es el la ntdll.dll al apretar f8 nos dara la base de dicha dll la que servira
luego en GetProcessAddress como parámetro para hallar la dirección de una api nueva.
Apreto f8 y allí esta en EAX, la base de dicha dll, seguro ira a GetProcAddress jeje apretemos f9 a
ver si acierto.

Bueno no era tan dificil de ver estaba justo debajo jeje.

Los parametros de la api son

Hmm esto le dara al programa la direccion de dicha api, f9 again

Pues si va a parchear una api de este mismo proceso, es parte del sistema antiattach que esta
implementando, pero como nosotros ya estamos dentro pues solo lo mencionamos para el que le
interesa estudiarlo, aquí cambiara el permiso de dicha api, para poder escribir en ella.
Y con la api WriteProcessMemory hara los cambios, vemos en los parametros

Que esta por escribir en este mismo proceso de ahi el handle FFFFFFFF en la direccion de la api
que averiguo y que escribira un solo byte, miremos alli a ver que hay.

vemos como alli llama a DbgBreakPoint si recordamos al atchear para en DbgBreakPoint, asi que
esto tiene que ver con eso, al ejecutar la api veamos que cambia aquí.

Pues anulo la api con un RET directamente en el INICIO de la misma, sigamos con nuestro
OLLYKAM que nos enseña mucho sobre el programa lo que esta haciendo y las apis que usa y para
que.

Otra vez sacar la base de una dll en este caso la misma que antes ntdll.dll

Vemos que va a GetProcAddress a buscar la direccion de DbgBreakPoint seguramente para


parchearla tambien.

Y si alli le colocara permiso de lectura-escritura, sigamos

Hara los cambios, veamos los parametros.

Cambiara un solo byte en la api DbgBreakPoint veamos como queda

Al apretar F8 cambia la api a

O sea le quita el INT3 que seguro provoca una excepcion para poder atachearnos, al cambiarlo por
un RET seguro que no dejara hacerlo, bueno el que queria aprender un sistema antiatach el
OLLYKAM nos lo mostro y enseño jeje, sigamos con F9.

Llega a la api OpenMutexA que es otra api que se usa para trabajar con Mutex , recordemos que
este fue creado por el padre cualquier duda siempre mirar la ventana handles, en el padre si vemos
en la ventana de handles alli esta el Mutex llamado WAIT creado.

En la del hijo aun no esta pues nunca fue llamado, ahora con OpenMutexA, lo abrira y al recibir un
handle podra trabajar con el mismo Mutex.

Vemos que le otorgo un handle como a todos los objetos que se abren si la operación es correcta.

Ahora si en el hijo aparece el mismo Mutex ya que lo acaba de cargar sigamos con f9.
Al comparar el handle obtenido y ver que no es cero, o sea que el objeto ya habia sido creado por el
padre y pudo obtener un handle, evita la llamada a ExitProcess al saltar, asi que otra comprobacion
mas que de no ser correcta nos hubiera llevado a que se cierre el HIJO y bye bye.

Bueno aquí tenemos otro punto critico en el HIJO esta llamada a WaitForSingleObject, los que
estuvieron luchando con el patrick, saben que el hijo a los pocos segundos si el padre no hace
ciertas cosas o esta loopeando, o perdes tiempo, el HIJO se cierra, pues aquí esta la culpable de
todo.

Veamos los parametros:

Vemos que el primero es el handle del MUTEX llamado WAIT o sea que el nombre WAIT nos lo
dice todo, esta puesto para que aquí el hijo espere que el padre haga ciertas cosas y luego de ello al
liberar el Mutex WAIT, el hijo pueda continuar, eso esta bien, el problema es el otro parametro de
tiempo que es 5000 ms, o sea que si en ese tiempo el hijo no recibe del padre la liberacion del
Mutex, pues se cierra por tiempo, y lamento decirles que se cierra el hijo tambien, si miramos un
poco lo que sigue despues de esta api sin tracear.
Veo que hay una comparacion con cero y según el resultado pues evita el JMP que nos lleva a
ExitProcess.
O sea para que no se cierre el HIJO debe salir de esta api, no por tiempo si no porque el padre libero
el Mutex WAIT, asi que cambiaremos el parametro de tiempo por INFINITO, con lo cual el HIJO
no saldra de la api WaitforSingleObject por tiempo.

Alli cambie el parametro por FFFFFFFF y le coloco un BP luego de la api para que pare cuando el
padre libere al Mutex.

Ahora apreto f9

Y el HIJO quedara RUNNING eternamente mientras el padre no llegue a la parte que libera el
Mutex, asi que aquí en el HIJO no podremos hacer nada quedara RUNNING, en el momento que el
padre libere el Mutex, el hijo parara en el BP que puse a continuacion, mientras quedara RUNNING
para siempre lo que me da tiempo, para ir a seguir el trabajo con el padre.
Recordemos que si no hubieramos cambiado el parametro del tiempo de la api
WaitForSingleObject, en unos milisegundos el HIJO impaciente no lo espera al padre mas y se va a
ExitProcess, jeje que hijo apurado que tiene, nosotros lo corregimos y lo hacemos esperar en forma
educada, jeje.

Volvamos al padre ya que es su turno de trabajar para ello usaremos nuestro OLLYKAM en el
padre asi que apretemos F9 a ver que hace el mismo.

Pasa por la api Sleep que solo le hace perder un poquito de tiempo, luego seguimos con f9 pasando
por distintas apis que no tienen mayor importancia hasta que llegamos aquí.

Veamos los parametros ya que aquí se ejecuta un truco maldito y hay que mirar bien lo que pasa.
Antes de seguir explicando el truco, hay que decir que apenas llegamos aquí a CreateFileA que es la
api encargada de ver si las filas fueron alteradas debemos SI O SI quitar todos los BP, pues estos
alteran el codigo y al comparar nos dara diferencias que luego haran que el programa se desencripte
mal, asi que dejemos los BPM ON ACCESS que usamos para el OLLYKAM, borremos todos los
BP tanto en el PADER COMO EN EL HIJO, y el BP que habiamos puesto para cuando el HIJO
pare al dejar de correr lo reemplazamos por un HE on EXECUTION, si no no, habra problemas al
desencriptarse.

Alli vemos los BP del padre hay que borrarlos a todos, incluso el ONE -SHOT que coloca
OLLYDBG para parar en el EP pues afecta el codigo, por supuesto en el hijo tambien TODOS los
borramos.

Bueno sigamos explicando el truquito con la api CreateFileA, dejando bien sentado que a partir de
aquí nada de BP todos deben ser BPMs o Hes.

Aquí estan lso parametros de la api CreateFileA.

Aquí sucede algo extraño yo lo atribuyo a un bug del OLLYDBG otra explicacion no le encuentro
si alguien luego de leer lo siguiente, conoce porque ocurre esto pues, que me lo diga, jamas lo he
visto como truco antiolly, ni tengo referencias ni conocimiento de que la api CreateFileA pueda
aprovechar un bug del OLLY, mirando en foros busque y no halle nada, puede ser algo novedoso,
algun bug que ha descubierto el amigo FATMIKE, pero la verdad solo por ser VIEJO BICHO del
cracking pude luego de muchisimo esfuerzo darme cuenta de lo que pasaba, tratare de explicar lo
mas claramente lo que ocurre y como se me ocurrio a mi que aquí pasaba algo raro.

Lo primero que ven los que tratan de crackear este programa es que si cambian un solo byte en la
dll y guardan los cambios, la siguiente vez que lo ejecutan, el programa se da cuenta que hay un
byte cambiado y llega al OEP, pero mal descomprimido con toda basura que provoca errores.

Esto es porque el programa debe chequear con CreateFileA la antidebugdll.dll y y luego con
ReadFile leerla y comparar los bytes de los archivos con lso quee stan corriendo y determinar si
son iguales o no, y en ese caso si hay algun byte cambiado, no se descomprime bien, ahora que esto
ocurra cuando cambiamos uno o mas bytes es bastante logico y esperable, pero el problema es que
nosotros no cambiamos ni un solo byte en los archivos, todas las trapisondas que hemos hecho ha
sido en memoria asi que a leer la fila, debera leer los bytes correctos y si no hay Bps pues seran
iguales, sin embargo con OLLYDBG llegabamos al mismo resultado, toda basura mal
desencriptada en el OEP, o sea que algo estaba pasando con el OLLYDBG que hacia que de alguna
forma el programa se comportara como si tenia bytes cambiados al leer la fila.

Bueno este es el comportamiento y llegamos aquí, a la api CreateFileA, con los parametros que
vemos.
La mayoria son comunes y conocidos lo unico que resta mirar es el parametro SHAREMODE, y
que significa FILE_SHARE_READ, veamos en el winapis32.

Pues alli leemos que si el parametro es FILE_SHARE_READ la proxima vez que se llame a la fila
solo sera exitosa la llamada si se hace con el parametro ACCESS = GENERIC READ, ahora te
muestra tambien que si en vez de usar FILE SHARE READ pones cero, las siguientes veces que
intentes acceder a la fila, no se podra, pues la abriste y no se puede compartir.

Asi que ya sabemos, esta vez las cosas estan planteadas asi, si la fila vuelve a ser llamada por
segunda vez con el parametro GENERIC READ debe abrirse correctamente, dicho esto sigamos,
apretemos f8 para ver si nos da el handle.

Hasta aquí todo bien alli nos da el handle y somos felices, sigamos con el OLLYKAM.

Llama a la api CreateFileMappingA que creara una proyeccion de la fila esto lo vimos en los tutes
del nuevo curso igual no tiene mayor importancia en el funcionamiento del programa, aquí obtiene
el handle del filemapping.
Luego llama a la api MapViewOfFile que mapeara con el handle, la fila en la memoria al apretar f8
Tendremos la direccion donde la cargo.

O sea a partir de 9f0000 estan los bytes de la antidebugdll.dll cargados, uno deberia esperar que
compare dichos bytes con los que estan corriendo, pero no, no lo hace, solo compara algunos bytes
del header, pero del codigo del programa nada, alli vemos en el dump los bytes de la dll.

Deben ser similares a los bytes de la dll que esta corriendo,que en este caso estan a partir de
10000000 si vemos alli en el dump vemos que son similares.
Sin embargo a pesar de ser una buena opcion para el programador comparar aquí mismo ya que
tiene los bytes ya cargados y encima no se puede poner BPM ni HE en las secciones creadas con
Filemapping, por lo cual seria lo mas logico dar algunas vueltas para despistar y comenzar a
comparar aquí si hay algun bye modificado, me extraño sobremanera el hecho que solo compara 4 o
5 valores del header lo cual tuve que seguir, traceando con f7 como burro, dada la imposibilidad de
usar BPM ni HE en la seccion 9f0000, pero luego de mucho tracear vi que no comparaba con estos
bytes, lo cual es muy extraño, teniendolos ya a mano y dado que no se puede poner BPM ni HE
pues que mejor, sin embargo no lo hace y esa fue una de las razones por la que sospeche que el
autor algo se traia entre manos, es como si tenes todo servido y lo dejas para volver a hacerlo
masadelante, alguna razon debe haber, aquí mis sospechas se aumentaron, sigamos con el
OLLYKAM.

Aquí lee el tamaño del archivo para comprobar si fue alterado y luego comienza unas
comparaciones bastante ridiculas de la extension de la dll, a ver si es dll, DLL, exe, o EXE, y bueno
alla el, jeje, si tiene ganas de perder el tiempo.

Sigamos
Bueno aquí va a borrar la proyeccion de la fila que habia cargado en 9f0000, asi que no hara mas
nada con esos bytes.

Luego va a cerrar el handle de dicha proyeccion de la fila, con lo cual el caso quedaria cerrado por
alli.

Aquí viene la madre del borrego, llama nuevamente a CreateFileA con estos parametros.

Vemos que usa como decia el winapis32, el parametro ACCESS=GENERIC READ lo cual deberia
entregarnos un handle nuevamente ya que la fila existe, y no hay ningun problema, recordemos que
solo cuando SHARE era cero, en los sucesivos llamados a CreateFileA, no te dara un handle
aunque exista la fila, pero aquí no es asi, esta todo correcto, deberia entregarnos un HANDLE ya
que la fila existe y no hay restricciones por el SHARE, veamos que pasa.

Aquí viene el problema OLLYDBG falla aquí y no se aun porque no me entrega el handle y me da
el FFFFFFFF de error y encima en el mensaje de error me dice ERROR SHARING VIOLATION.
O sea que hay un error en el share, pero como vimos estaba todo bien, no se porque se produce este
error, si es un bug del ollydbg o el mismo se confunde por haber echo un Filemapping justo antes,
la cuestion que despues de mucho investigar llegamos a la conclusion de que OLLYDBG falla aquí.

El hecho de que el programa posteriormente use el handle que deberia entregarnos aquí, para leer la
dll con ReadFile y alli realizar las comparaciones, cunado podia haberlo hecho antes, es una prueba
de que esto ha sido hecho adrede, alguien encontro una falla en el OLLYDBG y la esta provocando
a proposito, de esta forma al no poder leer los bytes de la fila y compararlos, al usar OLLYDBG
ocurrira lo mismo que si hubiera bytes cambiados no se desencriptara bien la fila. Esto eran todas
sospechas que comprobe fehacientemente de la siguiente forma.

Vemos que luego de no obtener un handle va a ReadFile y al tratar de leer con el parametro
FFFFFFFF el retorno de la api en EAX es cero y salta, si tuviera un handle, leeria y no saltaria,
quiere decir que la direccion 10003901 en la imagen, miestras corramos el programa en OLLYDBG
nunca sera accedida, pues la salta por encima al haber un error en ReadFile.
El tema era probar que cuando no usabamos OLLYDBG si pasaba por alli, o sea leia bien, el
retorno de la api era uno, y no saltaba ni evitaba esa zona.

Pues lo hice de una forma media precaria que no explicare demasiado, usando el kerio firewall que
tiene la opcion de colocarle una tilde para que los programas antes de arrancar muestren una caja de
dialogo preguntando si queres que arranquen o no, ejecute un patrick fuera de OLLYDBG y salio la
caja de dialogo, luego abri el pupe y puse un EB FE en la direccion de la ntdll.dll que sabemos que
pasa por alli, en mi maquina 7c9111a4, y acepte la caja de dialogo, luego colocando otro loop unas
lineas antes en 7c911199, quitando el otro y asi sucesivamente poniendo uno y quitando el otro
hasta que la dll es cargada y alli le puse un loop infinito en 10003901, alli quite los loops de la
ntdll para que corra el programa, y el mismo quedo loopeando en la direccion 10003901 donde el
OLLYDBG nunca accede, lo pude atachear y ver que estaba detenido en el punto de la imagen
anterior, en el cual con OLLYDBG nunca pasamos y que solo es posible si en esta CreateFileA,
obtiene un handle valido, asi que si o si OLLYDBG comete un error alli, lo obligaremos a trabajar
bien.

Pues bien debemos forzar a OLLYDBG a que nos de un handle aquí asi que repito todo y llego
nuevamente a esta CreateFileA.

Alli llegue de nuevo, una forma de forzar al OLLYDBG a que nos de el handle como corresponde
es cambiar el parametro SHARE a 1.

Ahi apretamos f8 para pasar la api.


Y tenemos nuestro handle, este truco que parece tan tonto cuando se sabe, me llevo dias de revisar y
revisar a ver que pasaba, asi que no es pavada.

Bueno continuemos con nuestro OLLYKAM.

Ahora si llega a ReadFile y al pasarlo con f8.

Vemos que ahora si EAX=1 como deberia ser y que no salteara la direccion 10003901 como lo
hacia antes.

Una vez que comparo todo cierra el handle


hay que tener cuidado porque este truquito lo usa varias veces asi que atentos, OLLYKAM avanti.

Despues de parar en algunas apis sin importancia llegamos a CreateFileA nuevamente, esta vez por
primera vez leyendo la fila patrick.exe.

Como es la primera vez que para aquí no hay problema, nos da el handle perfectamente para
trabajar con la fila.

Lo mismo que hizo con la antidbgdll.dll ahora con la fila patrick.exe, ahora crea un filemapping, o
proyeccion de fila obtiene el handle del mismo.
Aquí ubica los bytes que lee de la fila y nos da la direccion donde esta ubicado, en este caso en
0Af0000 en mi maquina.

Si miro esa direccion en el dump vere la proyeccion de fila con los bytes que leyo de la fila
patrick.exe.

Por supuesto estos bytes seran similares a los del patrick.exe a partir de 400000.
Como vemos son exactamente iguales, pero al igual que con la dll, compara solamente algunos
punteros del header, pero no la totalidad de la fila, asi que seguimos con f9.

Lo mismo que hizo de verificar la extension, lo hace con el ejecutable patrick.exe.

Luego borra la proyeccion de fila, sin hacer la comparacion completa.

Luego de un par de apis sin importancia, va a cambiar los permisos del hijo en 401000 para
empezar a desencriptarse.
Vemos el handle del hijo y vemos que le dara permiso de lectura -escritura a la seccion que empieza
en 401000.

Alli va a ir a ReadProcessMemory en el call que esta un poco mas abajo vamos alli.

Vemos que va a leer 16 bytes desde 401000 y luego los desencriptara y los guardara en la misma
direccion con WriteProcessMemory, igual aunque no se vean en 401000 los bytes definitivos aun,
no se hagan problema, pues el hijo tambien le da una segunda desencriptada, mas adelante asi que
adelante.
Este loop se va a repetir hasta 406000 que es donde empieza la siguiente seccion asi que con
paciencia tengo apretado la tecla f9 y veo como va aumentando, hasta que cuando va llegando a
406000, voy haciendo mas despacio para no pasarme.

Como veo que estoy llegando suelto la tecla y sigo apretando espaciado para no pasarme cuando
termine.

Cuando termina va a hacer el RealeaseMutex para liberar al hijo y que siga corriendo, recordemos
que el hijo esta RUNNING ahi sin avanzar hasta que el PADRE haga el Realease del Mutex
llamado WAIT.

Si miramos los parametros es el handle 50 en mi maquina.

Vemos que corresponde al Mutex o Mutant como lo llama el OLLY, de nombre WAIT como
esperabamos, asi que el hijo esta RUNNING esperando, pero al apretar F8 se liberara y seguira
corriendo, por eso le puse el BP en la linea siguiente asi para alli al retornar de
WaitforSingleObject.
Como vemos al mismo momento momento que apreto F8 el hijo se libera y para en el HE siguiente.
En este momento los dos procesos estan libres asi que continuemos con el padre a ver si finaliza o
que hace, con nuestro OLLYKAM activado.

Alli tenemos otra espera esta vez del padre que esperara con esta api.

Como vemos puede salir de la api cuando se vence el parametro del tiempo, en este caso, no sera asi
pues el parametro es infinito, asi que solo saldra en el momento que el HIJO haya arrancado y este
esperando alguna entrada de teclado o entrada en general.

Asi como hice la otra vez, le pongo el HE en la linea siguiente y le doy RUN

Ahora el que queda RUNNING es el padre hasta que el hijo crezca, jeje asi que seguiremos
trabajando con el hijo, recordemos activar el OLLYKAM en el HIJO ahora para que pare en cada
api que use el programa.

Ahora el hijo llega a ReleaseMutex donde hara la liberación del Mutex WAIT tambien, pero en
este caso como el padre no esta esperando en un WaitforSingleObject, no se libera continua
RUNNING como vimos hasta que el hijo arranque, asi que continuamos con el HIJO, F9 again.
Vemos que el hijo lee por primerz vez la dll, para chequear su contenido, comoes la primera vez no
hay problema no explicare de nuevo el mismo truco, aquí obtenemos el handle perfectamente.

El mismo truco paso a paso que realizo el padre anteriormente.


Aquí llega al momento clave

Como la vez anterior correjimos el BUG cambiando el parametro SHARE a 1.

Asi, nos da el handle perfectamente.

Y luego de un par de apis sin importancia llega a ReadFile con el handle, para leer los bytes de la
fila y compararlos para ver si no hay bytes cambiados.
Luego que chequeo todo va a cerrar el handle.

Ahora CreateFileA al ejecutable patrick.exe

aquí no hay problema nos da el handle.

Lo mismo que hizo el padre no explicaremos lo mismo.

Ahora quiere hacer el mismo truquito con la patrick.exe

cambiamos el SHARE a 1 y no hay problema lo forzamos y nos da el handle.


Seguimos con f9 y llega luego de algunas apis, a ReadFile donde chequeara el contenido de dicha
fila.

Uff otra vez lo mismo cambiamos el SHARE a 1 se supone que si llegaste hasta aquí el truquito ya
lo descubriste.

De nuevo llega a ReadFile a chequear.

Llega a GetCurrentProcess donde hallara el handle del mismo proceso que corre que es FFFFFFFF,
aquí empieza lo bueno ya saliendo de todos los chequeos.

Alli vemos que se va a modificar asi mismo de la misma forma que lo hizo el padre antes mediante
un bucle de ReadProcessMemory y WriteProcessMemory, aquí le da permiso de lectura y escritura
a la seccion code del programa.

Y luego va a WriteProcessMemory

Donde desencripta los primeros 16 bytes al apretar f8 alli los vemos en 401000

vemos que se esta desencriptando correctamente.

Esta quedando una pinturita jeje.


Como la vez anterior mantenemos apretado f9 hasta que estemos cerca de 406000.

vemos que la zona del OEP esta tambien correctamente desencriptada

Luego que termina de desencriptar va a crear los Threads de proteccion alli podemos cambiarlos a
suspendidos, cambiando el parametro a 4.
Esa es la direccion de inicio del primer Thread

Y esta la del segundo donde vemos que hara nuevamente el chequeo de los procesos que estan
corriendo alli se ven las apis para ello.

Lo mejor es cambiarle el parametro CreationFlags a CREATE SUSPENDED

Bueno aquí le quito todos los hardware BPX por si acaso y le pongo un BPM ON ACCESS en la
seccion code del patricio la que se inicia en 401000, y pongo uno BREAK ON ACCESS en la
seccion code del antidebugdll.dll y voy saltando con f9 y increiblemente para aquí.

Supuestamente llegara en breve al OEP asi que sigamos como tenemos un BPM en toda la seccion ,
vamos apretando f9 saltando y quitamos todas las tildes de las excepciones y se produce una aquí.

Porque retorna a la direccion 00000000, pero si no tengo puestas las tildes de exceptions, y le doy
shift + f9, como tengo un BREAK ON ACCESS en la seccion code al darle para el el OEP, hemos
llegado.

Bueno aquí podriamos dumpear, pero lo arreglare de otra forma.

Abro otro PATRICK.exe en un tercer OLLYDBG y cuando para en System Breakpoint


Ahora copiare todos los bytes de la primera seccion del hijo a la primera seccion de este nuevo que
abri.

Alli los copie ahora los pego en la pprimera seccion del que abri, luego guardo los cambios con
COPY TO EXECUTABLE FILE, como veo que la IAT esta toda correcta no hay problema.

Cuando lo reinicio veo que cuando para en SYSTEM STARTUP ya esta el codigo correcto en la
primera seccion el unico problema seria que arranca la maldita dll, asi que antes de eliminarla por
completo le coloco un RET en el EP de la dll.

Y guardo los cambios

Luego lo cargo en peeditor y le cambio todas las secciones a E0000020.


Alli vemos un CALL que nos lleva a la antidebugdll.dl, lo nopeamos.

Guardamos lso cambios y reiniciamos y probamos

Ya con eso corre pero si queremos la frutilla del postre y queremos que no cargue la dll para nada
hacemos esto.
Busco el inicio de la IT en el header es 406f3c.

Esta es la IT recordamos que los 5 primeros DWORDS corresponden a la 1ra dll, veamos cuale s la
primera dll, el 4to dword apunta al nombre de la misma.

O sea que el nombre de la primera dll esta en 40712e, veamos cual es.

Es la WINMM.dll, la segunda es la antidebugdll.dll asi que si copio, los primeros 5 dwords encima
de los segundos anulo la antidebuddll.dll y la primera que cargara sera de nuevo la WINMM.dll,
pero ya no existira la antidebugdll.dll.
Alli esta ahora solo tengo que guardar los cambios y cambiar el inicio de la IT a este nuevo inicio
en 406f50

Guardamos los cambios y al reiniciar cambiamos el inicio de la IT.

y queda asi

guardo los cambios y reinicio vemos que al arrancar ya no carga la dll maldita y corre
perfectamente.
Jeje buen final para el temido patricio,la solcion sencilla era agarrar el patrick.exe y cambiarle el
permiso de la seccion data a 40000040 con lo cual le quitamos todos los permisos y unas lineas
abajo del OEP se produce un error y se abre el OLLYDBG como JIT.
Con eso ya estamos justo debajo el OEP y desempacado, a partir de alli,se puede hacer lo mismo
que himos de copiar y pegar la primera seccion a un tercer OLLYDBG y de cambiar la IT y ya sale
funcionando, jeje

Adios PATRICIO jeje

Ricardo Narvaja
INTRODUCCION AL OLLYDBG PARTE 48

Los que descargaron la parte 46 y 47 apenas salio no leyeron la nota que les agregue, para los que
las descargan a partir de ahora.

LUEGO DE ESCRIBIR LA PARTE 46 y sin haber terminado de solucionar aun el


PATRICK, me di cuenta de este seria un tutorial bastante elevado, para el nivel que veniamos
llevando asi que si alguno le resulta muy complicado tanto la parte 46 como la 47, les aconsejo
saltearlos que despues de estos el 48 ya vuelve al nivel que estabamos y dejarlos para mas
adelante cuando se sientan mas preparados.

Ricardo Narvaja

Y si ocurrio que cuando empece el patrick lo solucione primero con el metodo sencillo que se
explica al final y pense que seria mas facil y resulto terrible, por lo cual quedaron estos tutes como
muy dificiles entre los de la introduccion por ello la nota y si alguien ve que le resulta muy dificil
aun el nivel de esos tutes pues los saltea y sigue por el 48 que continua con el nivel que veniamos
teniendo y mas adelante los puede leer cuando tenga mas practica.

El packer que estudiaremos ahora en profundidad es el PESPIN 1.304 FULL hay muy buenos tutes
de PESPIN, pero realmente hay muy buenos tutes de casi todos los packers en CRACKSLATINOS
si quiero hacer un tute de algo que no hay la tendre dificil pues hay casi de todo.

Bueno llegar al OEP con el PESPIN es lo mas sencillo

Alli tenemos al Pespin detenido en su EP, usaremos el OLLYDBG preparado para buscar OEPs,
que utilizaremos con ese fin.

Vamos al mapa de memoria y alli en la primera seccion luego del header, ponemos un MEMORY
BREAKPOINT ON ACCESS que realmente sera ON EXECUTION, porque si recuerdan este
OLLYDBG esta parcheado para que pare solamente por ejecucion, y saltee los READ Y WRITE.
Nos aseguramos que tengamos todas las tildes puestas en DEBUGGING OPTIONS-
EXCEPTIONS.

Y damos RUN

y luego de un largo cafe, jeje para en el OEP que apenas lo miramos nos damos cuanta que de OEP
no tiene nada pues hay STOLEN BYTES.
Mirando el stack

Vemos que hay mucho codigo ya ejecutado antes de llegar al falso OEP, o sea que hay stolen bytes.

Tambien vemos que si hacemos SEARCH FOR- ALL INTERMODULAR CALLS


hay muy pocas llamadas a apis si seguimos alguna

Alli hallamos unos pocos saltos a apis que estan resueltas y de aquí podemos mirar la IAT.
Alli vemos la IAT y justo en 460F28 esta el final, y si subimos

Vemos entradas redirigidas que si probamos a ver si tienen referencias para ver si pertenecen a la
IAT.

Vemos que no tienen referencias pero si seguimos subiendo vemos que pertenecen a la IAT asi que
sera uno de los tantos trucos que tiene el PESPIN.
Tenemos el INICIO DE LA IAT en 460814, alli a la vista, luego nos detendremos a ver como
repararemos la IAT para que quede correcta.

Volvamos al tema de los stolen bytes alli vemos justo arriba del falso OEP una zona de ceros ideal
para los mismos.

Reiniciemos el OLLYDBG y miremos el stack


Vemos alli que antes de correr el programa, el stack esta en mi maquina en 12ffc4, quiere decir que
si cuando llega al verdadero OEP el stack esta en la misma posicion o sea en 12FFc4, la primera
sentencia que podria ser PUSH EBP se escribira en 12ffc0 justo arriba de esta, asi que busquemos
12FFc0 en el dump y pongamosle un HARDWARE BPX ON WRITE a ver si nos da resultado,
puede que si puede que no, pero el razonamiento es logico.

Alli lo colocamos y damos RUN, esto puede fallar si el programa detecta los hardware bpx o como
en algunos packers si cambia las direcciones del stack a proposito para evitarlo antes de llegar al
OEP, pero bueno intentemos.

Para aquí se ve que es cuando trabaja el unpacker sigamos adelante apretemos F9.

Alli hay un PUSH EBP, podria ser el OEP? Jeje traceemos, por supuesto los JMPS no interesan
pues no cambian ni registros ni el stack.
Aquí vemos una instrucción rara vemos que hace un PUSH y luego le suma un valor al mismo
veamos.

Luego de sumar el valor vemos que queda 450e60 asi que esto es similar a PUSH 450e60.

Luego el mismo truquito realmente es PUSH 4292c8

Sigamos

Alli hay otra sentencia, sigamos


Y bueno son unos cuantos sigamos

Un call lo copiamos exactamente asi luego resolveremos si va a una api o que es cuando arreglemos
la IAT.
Y aquí ya salta al falso OEP asi que ya tenemos los stolen bytes jeje

Si los copiamos a la zona del OEP

Vemos que caben justo y coinciden perfectamente aunque por ahora no haremos el dump ya
tenemos localizados los stolen bytes, en la parte 49 veremos como empezar a tallar con la IAT.

09/07/06
Hasta la parte 49
Ricardo Narvaja
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 49

Bueno aquí vamos con la reparación de la IAT del pespin que no es moco de pavo realmente, pero
se puede solucionar perfectamente.

Cuando llegamos al supuesto OEP, vimos en la parte anterior la IAT, pero si alguno presto
atencion, vemos que hay llamadas a las apis que no toman valores de la IAT, miremos por ejemplo
esta.

La IAT correcta iria desde

INICIO= 460818
FINAL=460F28

Esa es la IAT CORRECTA del programa, a partir de ahora a la IAT correcta la llamaremos IAT
CORRECTA, jeje.

Habiamos visto que algunas entradas de la IAT, no tenian referencias, y ademas no iban a ninguna
api a pesar de que muestran algunos valores raros que no pertenecen a ningua dll, pero tampoco nos
llevan a ningun redireccionamiento valido, estan llenos como de basura.

Tambien vamos que si hacemos SEARCH FOR INTERMODULAR CALLS


Que hay muchos calls que parecen tomar valores de una segunda especie de IAT que le llamaremos
TABLA por ponerle un nombre para diferenciar de la IAT correcta.

Veamos esta TABLA en el DUMP, cualquiera de estos CALL toma valores de dicha TABLA asi
que elijiendo uno cualquiera.

Lo buscamos en el listado.

Alli esta veamos la TABLA esta.


Vemos que no tiene la organización valida para ser una IAT, pero es una TABLA, de donde parece
saltar a los redireccionamientos de las apis.

Sigamos con FOLLOW a ver si llega a una api.

Luego de un par de saltos mas llega a

y de alli salta a
salta a la 4ta instrucción de una api siendo que antes ejecuto en su propia seccion las primeras 3,
probablemente para evitar que pare en BPs y que no pueda ser identificada facilmente la api, pero
igual si quisiera saber que api es, haciendo en donde se inicia la misma CLICK DERECHO-NEW
ORIGIN HERE, cambiaria el EIP

y el mismo en los registros me mostraria el nombre de la api

Y ahora que lo se, puedo volver al JNZ donde estaba sin problemas.
Bueno pero esto aun esta muy verde sabemos la api que va esa call, pero aun tenemos la IAT
CORRECTA destrozada y los CALLS a las apis que en vez de tomar valores de la IAT correcta,
toman valores de esta TABLA que no nos sirve para repararla.

Pero bueno sabemos que el CALL

va a la api RtlLeaveCriticalSection, eso ya es un dato, asi que podemos usarlo, veremos si podemos
hacerlo en varios pasos, el primero sera, respetando el mismo CALL que toma valores de la
TABLA, quitarle la redireccion de la misma o sea que en este CALL por ejemplo, encontremos un
metodo, para que en la TABLA

En vez de ir a la seccion redireccionada y que luego de varios saltos llegue a la api, directamente
tratar de que esten los valores de las apis correctas, o sea que en este caso en vez de 00A205EC
figure 7C9110ED que es la direccion en mi maquina de dicha api.

Pues para ver donde guarda ese valor en la entrada de la TABLA, pongamosle un HARDWARE
BREAKPOINT ON WRITE alli.
Bueno reiniciemos el programa y corramoslo mirando para pescar cuando guarda el valor
00A205EC en mi maquina, ustedes en la suya deben buscar el correspondiente.

Bueno demos RUN


para varias veces y cuando para aquí el valor esta guardado, sabemos que siempre los
HARDWARE ON WRITE se pasan una linea asi que miremos la linea anterior.

Vemos que la zona esta ofuscada y no se ve nada, pero si nos ponemos en el JMP anterior y
hacemos FOLLOW veremos la linea.

Alli se ve la linea exacta donde guarda el valor malo si miramos los registros.
Vemos que estamos en el lugar correcto.

Y colocamos un HARDWARE BPX ON EXECUTION en la linea que guarda.

Vemos que si doy RUN va incrementando en orden las entradas de la TABLA que se van llenando.
Otra cosa curiosa que hay que remarcar es que veo algo sospechoso en los registro, miremos ahora
cuando guarda otra entrada.
Doy RUN para que guarde la siguiente

Vemos que a medida que en EDI aumentan los valores que recorren la TABLA, tambien aumentan
a la vez en EDX valores que pertenecen a la IAT CORRECTA como que esos son lo valores donde
deberia guardar realmente y no en EDX, bueno dejemoslo esto por ahora, lo que voy a hacer es
reiniciar y llegar hasta donde guarda la entrada anterior a la que estudiamos,

aquí esta llegamos justo cuando guarda en la entrada anterior que es 46f529, o sea que si apretara
(no lo hagan) F9 de nuevo, llegaria al momento que guarda la entrada estudiada.

Pero bueno desde aquí habria que tracear, ya que antes de guardar el valor redireccionado, debera
este calcularlo a partir de la direccion de la api correcta, asi que como sabemos que la siguiente
entrada corresponde a la api RtlLeaveCriticalSection cuya direccion es como habiamos visto
7C9110ED en mi maquina, deberia tracear hasta que en algun registro aparezca esa direccion.

Podria probar hacer un TRACE INTO con esta condicion

EAX==7C9110ED || EBX==7C9110ED || ECX==7C9110ED || EDX==7C9110ED ||


ESI==7C9110ED || EDI==7C9110ED

siempre recordamos que hay que poner doble signo igual y doble signo | que significa o.

O sea que dicha condicion parara el traceo cuando EAX valga 7C9110ED o EBX valga lo mismo o
ECX etc etc o sea cuando algun registro tome ese valor asi que quedaria asi.
Alli esta y le agrego las tildes para que no se detenga cuando pasa por dlls, y la segunda para que no
pierda tiempo repitiendose con los REPS y lo tome como una sola instruccion, hagamoslo tracear
con TRACE INTO.
Y si me voy a tomar un largo café sabiendo que todas esas lineas sino las deberia tracear a mano
jeje, a ver si cuando vuelvo ya paro.

Y si paro aquí al regresar de un CALL que si lo miro en el LOG

Y desde alli del log le hago doble click

Vemos que nos muestra la direccion donde fue en el momento en que el LOG lo guardo al pasar por
alli, asi que este es el punto en que el programa se hace de la direccion de la api, antes de
redireccionarlo a su propia seccion.

Bueno tenemos este primer punto ahora debemos hallar donde saca la diireccion 00A205EC asi
que cambiemos la condicion a

EAX== 00A205EC || EBX== 00A205EC || ECX== 00A205EC || EDX== 00A205EC || ESI==


00A205EC || EDI== 00A205EC
Pues alli tenemos la nueva condicion demosle TRACE INTO.

Pues alli tenemos en EAX la direccion buena de la api y en ESI la direccion redireccionada, asi que
es un buen momento jeje.

Asi que quitare todos los HBP y pondre uno solamente aquí
Reiniciamos y la primera vez que para vemos

Lo mismo que en EAX esta la api buena y en ESI la redireccionada asi que probemos que ocurriria
si cambio esta instrucción por.

Donde guarda la direccion correcta en vez de la redireccionada, quitemos el HBP y demos RUN.

Vemos que arranca igual no detecta el cambio miremos la TABLA.


Vemos que nuestro primer objetivo que era quitar la redireccion de las entradas de esta TABLA se
cumplio ahora tenemos las direcciones de las apis directamente y llena con valores correctos.

Si vemos la entrada que estabamos estudiando

Vemos que ahora es un CALL directo a una API ya no esta redireccionado, lo unico es que toma
valores de la TABLA y no de la IAT, pero ese sera el segundo paso arreglar la IAT y que tome
valores correctos de ella.

Tenemos ahora dos buenos puntos estudiados, uno es 46BBc4 donde al cambiar ESI por EAX le
quitamos la redireccion a la tabla.

El otro punto interesante es donde guardaba que era 46c010 ponemos un HBP ON EXECUTION
en cada uno y reiniciamos.
Primero para aquí donde cambiamos ESI por EAX como vimos.

Damos RUN

Y para cuando va a guardar la api correcta en la TABLA, tambien sabemos que en EDX tenemos la
direccion de la entrada de la IAT correspomdiente pero no podemos cambiar EDI por EDX porque
los calls estan tomando valores de la TABLA y no de la IAT y el programa no correra, pero lo que
si podemos hacer es lo siguiente.

Sabemos que desde ese JUMP va a la instrucción que guarda y lo que hay entremedio es basura
aquí que nopeamos el JMP ya que no necesitara saltar y la basura intermedia.
Quedo asi

Alli quedo solo la instrucción que guarda en la TABLA le agregaremos una instrucción que guarde
tambien en la entrada correcta de la IAT la direccion de la api.

Alli tenemos, ahora guarda la api correcta en ambas, tanto en la IAT como en la TABLA con lo
cual el funcionamiento se mantiene, quitemos los HBP volvamos un paso atrás para que se ejecute
el mov que agregamos.

Si aquí mismo colocamos UN BPM ON ACCESS en la seccion CODE y damos RUN llegamos al
supuesto OEP.

Alli llegamos al falso OEP veamos ambas tablas si vemos el CALL que esta justo debajo
vemos que la TABLA tiene valores correctos pero veamos la IAT

Vemos que la IAT tambien esta reparada ahora solo nos queda cambiar para que el programa tome
valores de la IAT y no de la TABLA lo cual es muy sencillo de realizar con un simple script, que
busque los CALLs y vea a que api va y busque esa api en la IAT y cambie a que lea de alli en vez
de desde la tabla.

Aquí esta como deberia ser el mismo explicado paso a paso, pero antes de explicar el script le
ponemos los stolen bytes.

Bueno el script es este quizas no es perfecto pero se la banca jeje, veamoslo


var call
var tabla
var api
var iat
var programa
var end

mov programa,401000
mov iat,460818

start:

findop programa, #FF15??#


log $RESULT

mov call,$RESULT

cmp call,0
je final
cmp call,44904b
jae final

sigue:

add call,2
log call

mov tabla,[call]
log tabla
mov api, [tabla]
log api
cmp api,50000000
jb saltar

loop:

cmp api, [iat]


je solucionar
add iat,4
cmp iat,460f28
jae saltar
jmp loop

solucionar:
log iat
log call
mov [call],iat
cmp call,449068
jae final

saltar:

sti
mov eip,4271f7
mov programa,call
log programa
mov iat,460818
jmp start

final:
ret

------------------------------------------------------------------------------------------------------------

Lo explicaremos un poco:

var call
var tabla
var api
var iat
var programa
var end

Bueno esta es la declaración de las variables auxiliares que necesita el programa, luego veremos
para que es cada una.

mov programa,401000
mov iat,460818

aquí le colocamos los valores iniciales, a la variable programa le colocamos la direccion de inicio
de la seccion code que es desde donde debe empezar a buscar los calls, y a la variable iat, le
colocamos la direccion de inicio de la IAT.

start:

findop programa, #FF15??#


log $RESULT

aquí realmente comienza la ejecucion del script le colocamos la etiqueta start y utilizamos el
comando findop para hallar el primer opcode que comienza con FF 15 o sea un CALL
INDIRECTO.
Los log son solamente de control, pueden no estar, simplemente para ir llevando la cuenta de lo que
se va haciendo en el LOG del OLLYDBG, asi que no los aclarare mas.

mov call,$RESULT
cmp call,0
je final
cmp call,44904b
jae final

La primera direccion del call indirecto se la pasamos a la variable CALL, y comparamos si no es


cero, en caso de no encontrar ningun CALL INDIRECTO pues el resultado es cero y se va al final
del programa, lo mismo que chequea si ya arreglo el ultimo CALL INDIRECTO de la seccion code
y si es mas alta la direccion que ese ultimo call, pues tambien se termina.

sigue:

add call,2
log call

mov tabla,[call]
log tabla
mov api, [tabla]
log api
cmp api,50000000
jb saltar

aquí lo que hace es sumarle dos a la direccion del call, para apuntar adonde esta guardado la
direccion indirecta o sea dos bytes mas adelante, justo a continuacion de FF 15.

Luego mueve la direccion de la entrada de la TABLA a la variable tabla, y mueve la api


correspondiente a la variable api, esa es la api que hay que averiguar en donde este en la IAT.

Hago un chequeo por si acaso ya que las direcciones de las apis en este caso son en mi maquina
mayores que 50000000, pues si llega a ser menor salta al proximo valor o sea que no es una api y
no cambia nada.

loop:

cmp api, [iat]


je solucionar
add iat,4
cmp iat,460f28
jae saltar
jmp loop

Ya tenemos el valor de la api, y en este loop la buscamos en la IAT, cuando la encuentra salta a
solucionar.

solucionar:
log iat
log call
mov [call],iat

donde mueve la entrada de la IAT a la posicion que apunta call o sea a continuacion d ellos bytes
FF 15.
Esa es la explicacion del script realmente como funciona, luego cambia para que busque a partir de
aquí, moviendo a programa al valor de call para que busque de alli para adelante y siga con el
siguiente, y tambien se coloca la iat nuevamente en su inicio para buscar la siguiente api.

sti
mov eip,4271f7

estas dos lineas realmente no sirven para nada, pero el OLLYSCRIPT debe ejecutar algo del
programa y no solo buscar y cambiar valores si no a la larga se cuelga, por lo cual le hago hacer con
STI un f7, o sea un paso adelante, y luego vuelvo atrás al falso oep nuevamente con eso evito que se
cuelgue.

Lamentablemente a veces el OLLYDBG cuando algun script cambia muchos bytes me saca un
MESSAGEBOX de que hay mas de 1000 parches, pero si lo acepto varias veces termina el script y
repara todo.

Bueno una vez reparado todo, puedo dumpear y usar el IMP REC para reparar la IAT

Solamente una entrada basura encontre que la elimine con CUT THUNKS y ahora ejecuto el
crackme reparado y que ocurre no funciona algo falta aun.
Es que alli abajo hay unos antidumps que saltan al header, que el dumpeado no tiene ese codigo en
el mismo pues alli tiene lso datos del header propio de las secciones etc.

Veamos en el search for intermodular calls del original que tenemos aun parado en el oep cuantos
son:
Vemos que la mayoria estan bien reparados miremos bien
Veo que hay unos cuantos para reparar

Bueno como no tengo muchas ganas de trabajar y hacer otro script y dado que para que arranque el
dumpeado no podemos guardar definitivamente tanta cosa en el header, haremos lo siguiente.

Buaquemos en el dumpeado una zona de alrededor de 1000 bytes y que se pueda escribir por
ejemplo esta es buena

Compruebo que existe realmente y no es solo una seccion virtual haciendo VIEW-EXECUTABLE
FILE.
Bueno existe copiemos alli los 1000 bytes del header, que estan en el original que esta parado en el
OEP aun,

Alli esta marco toda esa seccion


Alli la copio y hago BYNARY PASTE en el dumpeado en la zona elegida y guardo los cambios.

Ahora lo unico que tengo que hacer es un injerto que antes de arrancar copie esos bytes al header.
Para ello un poco mas arriba de los bytes escribo un injerto que es un poco molesto, porque justo el
crackme no tiene en la IAT la api VirtualProtect.

Aquí deberiamos usar las apis LoadLibrary y GetProcAddress para obtener mayor compatibilidad
con viejos sistemas y con ellas hallar la direccion de VirtualProtect, pero yo dare una solucion mas
rapida veamos esto:

En verde tenemos la api LoadLibraryA que si esta en la IAT y en celeste esta la api VirtualProtect
que la necesitamos y no esta, pues leeremos la direccion de LoadLibrary y le restaremos los bytes
necesarios para llegar a VirtualProtect ya que la distancia se mantiene al menos en todos los XP.
Alli tenemos la entrada de la IAT de LoadLibrary

La muevo a EAX, veamos cual es la diferencia entre ambas apis.

O sea que si a LoadLibraryA le resto 2a7 llego a VirtualProtect veamos

Siiii pues halle la direccion de una api a partir de otra que esta en la IAT ahora debo darle permiso
al header para que se pueda escribir en el.
Alli esta la api a usar con sus parametros

Alli esta el injerto completo, hago el pushad, luego muevo a EAX la direccion de LoadLibrary a la
cual le resto 2a7 para obtener la de VirtualProtect, luego llamo a dicha api para que cambie el
permiso del header para que se pueda escribir en el, al llamar a VirtualProtect los parametros son

Alli vemos como a partir de 400000 le cambiamos a 1000 bytes, dandole permiso de escritura, y
luego de esto copiamos los bytes del header del original que los teniamos guardado en 45cab0 y los
copiamos a 400000 el lugar correcto, luego hacemos el popad y saltamos al EP.
Lo unico que nos queda es cambiar el EP para que el programa arranque del injerto, para ello en el
header del dumpeado lo cambiamos.

Lo cambiamos por el del injerto 45ca10 o sea 5ca10

ahora guardamos los cambios y voila

Corre como una gacela al viento jeje

Hasta la parte 50
Ricardo Narvaja
17/07/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 50

Bueno vamos a hacer una parte 50 sencilla pues venimos alto, luego del famoso PATRICK y el
PESPIN que es bastante vueltero, este packer es bien sencillo, aunque asi como viene no corre en
ningun OLLYDBG con ninguno de los plugins que yo tengo ni siquiera el advanced plugin que es
el que supuestamente mas protege y ese es el tema, que corra en OLLYDBG lo cual no es nada
dificil y lo lograremos rapidamente y a descansar jejeje.

El packer se llama UnPackMe_ReCrypt0.80.exe y estara adjunto a este tutorial

Bueno el tema es que corra en OLLYDBG y usaremos el OLLYDBG PARCHEADO PARA


BUSCAR OEPs.

Ustedes pueden jugar con la configuracion del plugin, es cierto que esta en fase beta y aun tiene
algunos errores, pero cumple su cometido, aunque en este packer no corre con ninguno de los
ocultadores conocidos por mi que probe.

Ademas el advanced tiene la opcion de reparar las secciones, que por un valor incorrecto en el
header de NumberOfRva me muestra una sola seccion, en vez de todas las existentes.
Bueno solo por eso se gano el lugar por hoy, asi que corramos el programa a ver que pasa.
Alli vemos las secciones correctas si no fuera por el advanced plugin se veria asi

Y nos costaria mas llegar al OEP porque ni si quiera vemos cual es la primera seccion, es cierto que
podemos abrir un PEEDITOR y mirar el largo de la primera seccion y poner un BPM a mano en el
DUMP abarcando todos los bytes, pero la verdad teniendo el plugin para que tanto trabajo jeje.

Si le doy RUN

jeje y chau, y eso que esta superoculto el OLLYDBG veamos que ocurre aceptemos el mensaje,
pausemos si es necesario y miremos el LOG.

Vemos que el programa arranca y nos muestra que es llamada la api OutputDebugStringA que es la
que se suele ultilizar para que el ollydbg se cuelgue con una string larga tipo %$%$%$%$%$%$,
pero veamos un poco que pasa , el advanced y otros plugins, nos protegen contra esos trucos y sin
embargo no corre.

Luego de la llamada a esa api hay una excepcion que no se puede continuar, si coloco un BP
OutputDebugStringA veamos que ocurre.

Como no tengo ganas de tipear siempre los nombres de las apis, pues usare el plugin de mi amigo
Red que es el +BP-OLLY version 2 que por supuesto trae incorporadas las apis mas usuales para
hacer click directamente y colocar el Bp en ellas y la posibilidad de agregar las que nosotros
querramos en forma personalizada.

Vemos como solo haciendo un click se colocan los Bps mas usados y de VB tambien.

Ahora como la api no es muy usada la agrego en personalizados.


Al apretar el boton PERSONALIZAR puedo escribir el Bp a la api que uso, me fijo que este bien
escrita con mayusculas y minusculas y apreto G y la proxima vez que abra ya aparece en los
botones personalizados.

Pues hago click y ya se pone el BP, asi que nunca mas tendre que tipear el nombre de la api para
poner Bps en ella.

Eso si cuando lo corro me da un error grave, asi que Bps no van en esa api en este packer, reinicio
apreto el noton nuevamente y en la comand bar cambio Bp por HE a ver si va mejor

Borro el Bp y doy RUN.


Veo que ahora si para, llego hasta el RET de la api.

Y vuelve de la api aquí

Veo que EAX es diferente de cero y va a ser comparado, veamos que pasa.

Alli vemos el truco EAX es diferente de cero y salta y le suma el valor de EAX al primer valor del
stack

queda asi
Si sigo traceando veo que en la siguiente linea llega a un Ret donde salta al valor que se creo en el
stack.
Como esa direccion no existe se genera una excepcion no continuable, salvo que el manejador de
excepciones lo podria salvar, pero esto fue hecho adrede por lo cual el manejador de excepciones no
lo arreglara y ira directo a finalizar el programa.

Pues si reiniciamos y al retornar de la api OutputDebugStringA cambiamos EAX a cero.

Ahora no salta y le suma uno a EAX con INC EAX o sea que quedara en 1, y se lo sumara al valor
del stack con lo que al llegar al ret.
Vuelve a una direccion existente y no hay error, ahora coloquemos un BPM ON ACCESS en la
primera seccion, a ver si desde aquí llegamos al OEP.

Recordemos que como usamos el OLLYDBG PARCHEADO PARA OEPs solo parara por
ejecucion.

Alli para por ejecucion justo en el OEP.

Lo demas es coser y cantar ya estamos en el OEP veamos si hacemos SEARCH FOR ALL
INTERMODULAR CALLs.

Vemos que las apis son pocas asi que la IAT sera pequeña.
Alli la vemos la IAT abarca desde 402000 hasta 40201C, o sea RVA=2000, SIZE=1c y OEP=1000,
dumpeemos para luego arreglarlo con el IMP REC.

Ahora abro el IMP REC


alli lo repara y lo guarda agregandole la _ antes de la palabra exe en el nombre.

Probemoslo....
Solucionado un packer sencillo para descansar un poco

Hasta la parte 51
Ricardo Narvaja
26/07/06

Anda mungkin juga menyukai