Este documento introduce conceptos básicos sobre el desempaquetado de programas con OllyDBG. Explica que los programas empaquetados ocultan su código original mediante encriptación para dificultar su modificación. El empaquetador UPX se usa como ejemplo para ilustrar cómo redirige la entrada al código de desempaquetado antes de reconstruir y desencriptar el código original en su ubicación. Se demuestra el proceso de desempaquetado paso a paso usando breakpoints que detienen la ejecución cuando se escribe en la sección de có
Este documento introduce conceptos básicos sobre el desempaquetado de programas con OllyDBG. Explica que los programas empaquetados ocultan su código original mediante encriptación para dificultar su modificación. El empaquetador UPX se usa como ejemplo para ilustrar cómo redirige la entrada al código de desempaquetado antes de reconstruir y desencriptar el código original en su ubicación. Se demuestra el proceso de desempaquetado paso a paso usando breakpoints que detienen la ejecución cuando se escribe en la sección de có
Título original
Introduccion Al Cracking Con Ollydbg Partes 31 a 40
Este documento introduce conceptos básicos sobre el desempaquetado de programas con OllyDBG. Explica que los programas empaquetados ocultan su código original mediante encriptación para dificultar su modificación. El empaquetador UPX se usa como ejemplo para ilustrar cómo redirige la entrada al código de desempaquetado antes de reconstruir y desencriptar el código original en su ubicación. Se demuestra el proceso de desempaquetado paso a paso usando breakpoints que detienen la ejecución cuando se escribe en la sección de có
Este documento introduce conceptos básicos sobre el desempaquetado de programas con OllyDBG. Explica que los programas empaquetados ocultan su código original mediante encriptación para dificultar su modificación. El empaquetador UPX se usa como ejemplo para ilustrar cómo redirige la entrada al código de desempaquetado antes de reconstruir y desencriptar el código original en su ubicación. Se demuestra el proceso de desempaquetado paso a paso usando breakpoints que detienen la ejecución cuando se escribe en la sección de có
Descargue como PDF, TXT o lea en línea desde Scribd
Descargar como pdf o txt
Está en la página 1de 207
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 31
NOCIONES INICIALES SOBRE DESEMPACANDO
Ustedes diran este se volvio loco, anuncio una tercera parte de PCODE y ahora comienza con desempacado, lo que pasa es que estoy viendo que en nuestra lista y en muchos crackers que me consultan, estan ansiosos por mejorar su perfomance en el unpacking, y PCODE hay muchos tutes incluso con WKT, ademas que no hay tantos programas hechos con PCODE, que creo que mas vale empezar con el tema de desempacado, ya que packers hay miles, por supuesto no veremos todos aqu pero daremos ideas generales y ejemplos que nos ayudaran a pensar packers que no hemos visto, por nosotros mismos, sin desesperarnos en buscar un tute por alli, (bueno a veces una ayuda puede servir jeje)
En esta primera parte veremos algunos conceptos e ideas basicas que nos serviran para trabajar en unpacking, luego en futuras partes, pondremos manos a la obra, desempacando ejemplos.
Bueno cual es la idea de empacar un programa, antes que nada
Pues ya vimos que un programa desempacado es sencillo de modificar pues los bytes estan accesibles desde el inicio del mismo y no cambian (estan en el ejecutable), el listado es constante, y en cualquier momento podemos modificar cualquier byte sin problemas y guardar los cambios. Si un programa se automodifica y va cambiando a medida que corre, es mas dificil de parchear pues , lo que debes parchear no esta al inicio, y va cambiando a medida que corre el mismo,
De esta manera, un programa empacado, al no tener el codigo original visible en un inicio, el codigo importante del programa original, no puede ser modificado facilmente, ya que no lo hallaremos, al estar encriptado inicialmente.
Pues el tema es que cuando empacas una aplicacin con un determinado packer, este encripta y guarda el codigo original del programa, bien escondido, y le agrega generalmente una o mas secciones,y en ellas le agrega una especie de cargador y redirige el Entry Point hacia este cargador- desempacador.
Como resultado de esto el codigo del programa original no estara visible en el inicio, si arrancamos el programa en OLLYDBG y se detiene, lo hara en el ENTRY POINT del desempacador, desde donde comenzara a ejecutarse.
Este desempacador, buscara la informacion guardada del codigo original encriptado, lo desencriptara y guardara en la ubicacin original, una vez que el proceso de desencriptado ha concluido, saltara el OEP o Original Entry Point que es el punto de entrada que tenia el programa antes de ser empacado, o sea seria la primera linea del codigo original ejecutada.
Buscaremos el empacador mas sencillo que existe, que es el UPX, bajaremos la version con GUI que es mas sencilla de usar se llama GUIPEX y se baja de:
http://www.blueorbsoft.com/guipex/
Bueno lo instalamos en nuestra maquina y lo corremos.
Bueno alli tenemos al empacador mas sencillo, pero que a algunos les ha hecho pasar un mal rato jeje, usaremos como victima el famoso CRACKME DE CRUEHEAD antes que nada abramoslo en OLLYDBG sin empacarlo aun.
Alli lo tenemos abierto en OLLYDBG, el Entry Point es 401000 o sea que si lo corremos, esta seria la primera linea de codigo que se ejecutara.
O sea que si lo empacamos el GUIPEX le agregara y cambiara las secciones, y encriptara el codigo original, y lo guardara en algun lugar, luego cambiara el EntryPoint para que apunte al cargador- desempacador y listo.
Entonces cuando corramos el programa empacado, el desempacador sacara del baul, el codigo original encriptado, lo desencriptara y ubicara en la primera seccion y luego de terminar su trabajo saltara a la primera linea de codigo original que se va a ejecutar, que es el famoso OEP, o ENTRY POINT ORIGINAL, que en nuestro caso ya sabemos que estara en 401000, ya que el programa original empieza alli y esa sera la primera linea que ejecute del mismo.
Logicamente cuando nosotros atacamos un programa empacado, no tenemos el original para comparar y saber cual es el OEP o primera linea del codigo original ejecutado, por lo cual debemos aprender diversas tecnicas para hallarlo, antes que nada practiquemos con el CC (Crackme de Cruehead, jeje para abreviar)
Guardemos una copia del CC en un lugar seguro por ejemplo el escritorio ya que el UPX modificara el que tenemos y necesitamos el original tambien, para comparar.
Abro el GUIPEX
Pues eso, arrastro y suelto el crackme alli
Alli vemos que lo tomo ya que figura el path al crackme, y en COMMANDS elijo COMPRESS para que comprima , pues tambien puedo descomprimir con esta tool, y el resto de las opciones las dejo como muestra la figura.
Una vez hecho eso apreto el boton RUN del GUIPEX para que haga el trabajo. lli vemos el OK de que la operacin ha sido correcta y que el crackme en UPX OUTPUT ha sido kme le cambiare el nombre para diferenciarlo del original le pondre CRACKME
omo vemos el crackme empacado es mas pequeo que el original, en una epoca esto era asi, ahora
A empacado. A este crac UPX.exe
C hay packer que agregan tanto codigo para proteger que son mucho mas grandes los empacados que el original, jeje.
Si ejecutamos el empacado vemos que funciona igual que el original, ahora miremos un poco ambos, abramos dos OLLYDBG uno con el CRACKME UPX.exe y otro con el CRACKME.exe para comparar.
ENTRY POINT DEL CRACKME.exe
ENTRY POINT DEL CRACKME UPX.exe
Como vemos son diferentes el CRACKME UPX cambio el entry point por 409bf0, donde comenzara a ejecutarse el desempacador, y si en este ultimo voy a mirar que hay en la direccion 401000 por supuesto no encuentro ni rastros del codigo original.
Como vemos la primera seccion esta completamente vacia, asi que el packer quito todos estos bytes los encripto y los guardo en alguna parte del codigo, ademas en este caso vacio la primera seccion completa.
En general la mayoria de los packers, crean una propia seccion y se ejecutan desde alli, para tomar los bytes encriptados guardados del codigo original y arreglar la primera seccion, desencriptando el codigo original en ella.
Si miramos nuevamente la rutina del desempacador sin ejecutarla, y bajamos.
Seguimos bajando hasta que vemos
Este es un packer muy inocente, vemos que arranca hace sus desencriptaciones y cuando termina todo su trabajo salta al OEP, sin ni siquiera ocultarlo, al ver los packers actuales da un poco de risa ver esto aun, pero bueno, asi trabaja.
O sea que si pongo un BP en ese J MP
Y doy RUN
Alli paro y como termino de arreglar la primera seccion, salta al OEP o la primera linea original de codigo apretemos F7.
Ahi vemos el OEP con el mismo codigo que el Cracme de Cruehead original, el desempacador termino su trabajo y desencripto todo el codigo original, que como habiamos visto en un inicio no estaba alli, pues todo esto eran ceros, y una vez que termino salto al OEP, para empazar a correr el programa.
Este esquema de funcionamiento de un programa empacado
1)EJ ECUCION DEL DESEMPACADOR 2)REPARACION Y DESENCRIPTADO DE LA SECCION DONDE CORRE EL CODIGO ORIGINAL 3)SALTO AL OEP 4)EJ ECUCION DEL PROGRAMA
Ha sido un esquema que ha funcionado durante aos y muchisimos packers trabajan asi, con el tiempo los programadores de packers se han dado cuenta que debian modificar un poco el esquema y han agregado ardides para ocultar el OEP, y otro trucos que veremos mas adelante, pero normalmente el funcionamiento general es ese.
Reinicio el CRACKME UPX
Obviamente si la primera seccion estaba vacia como en este caso o tenia basura y alli se contruye el codigo original, debera escribir en dicha seccion, por lo cual si uso un BPM ON ACCESS en la misma, parara en la rutina que desencripta el codigo veamos.
Vayamos a M
Vemos que las secciones han sido cambiadas en tamao con respecto al original, el cual vemos sus secciones abajo.
Vemos que la seccion CODE empieza en 401000 y tiene 1000 bytes de largo en el original, meintras que en el CRACKME UPX, cambio la seccion CODE a la que empieza en 409000.
Bueno igual no importa pongamos un BPM ON ACCESS en la primera seccion del empacado a ver si para cuando desempacay damos RUN.
Vemos exactamente que para cuando va a guardar AL=6A en 401000, si vemos el original en 401000.
Vemos que esta guardando el primer byte 6A que el original posee en 401000, si apreto F9 de nuevo, deberia guardar el byte siguiente o sea el 00 que esta a continuacion, veamos.
Y asi podemos seguir byte por byte, mientras guarda los bytes desencriptados y reconstruye el codigo original, por supuesto no todos los packers desempacan en orden ni desde el inicio como este que es buenito, pero vemos el ejemplo de algo lo mas sanito posible para empezar jeje.
Si nos tomamos el trabajo de tracear veremos que esto es un LOOP donde lee un byte de los guardados encriptados, le realiza las operaciones matematicas para desencriptarlo, (sumas, multiplicaciones etc por ejemplo) y cuando obtiene el valor original, lo guarda a continuacion del anterior.
Si quitamos el BPM ON ACCESS, podemos si apretamos ANIMATE INTO, divertirnos viendo como se va llenando la primera seccion con los valores originales somo si fuera una pelicula, hasta que llega al BPX que pusimos que es el J MP al OEP.
Vemos como trabaja el programa desencriptando la seccion CODE
Arriba vemos moviendose y ejecutandose al desempacador transpirando la camiseta en un loop, mientras va llenando la primera seccion de valores originales, hasta que termina y llega al J MP al OEP.
Una vez que para en el J MP estamos nuevamente a un pasito del OEP apretamos F7
Alli estamos en el OEP, porque decimos que no podemos cambiar con OLLYDBG el codigo y guardarlo como lo hacemos habitualmente, jeje.
Si yo por ejemplo agarro los dos primeros bytes 6A 00 y los quiero cambiar por ejemplo por 90 90, y trato de guardar los cambios OLLYDBG me despierta con un
O sea que no puedo hacer eso, porque OLLYDBG no encuentra el codigo en el ejecutable, para cambiarlo.
Pero si insisto y con un EDITOR HEXA pongo 90 90 en 401000 y abro en OLLY el crackme modificado, y voy a mirar que hay en 401000, tendre el 90 90 y a continuacion todos ceros, y cuando el packer corra y guarde los valores originales en la primera seccion, mis cambios seran sobreescritos, por los bytes 6A 00 nuevamente, que el desempacador guardara alli en ejecucion y al llegar al OEP en 401000 tendre 6A 00, por mas que en el archivo esten guardados 90 90, han sido sobreescritos en tiempo de ejecucion por el desempacador.
O sea que si yo quisiera cambiar esos dos bytes realmente, deberia buscar donde lee el desempacador los bytes originales encriptados, ver que operaciones le aplica para transformarlos en originales, asi poder calcular que valor devberian tener ufff, demasiado trabajo mas facil es desempacar el archivo asi puedo cambiar lo que se me antoje cuando quiero, jeje.
Por supuesto hay otras tecnicas para parchear en memoria mediante loaders, que no son motivo de esta parte, los loaders cargan el crackme, esperando que se desempaque en memoria y luego hacen los cambios en alli mismo en la memoria, para que al correr, encuentre los bytes modificados, pero eso es otra historia vamos despacio que despacio se llega jeje ya eso lo veremos mas adelante.
Bueno aqu termina esta breve y sencilla resea inicial, en la parte dos continuaremos investigando el desempacado del famoso CC.
Hasta la parte 32 Ricardo Narvaja 16/02/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 32
En la parte anterior tratamos de dejar claro el concepto de OEP, o sea la primera linea ejecutada del programa original que el 99 por ciento de las veces esta en la primera seccion (aunque aqu en esta parte he puesto uno que no esta en la primera seccin de molesto que soy jeje)
Vimos que cuando llegamos alli, y mirabamos la memoria, el contenido es similar al del original, lo cual nos da la posibilidad de intentar dumpear y generar el archivo mas parecido posible al original para reconstruirlo.
El metodo clasico seria:
1)ENCONTRAR EL OEP 2)DUMPEAR 3)REPARAR LA IAT 4)VERIFICAR SI EL ARCHIVO TIENE ANTIDUMPS O CHEQUEOS QUE LE IMPIDAN CORRER Y REPARARLOS
Este es el metodo clasico que con pequeas variaciones segn el packer, normalmente se utiliza como metodo de trabajo, nos enfocaremos en esta parte en los metodos que podemos utilizar para llegar al OEP, que pueden funcionar en diferentes packers. Hay que decir que muchas veces es necesario probar e intentar, muchas veces estos metodos funcionan, otras veces hay packers que evitan que estos metodos funcionen, por lo cual hay que usar un poco de inventiva, pero teniendo la idea que cual es el punto a hallar (el OEP) veremos como podemos arreglarnos utilizando las herramientas que poseemos.
Por ahora para explicar utilizare el Crackme de Cruehead empacado, mas adelante veremos otros packers, pero en esta explicacion general, el mismo nos servira.
1) MIRAR O BUSCAR OPCODES EN EL LISTADO MUERTO DEL PACKER ANTES DE EJECUTAR
Esto solo puede funcionar en packers inocentes ni se me ocurriria intentarlo en un asprotect por ejemplo jeje, pero a veces sirve buscar los opcodes del J MP LARGO (0E9) o CALL LARGO (0E8), pensando que el packer necesitara un salto o call largo a la primera seccin para llegar al OEP, y rezando que el mismo este presente en el inicio, o sea que no se automodifique el packer jeje.
Pues en este caso seria
Cuando para miro a ver si es un salto a la primera seccin y si no es, apreto CTRL+L para que busque el siguiente E9.
Hago CTRL+L
Empiezo a hallar salto largos que no van a la primera seccion, y asi hasta que llego a
El cual es un salto a la primera seccion al que le puedo poner un BPX y cuando para apretar f7 y estare en el OEP.
Tambien si uno tiene ganas de buscar en el codigo del packer deberia intentar CALL EAX, CALL; EBX, J MP EAX, porque muchos packers utlizan los registros para disimular el salto al OEP, en el caso de estos comandos lo bueno es que como son comandos completos los podemos buscar todos con SEARCH FOR - ALL COMMANDS y ponerle BPX a todos juntos, veamos un ejemplo.
Y en este caso no sale ningun resultado, pero si hubiera varios resultados que me salen en la lista, puedo haces click derecho en los resultados y elegir la opcion de ponerle BPX a todos ellos, y con eso tendria la posibilidad de que pare en los mismos, y alli cuando para fijarme en este caso el valor que toma EAX y si vemos que es un CALL o J MP a la primera seccion, pues apreto f7 y llego.
Este metodo de buscar en el listado muerto no es muy utilizado, porque la mayoria de las rutinas desempacadoras modernas se automodifica, cuidando especialmente de que la parte del salto al OEP no este visible en el inicio, para evitar este tipo de busquedas, pero bueno, mencionamos la posibilidad que en un packer antiguo o malo, puede funcionar.
2)USAR EL BUSCADOR DE OEPs que trae incluido el OLLYDBG
Abramos el crackme UPX y vayamos a DEBUGGING OPTIONS-SFX
Alli vemos las dos opciones que en la pestaa SFX, tiene el OLLYDBG para hallar OEPs, la que esta sealada con rojo es la mas rapida, y la que esta sealada con verde es mas lenta aunque puede funcionar un poco mejor a veces, probemos, pongamos la tilde en la de la flecha roja.
Al reiniciar veo que no funciona en este caso, porque es eso, veamos las instrucciones del caso.
Veo en la ayuda del OLLYDBG que esto solo funciona cuando OLLYDBG detecta que el Entry point esta fuera de la seccion code como en la mayoria de los programas empacados, pero en este caso no nos advrtio OLLYDBG de ello, el problema es que UPX cambia la seccion CODE a esta en la cual se ejecuta el desempacador, por lo cual el EP esta en la misma seccion CODE y OLLYDBG no detecta como que es un empacado y en este caso el metodo no funciona, aunque es raro que un packer realice ese cambio, pues aqu no va.
Pues para poder demostrar como va este metodo, usare otro crackme empacado que adjunto, es el crackme empacado con aspack, otro sencillo packer.
Primero coloco la tilde en su posicion nornal y veo que OLLYDBG me lo reconoce como packer segn su metodo de ver si el EP esta dentro de la seccion CODE.
Y me muestra el cartelito de aviso y al aceptarlo llega al EP.
Ahora cambio la tilde por la de la flecha roja, me fijo que las tildes en EXCEPTIONS esten marcadas para que no pare por excepciones y renicio el programa en OLLYDBG.
Doy RUN.
Vemos que alli para en 404000 que me marca REAL ENTRY POINT OF SFX CODE (aunque no esta en la primera seccion ya veremos que este crackme es un caso especial que se desempaca en la tercera seccion algo inusual pero posible)
.
En este caso el metodo funciono, ese es el OEP, veamos si tarda mucho mas si hubieramos puesto la flecha verde en vez de la roja.
Reinicio y no tarda muchisimo mas ya que el codigo del desempacador es breve, en ambos casos funciono y me dio el OEP correcto.
Siempre debemos recordar cuando termino de usar este metodo de ir y quitar la tilde y volverla a su posicion original, pues si no OLLYDBG no parara en los ENTRY POINTS comunes normalmente y siempre buscara parar en OEPs.
3)USANDO EL OLLYDBG PARCHEADO PARA BUSCAR OEPs
Este es el mismo OLLYDBG que usamos para las partes sobre Visual Basic, que cuando pones un BPM ON ACCESS, para solo por ejecucion y no cuando lee y escribe (ON READ o ON WRITE) y es ideal para hallar OEPS, veamos el caso del UPX, vayamos a M y miremos las secciones.
Alli esta la primera seccion, en ella el desempacador escribira mientras desencripta los bytes originales, y no queremos que pare mientras trabaja, ya que si no, parara miles de veces antes de llegar al OEP cuando lee y escribe, gracias a este OLLYDBG modificado, no para cuando lee y escribe en dicha seccion, si no solo cuando ejecuta, y eso es lo que queremos hallar nosotros, que pare en la primera linea que se ejecuta en la primera seccion la cual sera casi siempre el OEP.
Me fijo en la pestaa EXCEPTIONS que esten todas las tildes marcadas para que no pare por EXCEPCIONES, y doy RUN y me voy a tomar unos mates, (caf o te para los que no son argentinos jeje, aunque yo no tomo mate ju)
Por supuesto este metodo es un poco mas lento por eso le digo que se tomen unos mates, depende el packer puede tardar unos segundos hasta varios minutos.
Cuando vuelvo de los mates esta detenido en el OEP
Si lo hago en el aspack
Doy RUN
Veo que la primera linea ejecutada es esta, veamos que pasa si apreto f7
Vuelve a la rutina del packer, por lo cual le doy RUN de nuevo y vemos que el programa se ejecuta sin parar, porque ocurre esto? Si nos fijamos, cuando halllamos el OEP con OLLYDBG en este caso el packer varia y no se desempaca en la primera seccion por lo cual hay que poner un BPM ON ACCESS en otra seccion y no en la primera, para determinar en cual, podemos correr el crackme sin poner BPM ni nada.
.
Una vez que aparece la ventana del mismo ya sabemos que esta desempacado en memoria, para saber en que seccion esta corriendo, probamos poner BPM ON ACCESS, en cada seccion, si el programa sigue coriendo y no para en OLLYDBG quiere decir que no esta corriendo en esa seccion y probamos la siguiente.
Alli pongo un BPM ON ACCESS en la primera y no pasa nada sigue como si nada, hago lo mismo en la segunda y nada, al poner en la tercera que empieza en 404000.
Veo que para en OLLYDBG, al tratar de ver la ventana del crackme, eso quiere decir que esa es la
hi si se toman unos mates cafes lo que quieran y al volver esta parado en el OEP, jeje, otro 4) EL METODO DEL PUSHAD seccion que se esta ejecutando, asi que repitamos el proceso desde el inicio para buscar el OEP, pero en este caso, poniendo un BPM ON ACCESS en la tercera seccion.
A metodo que suele funcionar bien en muchisimos packers.
ste metodo funciona en una buena cantidad de packers y se basa en lo siguiente, muchos packers eamos el CRACKME UPX
emos el PUSHAD alli en el inicio, a veces puede estar un poco mas adelante, otra veces hay i nosotros pasamos el PUSHAD con f7 E en sus primeras lineas ejecutan un PUSHAD para guardar los valores iniciales de los registros, luego desempacan, y antes de saltar al OEP, recuperan los valores iniciales de los registros con un POPAD.
V
V packers que hacen PUSH de cada registro uno a uno, (PUSH EAX, PUSH EBX, etc) pero para el caso es lo mismo guardan en el stack los valores iniciales de los registros, los cuales recuperan antes de saltar al OEP.
S
Vemos que alli estan guardados los valores iniciales de los registros, y si los lee antes de saltar al OEP podemos ponerle un HARDWARE BPX ON ACCESS en alguno de esos valores para que pare justo cuando lo lea, y estaremos justo antes de saltar al OEP.
Busquemos estos valores en el DUMP, marcando el registro ESP y haciendo FOLLOW IN DUMP
Eso nos mostrara en el DUMP el contenido del stack
Alli vemos los valores que guard, normalmente lo que se hace es marcar el primer byte o los primeros 4 bytes y colocarle un HARDWARE BPX ON ACCESS.
Es lo mismo que sea BYTE o WORD o DWORD, la cuestion es que pare cuando lea ese valor, demos RUN ahora.
Vemos que al ejecutar el POPAD para restaurar esos valores guardados en el stack, los lee y para, y justo abajo tenemos el salto al OEP, asi que estamos de parabienes aqu este metodo funciono de maravilla.
Probemos en el aspack
Alli veo un PUSHAD, lo paso con f7 y luego ESP-FOLLOW IN DUMP
Y doy RUN.
Vemos que para alli justo antes del salto al OEP que en este caso es un PUSH 404000 y luego un RET si traceamos con f7.
Llegamos al OEP perfectamente
Debemos decir que muchos packers nuevos vienen protegidos contra este metodo, pero bueno, hay que conocer de todo, y intentarlo para saber si va o no.
Sigamos con mas metodos posibles.
5) PARA PROGRAMAS EN VISUAL BASIC (NATIVE O PCODE)
Bueno es muy sencillo hallar el OEP de programas de VB empacados, ya que como vimos siempre hay un PUSH y un CALL a la api de VB, al inicio, asi que utilizo el OLLYDBG para VB y cuando arranco el programa y estoy parado en el entry point, voy a M y busco la dll de visual, y en la seccion code de dicha dll, le coloco un BPM ON ACCESS. De esta forma el programa se descomprimira y parara justo en la primera linea que ejecute la dll de visual basic, y en la primera linea del stack tendre la direccion de retorno del call inicial, con lo cual yendo a esa direccion, justo arriba estaran el push y el call incial que se encuentran en el OEP, con lo cual lo habre hallado. Es cierto que el metodo del OLLYDBG modificado para VB tambien funcionara si pongo un BPM ON ACCESS en la primera seccion del programa directamente, pero hay packers que protegen esto muchisimo, por lo cual se pueden intentar ambos metodos y por eso lo dejo asentado aqu ya que ambos funcionan.
No veremos ejemplos en este caso pues es muy sencillo de entender, mas adelante si nos toca un crackme de VB empacado veremos el ejemplo en la practica.
6)METODO DE LAS EXCEPCIONES
Si tenemos un packer que genera muchas excepciones al desempacarse, el metodo es el siguiente, usaremos el crackme bitarts que adjunto.
Lo abrimos en el OLLYDBG para VB, protegido con los plugins necesarios para no ser detectado.
Coloco todas las tildes en EXCEPTIONS y lo corro en OLLYDBG hasta que veo que arranca
una vez que arranco me fijo en el LOG del OLLYDBG apretando L.
Me fijo la ultima excepcion que se produjo, que no sea producida en la primera seccion o sea que no se haya producido en la ejecucion del programa si no antes, en el desempacado, en este caso la ultima se produjo en 46e88f.
Ahora reinicio y quito todas las tildes en exceptions solo dejo la 1ra.
doy RUN y cada vez que para voy pasando con SHIFT+f9 hasta que llego a la ultima que anote,
lli paro como no es la que anote, hago shift +f9 para saltar la excepcion, recordemos que como es
lli estamo ue arranque el varias posibilidades, podemos poner un BPM ON ACCESS en la seccion code, y
Y en este caso 46e88f.
A un INT3 OLLYDBG parara en la direccion justo siguiente o sea 46e890.
A s justo en la ultima excepcion generada por el desempacador, antes q programa.
qu tengo A muchos se preguntaran porque no lo coloque en un inicio, y la respuesta es porque muchos packers pueden detectar el BPM si lo coloco desde el inicio, y al llegar aqu, quizas ya paso la deteccin, probemos si va.
hora no olvidemos que debemos apretar SHIFT mas f9 ya que estamos en una excepcion.
lli paro en el OEP, podemos probar si el packer detectaba el BPM realizando esto mismo desde el einicio y coloco todas las tildes en exceptions nuevamente y voy a M y le coloco un BPM ON
emos que llego perfectamente pero es bueno conocer el metodo de las excepciones para cuando el A
A inicio.
R ACCESS en la primera seccion y como estoy usando el OLLYDBG para detectar OEPs pues me voy a tomar unos mates jeje, ya que vemos que en este caso tardara unos cuantos largos minutos, en llegar al OEP.
V BPM ON ACCESS sea detectado por el packer y en ese caso hay que llegar lo mas cerca posible del OEP, para evitar la deteccion del mismo.
Vemos que en este packer incluso usando el metodo del buscador de OEPs que trae el OLLYDBG
asta el metodo del PUSHAD funciona perfectamente, vemos en el inicio
ue si traceamos con f7 unas lineas llegamos a un PUSHAD
o pasa tambien para perfectamente en el mismo y rapido.
H
Q
L mos con f7 y marcamos ESP-FOLLOW IN DUMP
Damos RUN
Y para cuando lee los valores guardados en ese POP, traceo con f7 hasta el ret al pasarlo llego al OEP.
7)EL METODO DE UNA API MUY USADA POR EL DESEMPACADOR
Reinicio este BIT ARTS con el OLLYDBG para OEPs, con todas las excepciones marcadas y buscare una api muy usada normalmente puede ser GetProcAddress, Load Library tambien es muy usada, ExitThread, esto variara segn el packer, probemos el metodo con GetProcAddress.
Alli veo en la commandbar la direccion de la api le pondre un BP
En la api elegida, al menos debe poder ponersele BP, si no se puede desde la comandbar habra que buscarla a mano y ponerselo directo.
Demos RUN.
Ahora cambiare este BP por un BP CONDICIONAL LOG que no pare, solo LOGUEE.
Ponemos que nunca pare, pero que loguee siempre y que ademas nos loguee el valor de [esp] o sea el valor de retorno, para poder saber desde donde fue llamada la api, limpiamos el LOG, haciendo click derecho-CLEAR LOG.
Damos Run hasta que arranque el programa y miraremos en el LOG la ultima llamada a la api que no sea hecha desde la primera seccion.
Vemos que hay todas llamadas desde el descompresor, hasta que la siguiente es desde 428c2B que ya es desde la primera seccion o sea que corresponde al programa, o sea que la ultima vez que usa el descompresor esta api, es cuando [esp]==47009A, asi que podemos poner como condicion que pare cuando se de eso.
Reiniciemos.
Editemos el BPX CONDICIONAL
Ahora le colocamos la condicion y ponemos la tilde para que pare ON CONDITION
Y damos RUN
Alli vemos que paro, este metodo se puede completar como antes poniendo BPM ON ACCESS en la seccion CODE, para evitar la deteccion del BPM aunque tiene como problema que muchos nuevos packers detectan el BPX en las apis, por lo cual muchas veces conviene no hacerlo en la primera linea de la api si no en el RET de la misma, el metodo es similar, la idea es buscar que pare lo mas cerca posible antes del oep ya sea para poner un BPM ON ACCESS o ya sea para tracear desde aqu con el trazador automatico que tiene el OLLYDBG (TRACE INTO)
Si hemos llegado bastante cerca del OEP, tendremos mas suerte y habremos elegido bien la api, si no, pues deberemos cambiar de api, si miramos el LOG de este programa vemos que una de las cosas que hace antes de arrancar este, es terminar un thread
Por lo cual tanto poner un BP ExitThread como cambiar en el OLLY la configuracion para que pare cada vez que se cierra un thread es posible tambien.
Demos RUN
para alli al terminar el thread
Alli poniendo el BPM ON ACCESS en la seccion CODE parara perfectamente tambien.
8)METODO DE LA PRIMERA API EJECUTADA POR EL PROGRAMA
Este metodo es poner un BP directamente en una api sospechosa de ser la primera que ejecuta el programa, normalmente los programas ejecutan al inicio GetVersion, GetModuleHandleA, con mirar unos cuantos programas desempacados obtendremos una lista de las apis mas usadas al inicio no son muchas, en el caso del bitarts vemos que es GetVersion, en el Cruehead es GetModuleHandleA, por ejemplo probemos en el BIT ARTS con BP GetVersion.
Doy RUN
Me debo asegurar que la llamada sea hecha por el programa o sea, desde la primera seccion.
Cuando para miro el primer valor del stack que es la direccion de retorno y voy alli.
Alli veo el OEP que lo obtuve con el metodo de la primera api utilizada por el programa, si el programa detecta el BP en GetVersion, se puede poner tambien en el RET de la api.
Creo que metodos hay como packers hay y son miles, estos son los ejemplos de los mas usados, ya veran cuando desempaquemos como estos metodos se pueden flexibilizar y adaptar al caso, pero es bueno que tengan una idea de los metodos generales, para poder tener una buena base de los mismos.
Adjunto un crackme para practicar que hallen el OEP el UnPackMe_tElock0.98.exe que tiene algunos trucos y que no le van todos los metodos anteriores, auqnue es bueno que practiquen y hallen el OEP por ustedes mismos.
Recuerden que si un desempacador detecta un BP o HBP, y no corre, deben revisar bien que no haya ningun BP mi HBP puesto, para que vuelva a correr, recuerden que el metodo del PUSHAD deja un HBP puesto que si no funciona el metodo, hay que borrar antes de intentar otro.
Por supuesto el proximo nivel sera un rar con clave, la clave para abrir el mismo sera el OEP del telock0.98 jeje, a practicar y a probar que tienen que ser expertos en hallar OEPs antes de pasar al dumpeo y reparacion de IATs.
Hasta la parte 33 Ricardo Narvaja 20 de febrero de 2006 INTRODUCCION AL CRACKING CON OLLYDBG PARTE 33
Que es la IAT y como repararla
Antes de ponernos a reparar IATs como loco haremos una introduccion de que es exactamente la IAT y veremos en el CRACKME DE CRUEHEAD original donde esta ubicada y que le hace el packer a la misma, comparandolo con el crackmeUPX empacado.
Primero demos una idea generica de para que sirve todo esto que vamos a explicar:
El tema es el siguiente, como vimos las apis tienen una direccion en nustra maquina, por ejemplo si abro el Crackme de Cruehead original en OLLYDBG y tipeo
Veo que en mi maquina la direccion donde se encuentra la api es 77D504EA, si ustedes ven la direccion de esta api en vuestras maquinas, algunos tendran la misma direccion, otros no, depende de la version de Windows que tengan, y de las actualizaciones que hayan bajado tambien, que como saben son muchisimas, y en cada una al bajar nuevas versiones de la dll que contiene la api en este caso User32.dl, generalmente cambiara la direcin.
Cada vez que Microsoft saca una nueva version de esta dll, casi siempre cambiara la direccion de las apis que contiene, por lo tanto si yo programara el Crackme de Cruehead, al saltar a la api MessageBoxA, lo haria saltar a 77D504EA, y funcionaria pefcetamente en mi maquina, y en las que tuvieran la suerte de tener la misma version de User32.dll que yo, en el resto de los demas Windows que o bien no sean XP, o bien no tengan la misma version de la User32.dll, saltaria a una direccion donde no estaria la api, lo cual produciria error y no correria.
El tema entonces es que el sistema operativo debe suministrar alguna forma de compatibilizar para que mi crackme funcione en otros Windows (dentro de ciertos limites) y en otras versiones de la dll debe funcionar perfectamente.
Para ello se crearon estas famosas tablas llamadas IT (Import Table), y IAT (Import Adress Table)
No se austen son puro nombre una vez que uno sabe donde esta ubicada cada una en un programa desempacado y para que sirven no hay mas miedo.
Ahora hagamos SEARCH FOR-ALL INTERMODULAR CALLS y veamos los CALLS que van a otros modulos o dlls, que pueden ser calls a apis.
Alli vemos varios Calls a la api MessageBoxA como ejemplo, si hacemos doble click en el primero de ellos
Vemos que en realidad es un CALL 40143A que OLLYDBG para aclararnos nos pone que saltara a la api MessageBoxA, cambiando la notacion por CALL <MessageBoxA>pero no es un call indirecto, es un call directo
CALL 40143A
emos que en las opciones del OLLYDBG en la pestaa DISASM si le quitamos la tilde a SHOW
emos que igual nos aclara a la derecha los parametros y la api a la cual ira, pero ahora nos muestra ALL 40143A n SEARCH FOR INTERMODULARS CALLS V SIMBOLIC ADDRESSES el listado queda mas claro.
V el CALL realmente como call directo.
C
E
Vemos que en realidad los tres calls a MessageBoxA son calls a 40143A, pues veamos que hay alli.
Aqu vemos el quid de la cuestion, para llegar a la api hace un J MP indirecto, que al tenerlo en esta forma de visualizacion se ve claro que toma el valor a donde saltara de 4031AC
J MP [4031AC]
Tambien vemos que si ponemos la tilde, se nos complica un poco entender que es un salto indirecto, por lo cual la quitaremos mientras estamos trabajando con IATs.
Y aqu esta el truco, el programa salta a la api con un J MP indirecto que toma la direccion que la api tiene en nuestra maquina de 4031AC, y vemos que para todas las otras apis, hay otros J MPS INDIRECTOS similares.
Ahora empezamos a ver un poco mas claro el tema de la compatibilidad entre maquina, cuando el programa tiene que ir a una api, hace un salto indirecto, leyendo la direccion de la api de una especie de deposito, si vemos en el dump este deposito.
Alli vemos realemente que 4031AC es una parte de un deposito que contiene todas las direcciones a las apis en mi maquina, ahora este DEPOSITO es la famosa IAT o IMPORT TABLE ADDRESS, aqu esta la clave de la compatibilidad, quiere decir que todos los programas tendran los mismos J MPS INDIRECTOS a las apis, lo que cambiara es el valor guardado en el deposito, para cada maquina tendra direcciones diferentes que llevaran el salto indirecto, a la direccion correcta de la api.
Pero un momento me diran algunos, 4031AC es una direccion del programa, por lo cual si tiene diferentes direcciones para cada maquina, pues entonces el programa seria diferente para cada maquina?
J eje buena pregunta ahora veremos como funciona el sistema, pero ya sabemos el objetivo, el cual es llenar la IAT de las direcciones correctas para cada maquina.
Sabemos que si hacemos VIEW- EJ ECUTABLE FILE podemos ver lo que hay en la direccion 4031AC, realmente en el archivo ejecutable guardado en nuestro disco rigido.
Vemos que el valor en el exe, es 60 33, y que nosotros parados en el entry point ya tenemos en la memoria en la misma posicion la direccion de la api EA 04 D5 77 guardada alli, quiere decir que el sistema al arrancar el programa, tomo el 3360 que habia alli en el OFFSET 0FAC que corresponde a la direccion 4031ac y lo machaco con el valor de la direccion real de la api en mi maquina.
Magia?
No no asi trabaja Windows, cada archivo que arranca, el sistema operativo llena la IAT de las direcciones correctas de las apis en mi maquina, en este caso lleno 4031AC con el valor de la api MessageBoxA y los valores alrededor, con las direcciones de oras apis, para completar la tabla IAT o deposito de direcciones de las apis en mi maquina.
Ahora el sistema no es mago como hace esto, vemos que en 0FAC tiene un valor 3360, le indicara algo al sistema este puntero, para que sepa que api es la que debe llenar alli?
Pues si 3360 es el valor al cual si le sumamos la imagebase queda 403360 y si miramos en el sump esa direccion que vemos?
Pues aqu esta el truco es un puntero a la string MessageBoxA, eso quiere decir que el sistema mira ese puntero, busca que api es por el nombre y con GetProcAddress, saca la direccion de dicha api en nuestra maquina, y lo completa en la IAT, machacando el 3360, con la direccion real de la api en nuestra maquina, y de esta forma se asegura que el programa funcione para cualquier version de la dll, porque halla la direccion antes de llegar al Entry Point del programa y una vez que llego alli, queda la iat completita con las direcciones de las apis en mi maquina, si miro la iat de otra maquina diferente vere que el contenido de 4031AC es diferente pues la direccion de la api, es diferente, pero cuando haga.
J MP [4031AC]
ira a su MessageBoxA al igual que en mi maquina, el programador no se tiene que preocupar, siempre que haga calls o jmps indirectos al valor que se encuentra en el deposito de la IAT, este estara correcto, al arrancar el sistema coloco en tiempo real la direccion correcta, apuntando a MessageBoxA en todas las maquina para asegurar compatibilidad.
O sea que para que el sistema me complete correctamente la direccion de la api en la iat, debe el archivo tener varios punteros como vimos.
1)en la entrada de la iat en el ejecutable en mi rigido, debe tener un puntero a una cadena de texto que le identifique al sistema que api debe colocar en esa entrada. 2)Por supuesto debe tener la cadena de texto con el nombre de la api
Pues con estos dos puntos, podemos cocluir que el programa arrancara y el sistema me llenara la IAT con los valores correctos. (mas adelante veremos el trabajo cmpleto de este sistema)
Ahora ya vimos como llegamos al OEP de un programa empacado, porque se dice que cuando llegamos alli y dumpeamos un programa debemos reconstruir la IAT, los packers la rompen? Que hacen con ella, pues si la rompen algunos mas otros menos, el truco es que el packer no necesita la iat del programa en si porque arranca desde el mismo desempacador, y puede leer las apis que deberian ir en la IAT, mientras va desempacando el programa, y una vez que leyo cada api, y lleno la iat con las direcciones correctas de cada api, pues las strings que le indicaron cual era cada api, las borrara, ya no las necesita, pues el programa ya arranco y tiene ya en la IAT las direcciones correctas.
Es mas en los packers ni siquiera existen esas strings ya que el programa o bien las guarda encriptadas o bien las guarda en alguna otra direccion que no sean facil de hallar por nosotros los crackers.
Veamos el ejemplo con el empacado UPX para ver la diferencia y como nos queda al dumpearlo, y porque hay que repararlo.
Aqu tenemos el Crackme de Cruehead que esta empacado con UPX que habiamos hecho en partes anteriores.
Miremos la direccion 4031AC donde estaba el deposito de apis en el original
ada borro todo, y las strings de las apis estaban en 403360 que haya alli?
ada, de nada, lleguemos al oep y veamos que hay en estas mismas direcciones, ya que para que el MP [4031ac] estar vacio dara error, o sea que el packer hara el trabajo que hace normalmente el sistema y
n
N programa corra en la iat debe haber algo si no al saltar a la api, y hacer
J
y llenara la iat, lleguemos al OEP.
Ponemos un BP en el salto al OEP y damos RUN y llegamos alli
Veamos que hay en el lugar de la iat
Vemos que para que el programa funcione el desempacador lleno la iat con las direcciones correctas de la api en mi maquina, pero si nosotros dumpeamos aqu habra un problema, el ejecutable que salga del dumpeado le faltan datos para arrancar.
Ya de por si las strings que identificaban cada api y estaban en 403360 no estan
Veamos hagamos un dumpeado a ver que queda, pero ya nos damos cuenta que tendremos el codigo del programa correcto, pero el dumpeado no correra al no poder el sistema llenar la iat por falta de datos.
Por ahora utilizaremos un programa externo al OLLYDBG para dumpear este es el LORDPE DELUXE que se puede bajar desde mi HTTP.
Alli tenemos al LORD PE DELUXE busquemos el proceso a dumpear que es el crackmeUPX que tenemos detenido en el OEP.
Alli esta el crackmeUPX, marquemoslo
Haciendo click derecho cambiemos a INTELLIDUMP que dicen que es mejor dumpeando, jeje y luego hagamos click en DUMP FULL.
Lo hemos guardado con el nombre DUMPED.exe
Si corremos el dumpeado vemos que no arranca tratemos de abrirlo en OLLYDBG
Y nos da el mismo error pero si vemos el LOG del OLLYDBG los errores
El error se produjo en 7c929913 en mi maquina vayamos a esta direccion, ustedes en su maquina a la direccion que figure en el LOG.
Le pondre un HARDWARE BREAKPINT ON EXECUTION y un BP a ver si para antes de dar el error.
Pues veo que no para, pero tengo otra forma de parar en un error y es quitarle la tilde a las excepciones, al reiniciar
Vemos que si para antes de llegar al Entry Point en el error que no deja arrancar al dumpeado,.
Ya que estamos miremos que hay en la iat
Alli vemos que el dumpeador, logcamente guardo los valores que habia en la iat al momento de llegar al OEP que son los valores correctos en mi maquina de cada API, pero el tema como habiamos visto es que para que un exe arranque sin error y en cualquier maquina, en el ejecutable, alli debe haber un puntero a cada string con el nombre de la api, y el ejecutable contiene el mismo valor este que estamos viendo, que el sistema esta tratando de leer y al no hallar el puntero a la string de la api, le da error.
Pues no hay que ser un genio para darse cuanta que para que arranque el programa hay que restaurar los nombres de las apis, y los punteros a ellas,si quisiera hacerlo a mano es un trabajo terrible deberia cambiar el contenido de 4031AC por un puntero a la string de MessageBoxA y con ciertos arreglos de algunos punteros, pues arrancaria.
Aqu tenemos planteado el desafio, esto es lo que debemos reparar para que nuestro dumpeado ademas de tener el codigo correcto, que por supuesto lo tiene, corra perfectamente.
De que tiene el codigo correcto no hay duda vayamos a 401000 y miremos que hay alli
Si vamos a la zona de los saltos a las apis
Alli vemos el call a la MessageBoxA que habiamos visto anteriormente
En el CALL el codigo esta correcto, nos lleva al mismo J UMP que antes
Los J UMPS estan lo unico que falta es hacer funcionar el sistema de que llene la IAT con el contenido correcto, para que tenga en la misma antes de correr el programa, los punteros a las strings y que el sistema lo llene con las direciones correctas sin error.
Antes de acometer esta tarea veremos las definiciones y ubicacin correcta en el programa original sin empacar de la IAT y la IT.
Abramos el CC original en OLLYDBG.
Bueno ubicaremos las partes que hacen que este sistema funcione bien en el original.
En el header, tenemos algunos punteros importantes.
Vayamos al mismo
hora cambiemoslo a modo SPECIAL-PE HEADER
ajemos
os datos realmente empiezan en 100 donde comienza la PE SIGNATURE
A
B
L
El chico no miente alli empieza jeje en 400100 o sea en offset 100.
alli tenemos los punteros a la IT o sea la Import Table que no debemos confundirla con la IAT a pesar de que tengan nombres parecidos.
IT=IMPORT TABLE IAT=IMPORT ADDRESS TABLE
Como ya vimos la IAT es el deposito donde el sistema guarda las direcciones correctas de mi maquina al arrancar, y que es la IT, pues vayamos alli, como vemos dice que empieza en 3000 (403000) y su largo es 670 o sea que termina en 403670, vayamos a mirar.
Como esta fuera del header quitamos el MODO SPECIAL-PE HEADER
Esto que parece un chorizo sin interpretacion posible, es facil de interpretar, si sabemos que es cada cosa, lo detallaremos y veran que esto es muy importante.
Esto es la famosa IT, aqu la tenemos si comprendemos esto, y aunque no sepamos los nombres de cada puntero, sepamos que es cada cosa y donde apunta, pues estamos salvados.
Lo malo que tenemos para explicar esto en OLLYDBG es que es mucho mas comodo y visible hacerlo en una visualizacion de 5 columnas asi queda ordenado, ya veremos por que.
La famosa IT esta compuesta por los denominados IMAGE IMPORT DESCRIPTORs que son varias lineas de 5 valores dword, de la cual hay una por cada dll que cargara el programa.
Veamos la IT, por eso les digo que esto se ve mejor con 5 columnas para ordenar cada IID uno en cada linea.
Pero bueno no nos queda otra aqu vemos el primero
Ese es el primer IID de nuestra IT y tiene 5 DWORDS cuyos nombres son estos
OriginalFirtsThunks. TimeDateStamp. ForwarderChain. Puntero al nombre de la dll. FirtsThunk (Apunta a donde debe buscar en la IAT la primera entrada de dicha dll).
Los tres primeros no son importantes para el cracking hasta siendo cero, normalmente arranca igual el programa, son para usos muy determinados, los importantes son el 4 y el 5to puntero de nuestro primer IID.
Alli esta como vemos el 4to apunta al nombre de la dll a la cual pertenece este IID, veamos cual es la dll en 403290.
Alli esta la primera dll que el sistema buscara es USER32.dll y el 5to puntero marca donde comienza en la IAT las entradas de esta dll, en este caso es 403184.
Alli esta es la IAT, y su primera entrada, todo esto esta dentro de la IT, ya que terminaba en 403670, asi que tenemos que la famosa IT, tiene una linea para cada dll, estas lineas son llamadas IID o IMAGE IMPORT DESCRIPTOR y dentro de la IT esta la IAT o deposito de las direcciones de las apis, todo compacto y para el uso del sistema.
Muchos crackres experimentados diran que no siempre la IAT esta dentro de la IT, ya que el 5to puntero de cada IID puede apuntar a cualquier lado y tranquilamente puede estar fuera, ubicada en cualquier lugar del programa que tenga permiso de escritura, para que cuando arranque el exe, alli el sistema vaya guardando las direcciones correctas de las apis, la cuestion es que ya vemos como trabaja mejor el sistema para llenar la IAT,
1) Busca la IT 2) Busca la primera IID y se fija en el 4to puntero a que dll pertenece 3) Luego mira en el 5to puntero donde esta la primera entrada de la IAT 4) Alli hay un puntero a la string con el nombre de la api 5) Con GetProcAddress busca la direccion y la guarda en la misma entrada. 6) Cuando encuentra en la IAT una entrada con ceros, eso le indica que termino la primera dll y que debe pasar a mirar el segundo IID para buscar cual es la segunda, y repetir el proceso.
O sea que si el sistema hara esto en imagenes y es importante que lo entiendan bien porque si al sistema le falta algo o encuentra punteros incorrectos dara error y es importante entenderlo a fondo.
1)Busca la direccion de la IT
2)Va a esa direccion
3)En el primer IID busca el 4to DWORD que le apunta al nombre de la dll donde empezara a trabajar en este caso sera USER32.dll.
Luego mira el 5to puntero para buscar la primera entrada de la IAT que es 403184 y va alli.
Alli lee el valor que no es ese pues alli ya esta machacado, sino el que esta en el ejecutable, veamos
alli ve que el nombre de la primera api esta en 4032CC, va alli
Ve que la primera api es KillTimer con GetProcAddress halla su direccion que nosotros hallamos con el OLLYDBG.
Y ese valor que en mi maquina es 77d18c42 lo guarda en la misma entrada de la IAT machacando el existente.
Alli lo vemos es la primera entrada de la IAT ya cuando llego al entry point y muestra el valor que tiene esa api en mi maquina.
Asi saltara a la siguiente entrada de la IAT, que halla facilmente sumandole 4 a esta, y busca el siguiente puntero al nombre de la proxima api.
Por supuesto mira en el ejecutable y este es
32d8 o sea 4032d8, mira el nombre de la api siguiente alli y como no hallo un cero en la entrada, sabe que continua con las apis de user32.dll.
La segunda api es GetSystemMetrics hallara la direccion y la guardara en la segunda entrada de la iat y asi, seguira buscando apis en user32.dll hasta que llegue a una entrada con todos ceros si vemos la iat en el ejecutable.
Vemos que seguira buscando en user32.dll hasta que halle ese cero donde retorna al siguiente IID
Cuyos 4 y 5to puntero son esos, el 4to le dice que en 40329b esta el nombre de la 2 dll donde buscara nombres.
Que es Kernel32.dll y la primera entrada de la iat donde buscara sera la que esta a continuacion del cero o sea 40321c.
Alli vemos el cero que determino que no hay mas apis de user32.dll y en 40321c empiezan las de Kernel32.dll donde buscara en el ejecutable el primer puntero a la string y llenara aqu con el valor de la api correcta.
Creo que es muy importante entender bien esto, trate de explicarlo y repetirlo varias veces para que quede pero creo que con solo una leida eso no queda en la mente traten de grabarselo con fuego pues esto es la base de todo el tema de la reconstruccion de las IATs y aunque ya veremos en la parte siguiente que hay tools que nos ayudan a hacer el trabajo pesado sin tener que revisar todo esto, es muy importante saber como trabaja todo, asi cualquier problema o caso raro, no nos quedaremos a un costado del camino y siempre podremos entender que esta pasando.
En la parte siguiente arreglaremos IATs no lloren jeje ya tienen suficiente con comprender como trabajan por ahora jejejejeje.
Hasta la 34 Riardo Narvaja 27/02/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 34
En la parte 33 vimos como funciona el sistema de la IT y IAT, yo se y los que saben reparar una IAT, pueden pensar que no es necesario saber como funciona, ya que hay tools que reparan una iat casi automaticamente, pero yo les aseguro que es bueno saber como funciona y que ocurre en cada momento, porque hay muchos packers que engaan a las tools y las hacen fallar, por lo cual en esos casos hay que saber razonar y pensar que esta pasando para hacer alguna correcion a mano, o poder moverse con facilidad.
Empezaremos con algo facil el Crackme de Cruehead empacado con UPX, realizaremos el proceso de desempacado completo aqu para unir todo lo que vimos y al final repararemos la IAT, para que quede funcional.
Como vimos el primer paso era llegar al OEP, por lo cual abro en OLLYDBG el CC o sea el Crackme de Cruehead.
Aplicare el metodo del PUSHAD para llegar al OEP apreto f7 para pasar el PUSHAD.
Ahora marco ESP-FOLLOW IN DUMP.
Y en el dump vere los registros que guardo, y marcare los primeros 4 bytes, y pondre un HARDWARE BPX ON ACCESS.
Y doy RUN, parara en el salto al OEP.
Bueno ya estoy en el salto al OEP, apreto f7 y llego al mismo.
Bueno ya llegamos, al punto donde el programa esta desempacado en memoria ahora lo dumpearemos.
Como vimos en partes anteriores, existen muchos dumpeadores, incluso el OLLYDBG tiene un plugin llamado OLLYDMP que dumpea muy bien, pero como ya vimos como se hace con el LORD PE, ahora utilizaremos PE -TOOLS que pueden bajarse desde:
http://www.uinc.ru/files/neox/PE_Tools.shtml
Como nos cansaremos de desempacar, y de practicar mas adelante en futuros desempacados tambien usaremos el plugin OLLYDMP asi aprendemos a usar todos.
Abramos el PE-TOOLS sin cerrar el OLLYDBG que esta detenido en el OEP.
Bueno alli esta el proceso que en este caso se llama crackme.exe ya que perdi el que se llamaba crackmeUPX y lo hice de nuevo y me olvide de cambiarle el nombre, pero es lo mismo, se llame como se llame es el crackme de cruehead empacado con UPX y detenido en el OEP.
Haciendo click derecho-DUMP FULL
Bueno ya esta dumpeado ahora vamos a la reparacion de la IAT cerramos el PE TOOLS vimos que el DUMPED lo guardo en la carpeta del PE TOOLS, asi que lo buscamos y lo copiamos a la carpeta donde esta el mismo Crackme de Cruehead empacado con UPX.
Bueno ya sabemos que aun falta reparar la iat, igual probamos ver que pasa si lo ejecutamos, hacemos doble click en el dumped.exe y..
Bueno como ven hay que reparar la IAT, aunque corriera en nuestra maquina, debemos reparar la IAT para que funcione en cualquier maquina y no solo en la nuestra, para ello usaremos el IMPORT RECONSTRUCTOR, por supuesto no cerramos el OLLYDBG con el CC empacado con UPX detenido en el OEP, pues el IMP REC trabaja sobre el.
Lo abrimos y buscamos el proceso del crackme de cruehead con UPX que esta detenido en el OEP.
Ahora bien un tema que complica a muchisimos newbies es hallar el inicio y final de la IAT, por supuesto en el crackme que tenemos detenido en el OEP ya vimos que el packer destruyo la IT, por lo cual el primer Image Import descriptor cuyo 4 puntero marca el nombre de la dll y el 5to marca la primera entrada de la iat correspondiente a esa dll, no los tenemos, por lo cual debemos utilizar otros metodos para hallarla.
Por supuesto sabemos que las llamadas a las apis generealmente son realizadas con J MPs indirectos o CALLs indirectos del tipo.
J MP [xxxxxxx] o CALL [xxxxxx]
y como hemos visto en la parte anterior el programa toma la direccion de la api en nuestra maquina de la IAT, que es el deposito de direcciones de las apis en nuestra maquina, busquemos un salto a una api en el empacado, para lo cual miremos en el OLLYDBG con el CC empacado, parado en el OEP.
Alli en la segunda linea vemos un CALL que ollydbg nos dice que ira a una api, aunque previo paso por los J MPS INDIRECTOS, asi que marquemos esa linea y hagamos FOLLOW
Alli encontramos la tabla de saltos que tomando valores de la IAT, nos lleva a cada API, como vemos estos saltos comienzan con los opcodes FF 25, por lo cual muchas veces veran en tutes que directamente haces un search for bynary string y buscan FF 25, y llegan hasta aqu mas rapidamente.
El tema es que no todos los programas usan saltos indirectos para llegar a las apis, por lo cual a veces ese metodo falla, pero lo mejor y que nunca falla es buscar una llamada a una api, y ver de donde toma el valor guardado que nos llevara a la api, y ese valor tiene que estar guardado en la IAT.
Aqu en el ejemplo J MP [403238]
lli esta bien claro 403238 es una entrada de la IAT donde esta guardada la direccion de la api or supuesto mirar todos los J MPS INDIRECTOS y ver cual es la minima y maxima direccion
lli vemos la organizacin de la IAT, vimos en la parte anterior que estan continuadas todas las
lgunos packers ma basura para que se haga mas dificil la 29 B5 80 7C 0E 18 80 7C )|##| A GetModuleHandleA, de esta forma en el DUMP estamos viendo parte de la IAT, lo que necesitamos es ver donde comienza y donde termina la misma.
P podria ser un metodo, aunque es muy lento, lo mejor es ir al DUMP e ir subiendo de a poco, y como sabemos cada entrada tiene una direccion de una api, en este caso es 7C80B529, que vista al reves es 29 B5 80 7c, cambiare a la vista de dos culumnas para que se aprecie mas.
A entradas de la misma dll y luego la separacion para comenzar con la siguiente dll, es una entrada con ceros, si marcamos los ceros de separacion.
A s sofisticados sobreescriben los ceros con reconstruccion, total esas entradas no se usan, y como ya no necesita arrancar el programa, no necesita mantener los ceros, pero aqu estan y como ejemplo vemos que entre ellos en una misma dll las direcciones son cercanas ya que van a la misma seccion donde se encuentra esa dll, si ven abajo de
0403238 0 00403240 A2 CA 81 7C 00 00 00 00
hay tres apis que van a direcciones 7Cxxxxxx y luego esta la entrada con los ceros que separa de la iguiente dll. IEW-M veremos a que seccion CODE de que dll corresponden esas direcciones tipo Cxxxxxx
Pues alli vemos que todas esas direcciones estan co de la seccion code de la ernel32.dll.
Por supuesto en sus m s, pero aqu veo que n mi maquina esas entradas corresponde a la seccion CODE de la kernel32.dll o sea que las
ues alli vemos todas las e a la kernel32.dll, vemos la separacion con ceros arcada en rojo y mas arriba hay entradas que van a otra dll en este caso su seccion CODE se
seccion CODE de user32.dll, sigamos subiendo hasta la siguiente separacion. s
Si vemos en V 7
mprendidas dentro k
aquinas las dll pueden estar ubicadas en otras direccione e direcciones de las entradas contiguas caen todas alli en esa dll.
P ntradas correspondientes m encuentra en direcciones cercanas a 77Dxxxxx, miremos en M, a que dll corresponden.
Pues entonces las direcciones que hay arriba de la separacion, corresponden a la la
Pues alli vemos todas las apis que caen dentro de la seccion CODE de la user32.dll y la separacion pero arriba ya no hay mas nada quiere decir que el inicio de la iat es 403184, pues esa es la primera entrada valida.
Vemos claramente mas arriba no hay mas entradas que vayan a ninguna dll, y en este caso, ademas hacia arriba hay todos ceros lo cual nos facilita la tarea de ver el inicio de la IAT, algunos packers mas complejos normalmente llenan de basura antes de la IAT y luego de que termine, para que no sea tan facil identificar el inicio, pero si uno sabe que las entradas de la IAT siempre deben ir a la seccion code de una dll, pues el resto en seguida nos damos cuenta lo que es basura, pues no nos lleva a ninguna seccion code de ninguna dll.
Pues alli en la imagen vemos el inicio de la IAT que es 403184, ahora iremos bajando hasta hallar el final de la iat, usando el mismo metodo, mirando siempre que la IAT continuara mientras haya entradas que vayan a una seccion code de una dll.
Tambien mas adelante veremos que hay packers que cambian entradas de la IAT y las redireccionan a rutinas propias, desde la cual saltan a la api, ese caso por supuesto no se da aqu, y lo estudiaremos mas adelante, pero por ahora, sabemos que las entradas de la IAT son direcciones de apis, y que deben llevarnos a secciones code de dlls.
Alli vemos las ultimas entradas de la IAT que van a 76xxxxxx veamos a que dll corresponden.
En este caso corresponden a la seccin CODE de COMDLG32.dll y luego de esto no hay mas entradas asi que el final de la IAT para que queden todas las entradas incluidas dentro seria 40328C, podria tomarse tambien que la ultima entrada es 403288 y igual funcionara, pero para mas claridad vemos que termina en 40328c y ponemos esa direccion como fin de la IAT.
Por lo tanto ya tenemos el inicio y final de la IAT
INICIO: 403184 FINAL: 40328C
el IMPORT RECONTRUCTOR nos pide tres datos : 1)el inicio de la IAT, pero hay que restarle a 403184 la imagebase que en este caso es 400000 asi que seria 3184. 2) El segundo valor que nos pide es el largo de la IAT por lo cual restando el FINAL menos el INICIO tendremos el largo.
LARGO=40328c-403184=108
por lo cual el segundo dato que nos pide del largo o SIZE sera 108
3)El tercer dato es el OEP tambien restandole la imagebase seria 401000-400000=1000
Estos datos los ingresaremos en el IMP REC.
Alli vemos lso daros que pusim os el 1000 ya que a 401000 le restamos la im agebase tambien y en Size el largo de la IAT.
Ahora apretamos GET IM
Vemo la IAT, y ademas de hallarla, te com rcando YES, en el caso de entradas strara NO y en ese caso habra qu ara que el IMP REC reconozca co YES como en el caso actual ya podem
Tenemos cada entrad era que vimos en la IAT que era la entrada co
Si recuerdan esa fue la primera entrada que miramos en la IAT la correspondiente a 403238, por supuesto en IMP REC siempre hay que restar la imagebase por lo cual buscaremos 3238 ademas sabemos que pertenece a Kernel32.dll como vemos en la imagen superior al lado del nombre de la os en el IMP REC, en OEP pusim agebase, en RVA el inicio de tabla restandole la im PORTS
s que el IMP REC lo que hace es hallar que apis pertenece a cada entrada de unica si es valida o sea si esta correcta, ma redireccionadas por ciertos packers que no vayan directamente a una API te mo e averiguar esa entrada incorrecta a que api pertenece realmente, arreglarla p mo entrada correcta y nos diga YES y una vez que esta todo os reparar el dumpeado.
Antes de hacerlo como nos gusta mirar, veremos que en cada dll, si desplegamos el contenido apretando en el +.
a a que api pertenece y si tenemos ganas podemos ubicar la prim rrespondiente a GetModuleHandleA. api.
Alli buscamos el dumpeado y lo abrimos
Bueno alli vemos que el IMP REC lo repara aunque no toca el DUMPED que teniamos guardado
Por lo tanto debemos abrir la kernell32.dll y para ello hacemos click en el +que esta a la izquierda.
Alli vemos la entrada 3238 corresponde a GetModuleHandleA esta todo bien, asi que ahora repararemos el dumpeado, vamos al boton FIX DUMP.
sino que crea uno reparado con el nombre DUMPED_.exe. os alli en la carpeta donde esta. Veam
si quedo bien. uchas veces nos ne la solucion abrimos el PE TOOLS
vamo ente ahora lo jecutamos yyyy... os reparado la IAT, de
Alli esta podemos intentar ejecutarlo a ver
ejejejeje aun parece que falta algo pero a no asustarse que al reparar la IAT m J ocurrira esto, el mismo PE TOOLS tie
Y s a REBUILD PE y buscamos el DUMPED_.EXE y lo repara perfectam e
Funcionaaaaaaaaaa y ademas funcionara en cualquier maquina, porque hem forma que el IMP REC lo que hace es teniendo las apis correctas de cada entrada de la IAT, reescribe los punteros a los nom un IID por cada dll como vimos en la parte anterior que debe quedar todo a para que arranque normalmente sin error.
Si abrimos el DUMPED_.exe en OLLYDBG.
emo eccion code y
Llegam
bres de las apis, y arregla la IT poniendo program
V s que OLLYDBG nos dice ahora que el Entry Point, se encuentra fuera de la s eso es porque el UPX habia cambiado la seccion code a la 3ra, igual podemos arreglar eso. os al Entry Point y vamos a ver el header con GOTO EXPRESSION=400000
Alli esta bajamos
Cambiamos a modo SPECIAL-PE HEADER
Vemos que la PE SIGNATURE e
Alli esta el puntero m la primera, la que em
Lo marcamos y vamos a MODIFY INTEGER.
mpieza en 80 vayamos alli a 400080. aldito dice BASE OF CODE=9000 o sea queremos que la seccion CODE sea pieza en 401000 asi que cambiamos ese 9000 por 1000.
la
Ahora guardaremos los cambios como siempre click derecho COPY TO EXECUTABLE y en ventana que se abre click derecho SAVE FILE.
Ahora reiniciamo bien OLLYDBG analiza la seccion y cual suele ser de mucha ayuda.
Si vamo eccion nueva llamada mackt donde colocara la nueva IT, comprobemoslo, en el mismo header en odo SPECIAL vayamos a ver el puntero a la IT.
s y vemos que no solo no sale el cartelito molesto, si no que tam a que al interpretarla como CODE, le realiza el analisis, lo s a ver las secciones del dumpeado veamos que para repararlas el IMP REC le agrega una s m
Vemos que la IT esta ahora en B000 o sea 40B000 que es la direccion de la seccion que agrego el IMP REC vayamos a ver alli quitando el modo SPECIAL.
Alli vem letamente
Alli vemos el primer IID correspondiente a la primera dll, cuyo 4to DWORD nos apunta a su nombre como vimos, en este caso el nombre de la dll estara en B078 o sea 40B078.
os la IT tal cual la vimos en la parte anterior, unicada en otra direccion pero comp funcional, si queremos podemos hallar los punteros como en la parte anterior para repasar.
Es user32.dll.
Y el 5to puntero com habiam
os en el ejecutable, quina, debe
o vimos en la parte anterior apuntara a la primera entrada de la IAT, en este caso el 5to puntero es 3184 por lo tanto la primera entrada de la IAT estara en 403184 como os visto que era el inicio de la IAT al reconstruirla. Y por supuesto la primera entrada de la IAT ahora tiene el valor de la api pero si vem antes de ser sobreescrita por el sistema con la direccion de la api en mi ma tener el puntero al nombre de la api, que llenara dicha entrada si vemos.
eberia estar el nombre de la API que llenara esta entrada.
La cual es KillTimer.
Vemo mente arreglando todos los punteros ra que al arrancar el sistema sepa que api debe aravilla.
Bueno esta ha sido nuestra prim que puede existir, pero es la base de todo y es tengan bien claro, porque a medida que sigamos desem letemente destrozadas, apis redireccionadas y casos dificiles, para los cual prescindible haber entendido bien comno trabaja todo. demas este packer no tiene antidumps que es la parte que aun no vimos ya que no fue necesario, e os casos con ANTIDUMP. De cualquier m
Hasta la parte 35 Ricardo Narvaja 05/03/06
En esa entrada de la IAT en el ejecutable, existe el valor B084 que corresponde a 40B084, donde d
s que el IMP REC realizo un trabajo estupendo, detecto cada api, construyo la IT nueva , y reconstruyo la lista de nombres de cada api pa llenar cada entrada de la IAT una verdadera m era reconstrucion de una IAT la mas sencilla importante que tanto la parte anterior como esta, la pacando nos encontraremos con IATs comp es es im A pero a mdida que vayamos avanzando en la complejidad de los packers ya encontrarem anera iremos incrementando la dificultad suavemente para que se les vaya fijando los conceptos asi que no se asusten, vamos de a poquito jejejejeje
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 35
Seguiremos practicando y desempacando cada vez con packers mas dificiles, aumentando levemente el grado de dificultad.
El siguiente packer en la escala de dificultad es el aspack, casi muy parecido al UPX, y para el cual ya tenemos el crackme UnPackMe_ASPack2.12.exe que se envio en partes anteriores, al cual ademas ya le habiamos encontrado el OEP.
Coloco para practicar la dll del OLLYDUMP en la carpeta de plugins ya que lo dumpeare con el mismo.
Esa es la ultima version, parcheado algun bug que tenia por Parasito.
Abremos el OLLYDBG protegido con los plugins para ocultarlo, y lleguemos al OEP con el metodo el PUSHAD.
Vemos que aqu nos avisa que el entry point esta fuera de la seccion code como es lo usual, en la mayoria de los packers.
Ahi vemos el PUSHAD inicial al cual pasamos con f7 y luego hacemos.
ESP-FOLLOW IN DUMP para colocar un Hardware Breakpoint on accesss en los valores de los registros que guardo con el PUSHAD en el DUMP.
Luego apeto F9 con lo cual doy RUN
Con lo cual para justo despues del POPAD que restaura los valores guardados a los registros, traceo hasta llegar al OEP con f7.
Como veo que no se entiende el codigo, le quito el analisis.
vemos que si lo vuelvo a analizar mejora aun mas.
uego procedere al dumpeado voy al menu PLUGINS y alli busco el OLLYDUMP
Y
L
Nos aparece la ventana del plugin, en la cual ya vemos las cositas que podemos modificar, ya ahi podemos arreglar lo de la base of code, sin tener que luego cambiarlo en el header, en la ventana vemos base of code 4000, pero si recordamos este aspack corria en esta seccion que no es la primera, por lo cual le dejamos la base of code en 4000 que corresponde a 404000 que es la seccion donde esta el OEP y corre el programa.
Otro de los temas es la tilde de REBUILD IMPORT que esta abajo, el OLLYDUMP trata de hacer el trabajo del IMP REC para lo cual tiene dos opciones METHOD1 y METHOD2, que en algun packer sencillo puede funcionar, el que quiere a veces ganar tiempo, puede hacer un dumpeado con cada uno de estos metodos y ver si alguno funciona, aunque no es muy certero, pero alguna vez puede funcionar.
Nosotros le quitaremos la tilde en REBUILD IMPORT ya que lo haremos con el IMP REC que es mas confiable.
Bueno ahora podemos dumpear a ver que tal nos va.
Pues alli esta el dumpeado si lo ejecuto sin reparar la iat o bien correra solo en mi maquina con mucha suerte, o bien dara error veamos.
Bueno sin cerrar el archivo empacado que esta detenido en el OEP abrimos el IMP REC y elegimos dicho proceso en la lista del menu desplegable.
Volvemos al OLLYDBG para hallar los valores de INICIO DE IAT, LARGO y el OEP.
OEP es 404000 o sea que en el IMP REC ya que le debemos restar la imagebase que es 400000, quedara 4000.
Buscaremos el inicio y final de la iat como vimos para ellos hay que buscar una llamada a una api, justo abajo del oep esta la llamada a GetModulehandleA.
Si marco dicha linea y hago click derecho-FOLLOW
Veo que va directamente a la api sin J MPS INDIRECTOS intermedios por lo menos en esta llamada , (ya que si buscamos veremos que si hay J MPS INDIRECTOS lo que pasa es que no siempre los usa como en este caso)
Quiere decir aqu usa un CALL INDIRECTO, para saltar a la api, por lo cual es facil deducir que lee la direccion de la API directamente de la IAT para saltar a la misma correctamente.
Bueno es facil de ver que 4011F4 es una entrada de la IAT donde guarda la direccion de la API, GetModuleHandleA. El que gusta de ver los J MPS INDIRECTOS, buscando con FF 25 tambien los hallara.
Y llegara al mismo resultado ya que el J MP a GetModulehandleA lee valores de la misma entrada de la IAT.
Vayamos en el DUMP a mirar dicha entrada y la IAT en general.
Alli vemos todas las entradas que son compaeras de la que miramos inicialmente, todas van a la seccion code de la misma dll, miremos en VIEW-M a que dll corresponden.
Todas caen dentro de dicha seccion, por lo cual vemos que son las entradas que corresponden a Kernel32.dll ya que apuntan a su seccion CODE.
Alli mismo podemos ver el final de la IAT ya que debajo de 401218 no hay mas nada, asi que el final de la iat es 401218, ahora nos queda hallar el inicio.
Vemos la separacion de ceros y antes otro grupo de entradas.
Que son exactamente estas entradas, vemos que en las direcciones adonde apuntan (10xx o 11xx) no hay dlls ni nada ya que la mas baja direccion en el mapa de memoria es 10000.
Asi que estas entradas ya que no van ni a una dll, ni a una seccion real, ya que podrian apuntar a alguna seccion creada por el packer, lo cual no es este caso, son basura metida para molestar ya veremos lo que hacemos con ellas, ahora sigamos subiendo.
Vemos que entre ceros hay otro grupo de entradas que apuntan a direcciones 77Dxxxxx veamos en el mapa de memoria a que dll pertenecen.
Vemos que pertenecen a la User32.dll
Tambien vemos que hay mas dlls en el mapa de memoria como GDI32 y Ntdll las cuales pueden haber sido cargadas por el packer para su uso, y no la usa el programa, para verificar esto, hagamos en el mismo listado SEARCH FOR ALL INTERMODULAR CALLS.
Vemos que hay llamadas a 3 dll, las dos que hallamos y falta arreglar la Ntdll ya que hay llamados a la misma, veamos.
Si vamos a los calls de esas dll por ejemplo.
Vemos que la entrada esta en 401200 o sea que esta mezclada con las de kernel32.dll
Lo mismo la os cuenta por la proxim
IAT, es el que abarca todas las entradas as
El inicio de la Ia
Ve
ARGO=FINAL MENOS INICIO=401218-40119c =7C ongamos estos valores en el IMP REC a ver que pasa, veamos que paso con las dos entradas que estaban mezcladas de la ntdll con las de kernel32. otra de dicha dll esta tambien mezclada con las de kernel32.dll no nos dim idad de las secciones code de ambas pero es asi.
Bueno vemos algunos problemas en esto de cualquier forma el inicio de la i que t es 40119C lo que concuerda con el menor valor hallado en la tabla de saltos. mos que es el mas pequeo de todos estos valores, asi que ya tenemos OEP=4000 RVA o INICIO DE LA IAT=119C L
P
emos la parte que dice NO que c os que solo tiene entradas para kernel32, si m correspondian a 401200 y 401210, vemos que
La reemplazo por las sim
emo s de kernel32.dll y seguro cambiadas por el packer para m
s que esas entradas que dicen NO
Marco la prim
V orresponde a las entradas basura, y abajo vem iramos las entradas raras que ilares correspondientes a kernel32.dll y nos dijo algo de esto?
V s que si que nos aviso en el log que esas entradas son similares a la olestar y complicar las cosas. Bueno entonces solo tenemos que quitar la basura de en medio ya que verificamo , son basura, para verificarlo aqu vayamos a una de ellas.
era y hago click derecho- DISASSEMBLE-HEX VIEW
lli vemos que no cae en ningun lugar que exista, asi que marcamos todas las entradas basura.
pretando SHOW INVALID y alli las tenemos a todas marcadas ahora hacemos click derecho
A
A CUT THUNKS.
Con lo cual las anulamos a todas esas entradas para que al arrancar el sistema no de error tratando de arrancar apis inexistentes.
Ahora si, apreto FIX DUMP ya que tengo todas las entradas marcadas como YES o sea validas.
y me crea el dumpaspack_.exe el archivo que supuestamente ya estaria reparado, veamos ejecutemoslo.
Y si funciona perfectamente por lo cual terminamos con el segundo packer para ir aumentando la dificultad progresivamente y muy levemente.
Hasta la parte 36 con otro packer Ricardo Narvaja.
INTRODUCCION AL CRACKING EN OLLYDBG PARTE 36
Seguimos aumentando muy suavemente la dificultad en los packers que vamos viendo, en esta entrega veremos dos desempacados, el crunch o bitarts 5.0 y el telock 0.98, que nos servira para introducirlos en el tema de las entradas de la IAT redireccionadas, ambos unpackmes estan adjuntos a este tutorial, por lo que no hay problemas para obtenerlos.
Empezaremos con el mas sencillo con el BITARTS lo arrancamos en OLLYDBG.
Vemos que no hay un PUSHAD inicial, asi que traceemos un poco con f7.
Vemos que ahi llega a un PUSHAD asi que pasemoslo con f7 y hagamos ESP- FOLLOW IN DUMP.
Y pongo un Hardware Breakpoint on access en los primeros bytes.
Ahora apreto f9 y despues que pasa alguna que otra excepcion, para por el Hardware Breakpoint.
Traceo unas lineas y llego al OEP.
Al OEP se puede llegar tanto usando el buscador de OEPs de OLLYDBG, el OLLYDBG parcheado para OEPs o casi cualquiera de los metodos que vimos en las partes anteriores de la introduccion.
Como vemos dicha direccion esta en la primera seccion despues del header
Por lo cual la cosa parece bien ordenada, incluso esta marcada como seccion CODE asi que no habra problemas
Vemos que en este caso la primera API que llama es GetVersion por lo cual tambien poner un BP en dicha api y cuando para en ella, llamada desde primera seccion, al retornar de la misma, nos hubiera dejado, en la zona del OEP.
Bueno el OEP no tiene misterios, miremos un poco la IAT, por supuesto alli a la vista tenemos una llamada directa a una api, por lo cual es facil ver que el CALL INDIRECTO, toma el valor correcto en mi maquina de la api GetVersion, para dirigirse a la misma.
Por lo tanto 460ADC es una entrada de la IAT, la correspondiente a GetVersion, vayamos en el dump a verificar la IAT.
Lo que si se ve bien larga jeje, verifiquemos a ver donde van las entradas.
La primera entrada que nos llevo a la IAT era de GetVersion que pertenece a Kernel32.dll, podemos mirar en el mapa de memoria donde cae dicha direccion 7Cxxxxxx.
Vemos que todas corresponden a la Kernel32.dll, por ahi en el medio hay como en la parte anterior mezcladas un par correspondientes a la ntdll, pero ya verificamos que el sistema hace una excepcion para esas apis, que originalmente eran de kernel32.dll y como fueron reemplazadas por apis similares de ntdll.dll, pues por compatibilidad, las acepta como si fueran de la kernel32.dll si problemas, en cualquier otro caso que el sistema no tenga este tipo de excepciones que son muy pocas realmente (creo que las unicas), las apis deben ir ordenadas por dll, y separadas por ceros c los de otra dll, en una IAT correcta.
n hacer on ueno despues de la separacion vienen hacia abajo un grupo de apis de direcciones del tipo i uno tiene alguna duda de alguna entrada a que dll pertenece, ademas de ir al mapa de memoria y
on lo cual buscara en el listado, todas las instrucciones que utilizan dicha entrada, en este nde ebo
lli vemos los CALLs que existen en la priumera seccion correspondientes a dicha entrada. La cual B 77xxxxxx.
S fijarse, puede marcarla en la IAT y hacer click derecho-FIND REFERENCES.
C caso.(esto funcionara siempre y cuando el listado este mostrando la seccion del programa do trabaja el mismo, en este caso la primera seccion, si busco referencias, y el listado lo tengo mostrando otra seccion diferente, buscara en ella, y probablemente no hallara nada, asi que d verificar antes de usar este metodo, estar en la seccion correcta donde el programa corre ya desempacado, o la zona del oep, que es lo mismo)
A pertenece a la api VariantClear de la OleAut32.dll.
Mirando en el mapa de memoria, vemos que por supuesto el grupo siguiente cae en la seccion code de la OleAut32.dll, como corresponde.
Si seguimos bajando sin especificar cada dll, vemos grupos de entradas contiguas que van a otras dll, separacion con ceros, otro grupo, otra separacion y asi, seguimos bajando hasta ver donde acaba este esquema para encontrar el final de la iat ya que no se ven ceros donde termina.
Alli vemos la parte final donde se termina este esquema, vemos en celeste un grupo de apis, correspondientes a una dll, luego la separacion, luego en rosado otro grupo de apis, la separacion y vemos una entrada marcada con una flecha y otra separacion, luego de la cual ya no se mantiene el mismo esquema, podemos verificar si esta api de la flecha pertenece a la IAT, pues fijemosnos si va a alguna dll con los dos metodos.
Vemos que es una entrada de la IAT pues nos lleva a una api en este caso OleUiBusyA de la oledlg.dll, si verifico mirando el mapa de memoria.
Vemos que logicamente cae en la seccion CODE de dicha dll, por lo cual es una entrada de la IAT, la unica de esta dll, luego de eso, viene la separacion, y luego vienen grupos de numeros sueltos que no estan agrupados para ir a direcciones contiguas, ni sus direcciones apuntan a ninguna dll.
Si marcamos cualquiera de ellos, y hacemos FIND REFERENCES.
No hay resultados, que nos lleven a apis, por lo cual podemos deducir ya que mas abajo no encontramos mas entradas que nos lleven a apis, que aqu se termino la IAT por lo tanto el final de la misma es
FINAL: 460F28
Ahora hagamos lo mismo hacia arriba verificando donde comienza el esquema de la IAT.
Vemos que el esquema se va repitiendo hacia arriba hasta que llegamos aqu, en celeste estan marcadas las separaciones, el grupo marcado en amarillo es el que visualmente reconozco como un grupo ordenado que va a una dll, luego hay una separacion y una entrada que va a 8000008, como no se si no corresponde a alguna entrada suelta de alguna dll, verifico haciendo FIND REFERENCES.
EP=271B0 ARGO=710 ueno hacemos el dumpeado con el OLLYDMP.
No hay resultados que vayan a apis, ni en esa entrada, ni en ninguna superior por lo cual, podemos asegurar que la primera entrada es 460818.
por lo tanto ya tenemos el INICIO y FINAL de la IAT, hallamos el largo. FINAL-INICIO=460F28 460818 o sea que el largo es 710 recopilando para el IMP REC (le restamos ya la imagebase 400000 al OEP y INICIO) O INICIO o RVA=60818 L
B
Le quitam
Luego abramos el IMP REC sin cerrar el OLLYDBG, con el original detenido en el OEP.
os la tilde a Rebuild Import y dumpeamos.
Buscam
Y apretamos GET IMPORTS
Vemo apretamo
Lo guardo al reparado con el nombre unpacked_.exe, probemoslo a ver si funciona.
os el proceso en el menu desplegable y le colocamos los valores hallados. s que el packer no hace mucho por molestarnos todas las dlls estan correctas asi que s FIX DUMP y buscamos el dumpeado para que lo repare.
Funciona perfectamente, por lo cual no tiene antidumps, los cuales seguramente encontraremos mas delante en packers mas complejos.
La proxima victim de las entradas de la IAT redireccionadas.
os un poco a ver si hay algun PUSHAD.
asemoslo con f7, luego marcamos ESP-FOLLOW IN DUMP.
a a es el telock 0.98 que nos servira para empezar el tema
ribemos el metodo del pushad, traceem P
P
Quitem
Vemos que el m RDWARE BREAKPOI coloque.
Y reincio el OLLYDBG.
os el analisis a si se ve el codigo. etodo del pushad no funciona y que ademas esta protegido contra HA NTS porque si lo sigo corriendo da error, asi que quito el hardware breakpoint que Pues ese metodo no va, probem pio el LOG y lo hago correr al programa para que me
Pues quitemo pescar la de 4666f1 que es la ultima del desempacador.
Pues luego de pasar varias excepciones con SHIFT mas f9 llegamos a 4666f1.
os con el de las excepciones, lim liste las excepciones que pasa.
s las tildes de las excepciones y reiniciemos tratando de
Pongamos ahora un ME era seccion.
ecordemos que debemos apretar SHIFT mas f9 para pasar la excepcion que estamos parados si no dara error, lo hacemos.
era seccion donde para por MEMORY BRE
Por lo tanto el oep es 4271B0, el m UNCH, por lo cual parece ser el mism o si no supieramos nada de el.
Bueno en el ejem sta iba a la api GeVersion, pero en este caso no es asi, aq i hago MORY BREAKPOINT ON ACCESS en la prim
R Bueno para en un par de excepciones del tipo SINGLE STEP y llega al OEP en la prim AKPOINT ON EXECUTION. ismo que el del ejemplo anterior de CR o programa empacado con otro packer, igual lo trataremos com plo anterior sabiamos que ese call que esta a la vi u comienza el tema de entradas redireccionadas jeje.
S
ay muchismos Calls indirectos que en vez de dirigirse a una api de una dll, van en este aso una seccion 9fxxxx en mi maquina, pero que en su maquina puede variar y ser otra direccion parecida..
Si miro mas abajo en esta lista
para ver los CALLs que se dirigen a otras secciones, intentando ver si hay calls a alguna api.
Veo que h c
Vemo dio de
Alli tenem marque
4 es una entrada de la IAT, vayamos en el DUMP a verla. s que hay algunos CALLS directos que nos marca que van a apis, seguramente por me un J MP INDIRECTO, vayamos a ver alguno de estos CALLS. os uno, es un CALL 435CDE que ira seguro a los J MPS INDIRECTOS a las apis, moslo y hagamos click derecho- FOLLOW.
Alli vemos los saltos indirectos a las apis, por lo tanto sabemos que toman valores de la IAT, o sea que 460ED
Vemo de la IAT aq piezan todos ceros, ahora subam
Ve
emos que pertenece a la api PlaySoundA de la WINMM.dll de alli para arriba, no encuentro mas alores que vayan a dlls, pero si busco referencias. s que la parte final de la IAT es correcta y coincide con la del ejemplo de CRUNCH, el final u tambien es 460F28, es facil detectarlo pues aqu si termina la IAT y em os. mos ya, que el proximo grupo esta conflictuado, la primera entrada arriba de la separacion corresponde a 76B1A8F7 si la marco y hago click derecho-FIND REFERENCES. V v
rama salta a las apis de las dlls, por medio de la IAT, fuera de la misma ya que hallam salta a una s o es esto?
agen anterior
Comment=
En vez de gu plaza dicha
a debajo del EP.
Realmente no sabemos que va a GetVersion, solo porque el ejemplo anterior era un programa similar pero empacado con CRUNCH lo sabemos, pero realmente hasta aqu, para nosotros es un CALL INDIRECTO, lleguemos hasata el con f7 y entremos en el a ver donde va.
Veo que si existen referencias, por lo cual aqu hay un punto, cuando llegabamos subiendo y bajando al inicio de la IAT si buscabamos arriba del inicio, por ejemplo, no encontrabamos ninguna eferencia, pues el prog r no encontramos ninguna referencia, ahora aqu vemos que estas son posibles entradas de la IAT, ya os referencias que toman valores de ellas en el codigo, pero, en vez de saltar a las dlls, eccion que en mi caso, esta en Axxxxx o puede variar segn cada maquina, com Pues esto es lo que se llaman entradas redireccionadas, el desempacador al ejecutarse, sobrescribe algunas de las entradas a la IAT con valores que apuntan a rutinas propias, en el caso de la im 004038A6 CALL DWORD PTR DS:[460E48] DS:[00460E48]=00A00B61 ardar la direccion correcta de la api en mi maquina, el desempacador reem direccion por una direccion de una seccion propia creada por el, en tiempo de ejecucion, y alli pone una rutina que al final termina yendo a la api correcta. Para aclarar un poco veamos la entrada a GetVersion que esta en el inicio del program O
Vemos que para ver donde va toma el valor de lo que aun no sabemos con certeza, pero son osibles entradas de la IAT ya que mas abajo vemos entradas correctas a apis. tanto el programa al ejecutar ese CALL va aqu que en mi maquina a la direccion 9F06F7, en
p
Por lo las suyas puede cambiar. Esta direccion no pertenece a las secciones del programa en si.
lli vemo bre donde esta bicada la rutina donde salta el programa, fuera de las secciones del mismo. creada por el programa mientras se va desempacando, ahora, podemos ues podemos poner un BP VirtualAlloc que es la api encaragada de crear secciones virtuales y bicarlas.
Ahora demos RUN y si pongo todas las tildes en exceptions vemos que el programa no corre y se termina, por lo cual es obvio que detecta el BP que acabo de poner, probemos ponerlo en el RET de la api.
A s las secciones del programa en celeste y mas abajo una seccion sin nom u
Si reiniciamos el programa vemos que esa seccion no existe al inicio.
or lo tanto vemos que fue P verificar el momento en que dicha seccion es creada?
P u
Vemo
o ayuda que cuando el programa crea secciones las que usara, son marcadas como PRIV PRIVADAS, ma as secciones no estaban en el inicio, antes de desemp mpacar.
or lo tanto quitamos el BP y llegamos al OEP, como anteriormente, quitando las tildes de las o Ahora doy RUN
Como para en el retorno de la api, la misma devuelve en EAX la direccion base de la seccion creada en este caso paro, y creo una seccion en 3c0000, sigamos.
s que va creando secciones las cuales podemos ver en el mapa de memoria
Vemos com o s la ayuda que significa ver que es acar, pues, sabemos con certeza que son secciones creadas al dese P excepciones y llegando a la ultima, poniendo un BPM ON ACCESS en la primera seccion, saltand la ultima con SHIFT mas F9.
Alli llegamos nuevamente al OEP y si vemos el el mapa de memoria
Vemos secciones creadas que van a se das como PRIV y alli se dirige el call ese indirecto al cual volvemo
emos que llega aqu a un PUSH que pone la direccion de GetVersion en el stack, y luego salta a la sea que el desempacador reemplazo la entrada de la api GetVersion, con una direccion que apunta a una seccion propia o creada por el y no a una dll, y que si traceamos al final del cuentas nos lleva a la api correcta.
r utilizadas, estan marca s a entrar traceando con f7. Pues traceemos a ver donde llega esta rutina
V api al llegar al RET, por lo cual esta rutina es como un intermediario para llegar a la api GetVersion.
O Pues esta es la definicion de una entrada redireccionada, exactamente.
Por lo tanto cuando verificamos el inicio y final de la IAT no solo debemos verificar que una entrada vaya a una dll, si no tambien debemos aceptar como entradas de la IAT, aquellas que tienen referencias y que nos llevan a un codigo propio del packer, que resulta ser un intermediario para llegar a la api finalmente.
Por lo cual volvamos a la IAT como estabamos mirando para hallar el INICIO y FINAL.
Todas esas entradas que van a van a codigo creado por el desem sde el OEP no existiria, por lo cual sigam la seccion 0Axxxxxx en mi maquina son entradas redireccionadas, pacador, que si el programa arrancara de os subiendo para ver si hallamos el INICIO de la IAT.
Vemo seccion 9Fx
Ademas comprobando, vemos que dichas entradas tienen referencias, por lo cual, son entradas de la IAT, sigamos subiendo.
s que luego hay algunas entradas que van a dlls, y luego mas arriba entradas que van a la xxx otra seccion creada por el desempacador.
Luego vemos entradas que en mi maquina van a A1xxxx que es otra seccion creada por el packer
y que ademas
or lo cual son entradas de la IAT y si sigo subiendo veo que ya llego a
Donde hay entradas que van a una dll, luego la separacion y luego mas arriba ninguna entrada tiene referencias.
si busco tienen referencias. P
Como la image base.
OEP=271B0 INICIO o RVA= LARGO=710
Por lo tant
Como vemos el IMP REC detecta que hay entradas redireccionadas y nos pone NO en algunas, miremoslas apretando SHOW INVALIDS que nos mostrara las invalidas.
en el CRUNCH el inicio de la IAT es 460818 el largo 710 y el OEP es 4271B0, restandole
60818 o abramos el IMP REC sin cerrar este OLLYDBG.
Y coloquemosle los valores que hallamos. Ahora apreto GET IMPORTS
emos que el IMP REC nos muestra lo mismo que vimos en la IAT entradas que no van a ninguna vamos a tracear todas esas entradas incorrectas a mano, hay varios metodos para ae algunas posibilidades, otros metodos pueden hacerse a mano pero no todos los veremos en la parte 37, para que tengan bien claro el tema de las apis e vemos metodos para repararlas. choto y eso debem
Hasta la pa Ricardo Narvaja 7/03/06
V api, y que van alli en la imagen, a direcciones de secciones creadas por el packer o codigo propio del mismo.
Por supuesto no repararlas, el IMP REC tr traceando jeje odos estos me T redireccionadas repasen bien esta parte, asi en la parte siguient emos que asi como esta, no podemos reparar un dumpeado, pues debe tener el IMP REC todo V YES o sea todas las entradas deben apuntar a apis de dlls, y no a entradas redireccionadas ni codigo os arreglarlo nosotros. rte 37 1
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 37
En esta parte veremos algunos de los posibles metodos para reparar entradas redireccionadas, pero el tema no se agotara aqu, porque al igual que para llegar al OEP, hay tantos metodos como packers existen, y cuando veamos algunos otros packers saldran metodos nuevos tanto para llegar al OEP como para reparar la IAT. El tema es que estos metodos son ideas generales, y en otros packers pueden funcionar o no, o quizas necesitan cierta adaptacion segn el caso, por lo cual es bueno siempre intentar y practicar mucho, e ir variando y probando. De la misma forma que cuando vimos como llegar al OEP, daremos los metodos mas generales, y mas adelante cuando veamos distintos packers, adaptaremos estos metodos o usaremos alguno nuevo segn el caso, que quizas no este aqu al no ser muy general.
Bueno aqu estamos en el OEP del telock que como vimos la parte anterior tiene entradas redireccionadas a varias secciones que fueron creadas por el mismo packer en tiempo de desempacado.
Ahi teniamos una vista de la IAT con sus entradas para reparar, realmente hay packers que redireccionan uno a dos entradas, por lo cual siempre es bueno conocer metodos para reparar una sola entrada, que es lo que veremos al inicio, obviamente si son muchas entradas a reparar esto no sirve, porque te volves viejo, pero hay que saber como detectar que api corresponde a cada entrada, a veces para verificar alguna entrada que es dudosa.
Tomemos la entrada que manualmente habiamos traceado y sabiamos que finalmente va a GetVersion.
Alli esta el CALL y en el DUMP, la entrada de la IAT 460ADC con su contenido que apunta en mi maquina a 9F06F7, tambien tenemos el IMP REC abierto con todos los valores que hallamos a mano, de RVA, SIZE y OEP escritos, y a la vista las entradas malas.
Pongamos el IMP REC tambien para ver esa entrada
60ADC corresponde a la entrada de la IAT 460ADC.
Volvamos al OLLYDBG y a nuestra entrada, ya vimos que traceando a mano llegamos a una api, sabemos que el OLLYDBG trae un traceador incorporado, vamos a usarlo para llegar mas rapido, ya que aqu fueron 5 o 6 lineas que traceamos y ya llegamos a la api, pero hay packers que dan vueltas y vueltas antes de llegar a la misma, por lo cual el traceo automatico suele ser util.
Ponemos antes de tracear un BP en el retorno de la api, no sea cosa que nos equivoquemos y quede traceando sin parar nunca.
En DEBUG-SET CONDITION tenemos la posibilidad de elegir las opciones en las cuales el OLLYDBG detendra el traceo.
Alli vemos la ventana de CONDICIONES PARA PAUSAR EL TRACEO, veremos algunas que pueden funcionar y se pueden adaptar segn el caso.
EIP IS IN RANGE significa que si ponemos la tilde en este renglon, OLLYDBG parara cuando el EIP se encuentre dentro del rango de valores que especifiquemos en la derecha, por ejemplo.
Este ejemplo significa que OLLYDBG traceara hasta que vea que EIP vale algun valor comprendido entre 401000 y 500000 por supuesto esto es un ejemplo, y no nos sirve en este caso, ya que queremos que se detenga en la api. Para hallar los valores entre los cuales queremos que OLLYDBG se detenga en este caso miramos el mapa de memoria.
lli vemos marcado en celeste la zona que nos interesaria que se detenga OLLYDBG al tracear, o A sea desde donde se encuentra la primera dll en adelante, no queremos que pare ni en las secciones del exe, ni en las secciones creadas por el packer ya que ese es codigo intermedio, necesitamos que pare en las dlls, por lo tanto si marcamos la primera casilla y ponemos que EIP este entre 58000000 y 7FFFFFFF que es la direccion maxima seguro que parara en alguna dll (aclaracion no importa que no elegimos la direccion exacta de la primera dll ya que vemos que no hay codigo entre 58000000 y el inicio de la primera dll 58c30000 asi que alli no va a parar, pero para evitar poner cifras exactas puedo sin problemas redondear)
Quiere decir entonces que OLLYDBG ejecutara traceando linea a linea y en cada una verificara que se cumpla esa condicion, o sea que EIP este en la seccion de alguna dll y si es asi parara.
Lleguemos hasta el CALL poniendo un BP en el mismo.
Si teniamos puesto un MEMORY BREAKPOINT que usamos para llegar al OEP lo quitamos y llegamos al CALL. Alternativamente si no es un CALL que esta al inicio y no sabemos donde esta el CALL O J MP, podemos marcar los bytes de la entrada y poner un MEMORY BREAKPOINT ON ACCESS en la misma, con los cual al dar RUN, parara cuando lea la entrada o sea en el J MP o CALL correspondiente.
Bueno ya llegamos al CALL con alguno de esos dos metodos.
Pongamos a tracear al OLLYDBG
Es importante elegir TRACE INTO para que tracee linea a linea, si elegimos TRACE OVER no entrara en los calls y puede fallar.
Alli paro por la condicion que colocamos si vemos en OLLYDBG abajo
Paro porque EIP esta en el rango 58000000-7FFFFFFF, es bueno verificar esto para ver que no haya parado por alguna excepcion u otro motivo.
Lo siguiente que hay que verificar es que al ejecutar la api vuelva al programa a continuacion del CALL, porque hay packers que para confundir van primero a una api, y a continuacion a una segunda api, por lo tanto la api verdadera sera la ultima, y en la cual veamos en el valor de retorno de la misma, que retorna al programa a al instruccin siguiente al CALL. Por supuesto en este caso, retorna a la linea siguiente del CALL de donde partimos.
Vuelve a 4271DC como corresponde.
Bueno ahora nos falta ver que api es porque OLLYDBG no nos dice nada, la primera forma es analizar el codigo aqu mismo de la dll.
lli vemos justo abajo en la aclaracion que OLLYDBG nos muestra el nombre de la api lo mismo
tra condiciones posibles para el traceo desde el CALL para llegar hasta la api son: A que al lado del valor de EIP.
O
Este caso es la inversa del anterior OLLYDBG chequea que EIP este fuera del rango de las secciones del exe, y las secciones que hay antes de la primera dll.
Otra posibilidad
Para algun caso raro que el packer cree secciones mezcladas entre las dlls, puede utilizarse un metodo combinado como este que parara cuando halle un RET y ademas cuando la primera linea del stack sea 4271DC que es el retorno de la api. Este metodo apunta a parar en el retorno de la api, y muchas veces es efectivo sobre todo en packers que emulan las primeras lineas de la api y saltan a la tercera o cuarta linea de la misma, generalmente el RET siempre es respetado y parara en el mismo, si reinicio el OLLYDBG y llego de nuevo al call puedo probarlo rapidamente.
O sea aqu se deben cumplir dos condiciones a la vez, que estan unidas por && lo cual asegura que i fuera que quisiera que se detenga cuando alguna de las dos condiciones solas se cumpla, en ese sea que sean las dos condiciones las que se cumplan && equivale a Y.
S caso usaria || que equivale a O.
O
[ESP]==4271dc && byte [eip]==0C3 ignifica que se cumplan ambas condiciones a la vez, o sea SP]==4271dc (que la primera linea del stack sea el punto de retorno esperado de la api) yte [eip]==0C3 (y que el contenido de EIP o sea el byte que se esta ejecutando sea un RET o i desde el CALL lanzamos a tracear con esa condicion, vemos que para en el RET de la api.
l dispararse ambas condiciones a la vez, se detiene el traceo.. bre de la api que ejecuto, pues no
s
[E
b sea C3)
S
A Ahora que estamos en el RET, se nos complica saber el nom estamos en el inicio de la misma, lo mismo nos ocurre cuando el packer simula las dos o tres primeras lineaas de la api y estamos en la 4ta o 5ta linea de la misma, aqu OLLYDBG no nos muestra el nombre aunque hay varios recursos para hallarlo.
eremos en el listado de lo que traceo, para ello vamos al boton con los tres puntitos. V
Vemos obviamente que la primera linea que traceo en la dll es la marcada por la flecha, aunque no nos muestra el nombre de la api, asi que hagamos analisis del codigo, y luego hagamos doble click en esta linea que marca la flecha.
Vemos que OLLYDBG nos muestra cuanto valian los registros en ese momento, por eso se ponen en gris ya que no son los valores actuales, y ademas nos muestra la informacion como si estuvieramos ejecutando esa linea, entre lo cual podemos ver el nombre de la api, lo mismo ocurriria si luego de un traceo vamos apretando la tecla menos, OLLYDBG ira hacia atrs mostrando la informacion y los valores que guardo al pasar por cada instruccin.
En el caso de packers que emulan las dos o tres primeras lineas de la api y al tracear caemos por la cuarta o quinta linea, el traceador no pasara por la primera linea pues ellas son emuladas por el packer, por lo cual a veces hay que arreglarse un poco a ojo, pero un metodo casero que no falla es hacer lo siguiente jeje (perdon por lo berreta pero la verdad que sirve)
En cualquier parte vacia abajo del ret escribimos con assemble, o apretando la barra espaciadora, un CALL a la linea que sospechamos es el inicio de la api visualmente, en este caso
CALL 7C8114ab
Parece el inicio de la api en mi maquina, en la suya ponen la direccion donde les parece visualmente que puede comenzar la api.
Al aceptar, si es el inicio de una api, OLLYDBG nos mostrara el nombre, si nos equivocamos podemos repetir con.
Y asi en la zona alrededor de donde parece que se inicia la api, hasta que OLLYDBG nos de el nombre aunque es generalmente bastante facil darse cuenta de donde se inicia, por los corchetes que pone OLLYDBG al analizar, alli vemos que el corchete empieza en el inicio de la api.
Quitamos lo que escribimos con UNDO SELECTION
Bueno ya sabemos detectar a mano el nombre de la api, una vez que lo tenemos vamos al IMP REC y hacemos doble click en la entrada mala que estamos reparando y ponemos el nombre bueno.
hora si apretamos SHOW INVALID vemos que dicha entrada ya es tomada como correcta lo cual en el OLLYDBG en dicha entrada, la direccion de la api
lli esta la e reccion hallada de la
A es un gran beneplacito para nosotros jeje. Otra forma de reparar la entrada es escribir correcta en nuestra maquina.
A ntrada que estamos investigando 460aDC, le sobrescribimos la di api en nuestra maquina, habiamos hallado que la api GetVersion comenzaba en mi maquina en 7C8114AB, pues escribimos dicha direccion en la entrada.
lli vemos la entrada reparada ahora si en el IMP REC limpiamos todas las entradas apretando el
omo vemos es similar colocar la direccion correcta de la api en la entrada correspondiente A boton CLEAR IMPORTS y de nuevo apretamos GET IMPORTS veremos que ahora la entrada esta tomada como valida.
C directamente en la IAT en el OLLYDBG o en el IMP REC colocar el nombre de la API en dicha entrada.
Bueno si hacemos eso en cada entrada redireccionada, y las reparamos una a una, y luego rreglamos el dumpeado, funcionara, el tema es que es un metodo muy tedioso, aunque es bueno l IMP REC permite guardar la tabla on las reparaciones que le hayamos hecho con el boton SAVE TREE y luego si interrumpimos el
tra forma posible de reparar las entradas redireccionadas es usando plugins del IMP REC, en este aso si vamos a la carpeta s.org/HERRAMIENTAS/L-M-N-O-P/Plugin_Import/ a conocerlo para verificar alguna entrada a mano si esta dudosa.
Algo que ayuda a los fanaticos de este metodo manual es que e c trabajo podemos volver al OEP del programa, abrir el IMP REC y una vez puestos los datos del OEP; RVA Y SIZE, cargar la IAT que habiamos guardado en el estado que la dejamos con el boton LOAD TREE. O c
http://www.ricnar456.dyndn
Vemos que hay un plugin para telock el cual puede ser copiado a la carpeta plugins del IMP REC eamos si funciona este metodo.
Copiam v
os la dll a la carpeta PLUGIN del IMP REC.
Ahora deberemos reiniciar el IMP REC y una vez que volvemos a ingresar todos los datos, apretamos SHOW INVALID, hacemos click derecho PLUGIN TRACERS y buscamos el del telock, luego de tracear vemos que arregla todas las entradas menos 4, por lo cual vemos la importancia de la reparacion manual ya que el plugin dejo pocas entradas para reparar y estas pueden hacerse a mano.
Alli vemos que el IMP REC nos avisa que quedan 4 por reparar, las cuales podemos tracear a mano con el metodo que vimos al inicio, de cualquier manera, el metodo del plugin es muy limitado ya que dependemos que exista un plugin para el packer que estamos usando lo cual es dificil.
El IMP REC posee otros trazadores genericos que en vez de usar los del plugin, se puede intentar a ver si funciona, aunque recomiendo guardar lo reparado hasta ahora, porque la mayoria de las veces terminan en cuelgues del IMP REC.
Marcando una entrada invalida y haciendo CLICK DERECHO vemos tres niveles de traceo, probemos a ver que pasa primero con el de NIVEL 1.
Fallo, probemos con los otros dos, ya con el segundo se colgo el IMP REC, por lo cual a pesar de mencionar estos metodos para otros casos, aqu no funcionan, y generalmente terminan en cuelgues solo sirven para packers muy sencillos.
El proximo metodo es el del J MP-CALL MAGICO que hicimos popular en crackslatinos en tantos tutes de diferentes packers.
El metodo se basa en tratar de buscar el momento en el que el packer guarda los valores en la IAT, y alli observar un poco y comparar lo que ocurre cuando guarda un valor malo, con lo que ocurre cuando guarda un valor bueno.
Usemos como ejemplo la entrada esta que investigamos de GetVersion que es una entrada redireccionada o mala, reiniciemos el crackme empacado con telock, y busquemos dicha entrada al inicio antes de arrancar el programa.
Alli esta en el DUMP la direccion 460ADC que al correr el crackme y antes de llegar al OEP, en algun momento se escribira alli el valor malo de la entrada redireccionada que en mi maquina era 9F06F7, quiere decir que en algun momento el packer escribira ese valor en la entrada.
Para interceptar el moemnto en que escribe dicho valor generalmente se coloca al inicio un HARDWARE BPX ON WRITE en la entrada, pero como este packer detecta los HARDWARE BPX, colocaremos un MEMORY BREAKPOINT ON WRITE, para que pare al escribir el valor malo.
Al dar RUN la primera vez que para por MEMORY BREAKPOINT es aqu
Vemos que no es el lugar buscado porque al ejecutar la linea con F8 no guarda el valor malo en la entrada, asi que damos RUN nuevamente.
La proxima vez que para es aqu
Vemos que tampoco guarda el valor malo en la entrada damos RUN de nuevo.
Tampoco luego de pasarla con F8 la entrada sigue con otros valores.
Seguimos buscando el punto donde guarda el valor malo, vemos que va parando pero nunca guarda el valor buscado.
Al pasar el ultimo REP MOVS la IAT quedo con estos valores y aun no tiene el valor malo definitivo, sigamos dando RUN.
Hasta que llega aqu que vemos que ECX tiene el valor malo y lo guardara en la entrada.
ECX es 9F06F7 y lo guardara en el contenido de EAX o sea en 460ADC en la entrada que estamos investigando, este es el punto donde queriamos llegar.
Vemos que al apretar F8 guardo el valor malo, este es el primer paso que debemos hacer cuando utilizamos este metodo, ahora viene la parte mas trabajosa que es hallar el salto magico.
Como vemos al llegar a ese J E un poco mas abajo vemos en los registros, el nombre de la api que corresponde a esta entrada que acaba de llenar con el valor malo o sea GetVersion.
Luego vemos que llega a una llamada a GetProcAddress para encontrar la direccion de GetVersion en mi maquina ya que los parametros son.
Yo entre en la api para ver los parametros pero no es necesario, pasamos con f8 el CALL.
Y en EAX nos devuelve la direccion de GetVersion en nuestra maquina sigamos traceando.
Alli llegamos a un salto, el cual saltara veamos que pasa sin tracearlo, haciendo click en FOLLOW
Vemos que alli guardara la direccion pero en otro lugar no en la IAT ya que EDI vale
luego de guardar esos valores llega a este J MP
Que nos devuelve al inicio del proceso porque al retornar del mismo ya el valor de EAX es machacado.
Veamos con FOLLOW donde iria
Alli se ve claramente que EAX en la segunda linea perdera el valor correcto de la api en mi maquina y seguro pasara a repetir el ciclo para la siguiente entrada asi que debemos estar cerca. Podemos fijarnos para entradas malas cuales son los saltos condicionales que saltan, para luego cuando traceemos para entradas buenas podemos comparar.
Mucha veces yo me hago una tablita que suele ayudar mucho y es que en la rutina de este loop anoto que ocurre con los saltos tanto con entradas buenas como con entradas malas.
PARA ENTRADAS MALAS (pondre imagenes de todos los saltos a medida que paso por ellos traceando, hasta llegar a donde guarda el valor)
Esto es un miniloop luego de salir de el
Alli ya llega a GetProcAddress y luego salta donde lo guarda
Alli lo guarda este es un traceo completo para una entrada mala, mirando los saltos condicionales como funcionan en ese caso, ahora llegaremos el OEP y buscaremos una entrada buena para hacer el mismo trabajo y comparar.
Llego al OEP
Como entrada buena elegimos 460BAC, ahora realizamos el mismo proceso que hicimos con la mala.
Reiniciamos y la buscamos antes de ejecutar el programa.
hora ponemos un MEMORY BREAKPOINT ON WRITE para tratar de interceptar el momento
lli para cuando va a guardar en la entrada el valor bueno.
emos que EAX tiene el valor de una posible api aunque aun no dice el nombre, pero si miramos
A en que el packer guarda la entrada buena.
A
V con GOTO EXPRESSION -EAX
Vemos que nos lleva alli, y al volver al codigo magia aparecio el nombre jeje.
Ahora vamos a hacer el m la, esperemos que siga en orden y que la siguiente sea buena hasta que trabaje con una buena.
PARA ENTRADAS BU
ismo trabajo que hicimos con la entrada ma tambien si no deberemos seguir ENAS del loop y comenzamos a tracear. Llegamos hasta el inicio
ste salta igual que en las entradas malas
ste en las entradas malas no saltaba pero es un salto muy pequeo no creo que sea desicivo, igamos.
E E s
Ese no salta igual que en las malas
aqu vemos una gran diferencia este salto en las entradas malas no saltaba y aca si y vemos que el
Alli vemos que es un salto bastante largo lo cual puede ser la diferencia de la desicion entre si una entrada se guardara buena o mala, o sea este si todo va como imaginamos seria el posible salto magico, un salto que decide si la entrada se guardara buena o mala, quiere decir que para que una entrada se guarde buena este salto debe saltar asi que una posibilidad seria hacerlo J MP.
Pero ese salto no se encuentra en el inicio del programa debemos ser muy cuidadosos si reiniciamos el OLLYDBG y buscamos el salto
codigo que salta es mucho.
Vemo
l tema es como parar alli ya que HBP no acepta y BP los detecta asi que deberemos aguzar la
s que al inicio alli hay pura basura, asi que el packer creara ese salto mas adelante. E imaginacion.
Pondremos un BPM ON WRITE que abarque a toda la IAT para que pare cuando guarda el primer valor.
El inicio de la IAT era 460818 y el final 460f28 abarquemos toda esta zona con el BPM ON WRITE.
Alli esta tod er valor.
En los STOS para m os si en este mome
ues esta OEP.
demo
lli llegam
a la IAT con el BPM ON WRITE ahora lleguemos adonde guarda el prim uchisimas veces ya que abarca toda la IAT el BPM, asi que mirem nto ya esta visible el posible salto magico
P alli visible veamos que pasa si lo cambiamos a J MP y quitamos el BPM y llegamos al Hay dos posibilidades que el packer detecte los cambios y que falle o que corra y llegue al OEP, s RUN.
A os al OEP miremos la IAT
os haberlo
Le quito la tilde a REBUILD IMPORT. Todos valores correctos, jeje ya tenemos la IAT reparada, ahora dumpeemos, podiam hecho antes no hay diferencia con esto.
Y dump
magico hizo su magia jeje. Ahora reparo el dum
Alli lo guardo com
Funciona perfecto jeje
Bueno hemos visto un m pre varia de un packer a otro, pero comparando y m ena y una mala, siempre lo podemo
hasta la parte 38 Ricardo Narvaja 22/03/06
eo, ahora abro el IMP REC y le pongo nuevamente los valores de RVA; SIZE Y OEP.
eo que ahora sale todo valido, el salto V
peado apretando FIX DUMP.
o dumped_.exe y lo ejecuto a ver si funciona. etodo para hallar el salto magico que siem irando un poco entre lo que hace con una entrada bu s llegar a ubicar facilmente, continuaremos con mas packers en la parte 38.
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 38
En la ultima entrega vimos nuestro primer programa con entradas redireccionadas y como repararlas y continuaremos levemente aumentando la dificultad de los packers para ir aumentando el nivel, asimismo, empezaremos con los ejercicios para que practiquen un poco.
Aqu tenemos un unpackme de Yoda Crypter 1.3 para practicar un poco, por supuesto el OLLYDBG debe tener los plugins necesarios para no ser detectado por el antidebugging como vimos en partes anteriores.
Aqu estamos en el Entry Point
Vemos un PUSHAD funcionara? Probemos el metodo, lleguemos hasta alli traceando y pasemos con F7 el PUSHAD.
Hacemos ESP-FOLLOW IN DUMP y luego marcamos los primeros 4 bytes como vimos anteriormente y colocamos un HARDWARE BPX ON ACCESS.
Vemos una rutina que creara un manejador de excepciones y luego como salta con un J MP a una zona de ceros para provocar un error, asi que si traceamos y llegamos al J MP.
Alli va a saltar al error, miremos adonde saltara en el manejador de excepciones.
El mismo esta en 46590b, el que no quiere complicarse mucho la vida y llegar al OEP, aqu se puede poner un BPM ON ACCESS en la primera seccion y al pasar la excepcion llegaremos al OEP.
Alli esta el OEP es 4271B0 ya que esta empacado siempre con el mismo crackme, jeje.
ma normal ucho
Los que quieren profundizar un poco mas ya pueden ver que en el manejador de excepciones se nipula el context para modificar EIP y por lo tanto la direccion de la excepcion, que era mente 465982, o sea donde se produjo la excepcion, y es sobreescrita con la direccion del OEP o sea 4271B0 para que retorne de la excepcion directo al OEP, aunque esto no importa m por ahora, lo dejamos anotado para futuros estudios que hagamos de la estructura CONTEXT. Bueno la cuestion es que ya estamos en el OEP, podemos DUMPEAR.
Le quitamos la tilde para que no intente reparar la IAT y DUMPEAMOS.
Por supuesto si ejecutamos el yodadump.exe nos da error, nos podriamos haber dado por muy afortunados si corriera solo en nuestra maquina, pero ya veremos que la IAT tiene entradas redireccionadas lo cual hace que no pueda correr para nada, al tratar de acceder a esas direcciones inexistentes en el dump.
Bueno comencemos a analizar la IAT, busquemos una llamada a una api, alli debajo vemos una llamada a GetVersion la misma de siempre jeje.
Bueno vemos que dicho CALL toma valores de 460ADC para ver donde saltara o sea que esta es una entrada de la IAT, vayamos a verla en el DUMP.
Pues se ve esta parte de la IAT como correcta ya que si miro en el mapa de memoria donde van las entradas, todas van a 7C8XXXXX o cercanas y esas direcciones caen en la seccion code de kernel32.dll o sea que estas entradas serian correctas.
Por lo demas si busco referencias en cualquiera de ellas al azar y haciendo click derecho FIND REFERENCES hay referencias.
Si sigo bajando hasta la separacion
Veo que el siguiente grupo va a una zona de memoria 15XXXX veamos que hay alli.
Vemos una seccion queno hay dll asi que seguramente esa seccion fue creada por el packer, si reinicio para comprobarlo.
Vemos que hay una seccion creada por el sistema de 3000 bytes, pero la que usa el packer es de 29000 bytes mucho mas larga asi que el packer agrando esa seccion para su uso.
Por lo tanto estas son entradas redireccionadas por el packer a esa seccion, veamos una de ellas a ver como trabaja.
Tomare una de ellas, por ejemplo esta, y buscare la referencia, haciendo click derecho FIND REFERENCES.
Hay dos calls que tom e llevara en el listado
.
emos que la redireccion es muy sencilla, podra el IMP REC con sus traceadores repararla sin
Alli es
an valores de dicha entrada, mirare el primero haciendo doble click en el, m adonde esta ubicado.
Alli vemos el CALL, hagamos click derecho FOLLOW a ver que hace en la seccion redireccionada Vemos que sin muchos prolegomenos salta a la api SysStringLen directamente,por lo cual si lo traceamos a mano ya sabemos cual es la api correcta para esta entrada. V necesidad de hallar el magico?
bramos el IMP REC. A
ta el proceso detenido en el OEP, lo elegimos en el menu desplegable. No olvidemos que al IMP REC debemos darle 3 datos OEP, INICIO DE IAT y LARGO.
OEP=4271B0 al cual restandole la imagebase da 271B0
El inicio de la IAT si subimos en la misma.
Vemos que las entradas de la IAT o bien van a de dlls o bien a la seccion 15xxxxx el redireccionamiento, si seguimos subiendo a ver cuando acaban las entradas.
Vemos que hasta alli se repite el rencias a ver si hay mas entradas e la IAT, no hallo en ninguna.
Por lo cual la prim 60818 al restarle la agebase. la seccion code d
esquema, mas arriba si busco refe d
era entrada de la IAT es 460818 para el IMP REC es RVA= im
El final lo hallo de la misma manera voy bajando a ver donde termina el esquema de entradas que van a seccion code de dlls o aredireccionadas a la seccion 15XXXX.
Alli vemos la ultima ay para ninguna entrada, asi qu quede dentro, el final de la IAT es 460f28, ahora ebemos hallar el largo de la misma. Asi que poniendo en lim
EP=271B0 IZE O LARGO=710 n el IMP REC.
Al apretar GET IMPORTS
entrada de la IAT es 460f24 mas abajo si busco referencias no h e para que la ultima entrada d
LARGO=FINAL -INICIO=460f28 - 460818=710
pio O RVA o INICIO=60818 S
Pongamos estos valores e
Vemos que hay 296 entradas sin resolver, lo podra resolver con algun traceador?
Si apreto el boton AUTO TRACE se cuelga, probemos con los otros traceadores, apreto SHOW INVALIDS y en las entradas marcadas hago click derecho TRACE LEVEL 1.
Dice que resolvio todo y que no hay mas entradas invalidas, le creemos? J eje. Si apreto SHOW INVALID nuevamente veo que todas estan YES.
Probemos reparar el yodadump.exe apreto FIX DUMP
Alli me creo el yodadump_.exe que supustamente esta reparado, probemoslo.
J eje esta vez se porto el IMP REC y me ahorro mucho trabajo.
Ahora ademas de esto y para jorobar un poco, tiene salto magico este packer?
Busquemos una mala entrada en la IAT en el programa que esta detenido en el OEP.
e colocare un HARDWARE BPX ON WRITE antes de reiniciar, ya que los HBP se mantienen,
or supuesto el metodo es tratar de parar cuando guarda el valor malo 15XXXX en la entrada, para
lli pa lor de una API.
lo guarda en la entrada la
L aun despues de reiniciar y ya vimos con el metodo del PUSHAD que el packer no es alergico a los mismos.
P ello reinicio el OLLYDBG y doy RUN.
A ro y guardo el valor bueno en la entrada de la IAT vemos que EAX tiene el va
Y cual esta siendo apuntada por EDX, quiere decir que en este caso, primero guarda el valor bueno y luego lo modifica por el malo, sigamos traceando a ver cuand sucede esto.
o
emos que apenas una cuantas lienas mas abajo, ESI toma el valor malo y lo va a sobrescribir en la
uiere decir que las entradas buenas solo escribiran la primera vez y no llegaran a esta segunda epitamos el proceso ahora con una entrada buena, la de GetVersion que estaba unas lineas debajo
emos que para a
raceemos un poco. V entrada.
Q parte donde sobrescribe con el valor malo.
R del OEP estaba correcta asi que usemosla era 460ADC pongo un HBP ON WRITE en ella.
V lli, al guardar la direccion correcta que esta en EAX.
T
Vemos que llega al J MP que evita la zona marcada con la flecha roja donde se cambia por el valor malo, asi que el tema es evitar que salte este J MP, algunos de los saltos anteriores que evitan el J MP es el salto magico, veamos cual es ya que hay varios saltos condicionales, delante del J MP.
Tambien podriamos intentar como solucion NOPEAR la linea donde guarda los valores malos asi no lo guarda y queda toda la tabla bien, eso seria tambien correcto, podemos probar si funciona.
Para ello marco la linea anterior a la que guarda los valores malos y le coloco un HBP ON EXECUTION y reinicio hasta que pare alli por primera vez, lo coloco en la linea anterior porque el HBP para una instruccin despues de donde lo coloque y no quiero que me guarde el valor malo.
Alli paro, probemos nopeando la linea donde guarda el valor malo.
Ahora sigamos a ver si no detecta el nopeo que hice y llega al OEP.
Quito el HBP y doy RUN
Bueno el maldito detecta los cambios que hice y da error, asi que el nopeo no va, continuemos con el salto magico.
Traceando cualquier entrada mala, veo que es este el salto magico, el que evita el J MP y me lleva a la zona donde guarda el valor malo, asi que habria que nopearlo para llegar al J MP, aunque dudo que no detecte el nopeo, igual probemos.
ual en ambos metodos el programa nos da error pero luego de haber reparado correctamente toda
eo que la IAT esta toda correcta asi que no hay problema ninguno, tengo dos posibilidades aqu, o l Ig la tabla si miramos la misma, en el programa que se detuvo por el error.
V bien abro en otro OLLYDBG otra instancia del crackme, y sin modificar nada, llego al OEP, y le copio y pego la tabla correcta encima de la mala, con BYNARY COPY y BINARY PASTE lo cua es muy sencillo, tambien puedo utilizar directamente este proceso para el IMP REC que aunque no haya llegado al OEP ya tiene toda la IAT correcta y eso es con lo cual trabaja el IMP REC, el resto no importa, asi que si lo abro en el IMP REC y le coloco los valores correctos de OEP; RVA y SIZE, y apreto GET IMPORTS.
Veo que me salen todos los valores correctos, y aunque el proceso que tengo detenido no me sirva para dumpear ya que no llego al OEP, no importa ya que he dumpeado previamente en uno que si llego al OEP, y a ese dumpeado solo le falta la tabla que este si tiene correcta, por lo cual puedo reparar perfectamente con este proceso el dumpeado que ya tenia hecho, sin problemas y funcionara correctamente, si borro el anterior yodadump_.exe que estaba ya reparado y busco el dumpeado anterior yodadump.exe, y apreto fix dump y lo reparo.
Me crea un nuevo yodadump_.exe veamos si funciona.
Si funciona perfectamente quiere decir que aprendimos que el dumpeado se necesita hacer desde el OEP ya que alli esta todo el programa desempacado en memoria, pero la tabla puede arreglarse desde un proceso que la tenga correcta, aunque no haya llegado hasta el OEP, porque el IMP REC no cambia nada del DUMPEADO, salvo la IAT la cual esta correcta, por eso el dumpeado funciona perfectamente.
Como ejercicio les dejo el archivo adjunto para desempacar, es muy sencillo si que espero que lo puedan hacer sin problemas.
Hasta la parte 39 Ricardo Narvaja 27/03/06
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 39
Buenoen esta parte y la 40 empezaremos el tema de stolen bytes y scripts para ello usaremos uno unpackme conocido el UnPackMe_PELock1.06.d.exe que tiene su miga, y que del mismo o variaciones del mismo han hecho esta semana grandes tutes en la lista como el de Otup que esta regenial..
Aqu estamos en el inicio del programa paraditos en el OLLYDBG
Usaremos una variacion del metodo de las excepciones mas adelante veran porque, en este caso en vez de confiar en el LOG de OLLYDBG haremos nuestro propio LOG de excepciones, porque en estos packers una excepcion que se te pasa o no sale en el LOG o que es camuflada nos puede hacer mucho lio, lo cual puede ser posible ya que OLLYDBG no es perfecto y ya me ha ocurrido en packers raros y asi terminamos muertos, entonces estudiemos este BP.
Este BP sera nuestro LOGUEADOR de excepciones, por ahi OLLYDBG loguea las mismas pero yo cuando me enfrento a packers con muchas excepciones y mas de un Thread como en este caso que crea un thread, antes de llegar al OEP, siempre confio en el logueo directo hecho por mi y no en el que hace OLLYDBG, el tema es que todas las excepciones deben pasar por este punto en el cual acabamos de poner un BP, si lo vemos en OLLYDBG.
Esta rutina la podemos analizar facilmente de esta forma.
O sea el punto marcado con entrada es el inicio de la rutina que maneja las excepciones en la ntdll.dll, el call marcado con AL MANEJ ADOR, en un call que detro del mismo, luego de muchas vueltas salta al manejador de excepciones que nos indica VIEW-SEH CHAIN, luego de ejecutar el manejador de excepciones, retorna a esta rutina y llega hasta RETORNO donde dentro de ese call vuelve a continuar la ejecucion del programa.
Aclaro por si alguien se pone a tracear, que cuando salto de aqu al programa, no podemos llegar traceando, pues hay rutinas RING0 intermedias que OLLYDBG no puede tracear, en ese caso si queremos parar en el programa desde aqu debemos poner un BP en el manejador o retorno o tambien BPM ON ACCESS en toda la seccion donde se produjo la excepcion, para que OLLYDBG despues de que termine de ejecutarse la parte RING0, pare en el programa nuevamente, digo esto porque no faltara el curioso que quiera tracear desde aqu hasta el programa, y no se puede con OLLYDBG se llega un punto donde se salta a RING0 donde no se puede continuar traceando.
Bueno igual con los puntos que tenemos, ya es suficiente, si damos RUN y para en la primera excepcion.
Vemos en el LOG que la misma se produjo en mi maquina en 3a5c74 y luego de ella como teniamos todas las tildes marcadas en DEBUGGING OPTIONS-EXCEPTIONS, paro directamente en el BP que colocamos.
Ahora si miramos el stack
Vemos que unas lineas mas abajo esta la direccion donde se produjo la excepcion, excatamente en [esp +14]
Por lo tanto si coloco un BREAKPOINT CONDICIONAL LOG en vez de un BP y hago que loguee [ESP+14] tendre mi logueador propio jeje.
Por lo tanto hago click derecho, y cambio el BP que habia colocado por un CONDITIONAL LOG.
Pongo la tilde para que siempre loguee el valor de [esp+14] cada vez que pase por alli y que no pare, solamente loguee, y doy RUN.
Vemos que el programa arranca, extraamente casi ningun packer detecta los BP o BP CONDICIONALES en KiUserExceptionDispatcher.
Bueno miremos nuestra obra en el LOG.
Alli se ven y OLLYDBG logueo bien las que se ven aqu, la ultima esta un poco mas abajo.
Vemos que la ultima excepcion es una ACCESS VIOLATION en 3A6744, pero alli no podemos poner BP ni HE estos ultimos son detectados por el packer y no corre el programa, veamos
Una opcion que tengo es llegar al punto quitando la tilde de MEMORY ACCESS VIOLATIONS y parar en todas hasta que lleguemos a la ultima, este metodo si bien funciona, pensemos en algo mas generico y rapido y que sirva para todo tipo de excepciones, asi que vuelvo a colocar esta tilde.
Y sin matarme mucho voy a B donde esta la lista de breakpoints y aun esta mi BP condicional alli, hago click derecho- EDIT CONDITION.
Solamente debo agregar la condicion para que pare, si logueabamos [esp+14] y en el momento que queremos que se detenga ese valor era 3a7644, ya que era la intruccion donde se genero la excepcion que nos mostraba nuestro LOG, pues entonces que pare cuando [esp+14]==3a6744 y listo.
Cambio la tilde a que PAUSE PROGRAM-ON CONDITION para que pare cuando se cumpla la comdicion que colocamos y damos RUN.
Alli paro el programa en la ultima excepcion y sin tener que estar contando una a una, ademas si queremos volver a este punto, pues reiniciamos damos RUN de nuevo y parara aqu las veces que queramos sin tener que estar contando excepciones.
Por supuesto si desde aqu coloco un BPM ON ACCESS en la primera seccion pararemos en el OEP (sera asi? J eje hagamoslo)
Vemos que ahi para en la primera seccion en el supuesto OEP, pero que pasa aqu?
En este punto comenzaremos a estudiar los stolen bytes.
STOLEN BYTES son bytes del programa que son ejecutados por el packer, lo mismo que STOLEN CODE es codigo del programa ejecutado por el packer.
Los stolen bytes generalmente son las primeras instrucciones del programa original a partir del OEP
ara que se hace esto?, muy simple si yo dumpeo aqu y reparo la IAT y coloco como OEP packer, ue debo hacer? n metodo es tratar de tracear la rutina del packer, luego de la ultima excepcion y llegar al OEP e or eso realice el metodo de las excepciones de esa forma, ya que muchas veces el traceo en tengo . iremos antes de reiniciar un poco el panorama, cual es la forma de sospechar que hay stolen einiciemos el programa.
i veo el stack al inicio.
sta en 12FFc4 en mi maquina, y sea cual sea el valor en la suya, en el OEP salvo casos muy en el que el packer borra de la primera seccion y los ejecuta en otra seccion propia, y luego en vez de saltar al OEP salta a la 5 o 6ta linea por ejemplo habiendo ejecutado las anteriores en una seccion propia, generalmente fuera de las secciones del ejecutable.
P 4271D6, el programa no arranca pues le faltan las primeras lienas, que cuando corrio con el el maldito la ejecuto antes en su propia seccion y luego salto aqu, por lo cual en el dumepado, esas lineas no se ejecutaran.
Q
U FALSO traceando y guardando en un txt todo lo que ejecuto, cosa de poder analizar que fue lo qu ejecuto antes de saltar al ahora llamando falso OEP de 4271d6.
P OLLYDBG tiene unas cuantas posibilidades, tildes y opciones que intentar, y si cada vez que que llegar a la ultima excepcion tengo que contarlas una a una, me volvere loco, por lo cual, tengo la forma de que pare en el punto solo dando RUN, y ya estamos nuevamente en la ultima excepcion
M bytes?, pues mirando el stack.
R
S
E estramboticos, el programa se debe iniciar con el stack en 12FFc4 o cercano, todo lo que haya falso OEP, arriba de esta direccion sera codigo que ya se ejecuto desde el OEP VERDADERO hasta el FALSO
Veamos lleguemos nuevamente al falso OEP.
emos que si este fuera el verdadero OEP, el stack deberia estar en 12FFc4 o cerca, todo lo que hay ste
V arriba son instrucciones que ya se ejecutaron del programa, unas cuantas lineas que desde el verdadero OEP que el packer quito del programa y lo translado a otra seccion, se ejecutaron instrucciones que deberian estar arriba del falso OEP, y que fueron borradas, si recordamos e crackme que es el mismo que siempre venimos estudiando el OEP estaba en 4271b0, si miramos esa zona aqu.
Vem
ultim
La m
Tenemos el parametro que nos marca aqu el inicio de la estructura CONTEXT, miremosla en el DUMP.
os que el packer reemplazo los bytes originales del OEP e instrucciones siguientes con basura, que ademas nunca se ejecuto, pues con el BPM ON ACCESS paramos en la primera linea de codigo ejecutada en esta seccion y no paro en esos bytes sino mas abajo en 4271d6. Pues cuales son los metodos para hallar los stolen bytes, pues hay muchos realmente, el mas clasico es tracear luego de regresar de la ultima excepcion, probemos ese reiniciemos y volvamos a la a excepcion.
isma se habia generado en 3A6744, por lo cual no me interesa en este caso el manejador de excepciones, asi que pondre un BP en el retorno, asi salteo el mismo.
Ahora doy RUN, si alguien quiere saber donde retornara al programa para poner directamente un BP alli, pues veamos en el stack.
Los que ya conocen la estructura CONTEXT saben que isma , entre los valores a al regresar de la excepcion, como ya saben mas delante le dedicaremos un estudio detallado de la estructura CONTEXT por ahora, solo mirando lli saben donde volvera, si no quieren complicarse la vida buscando en el CONTEXT, poniendo un
Y dando RUN vemo
ese es el EIP de la m de los restantes registros que tendra el program a a BPM ON ACCESS en la seccion donde se produjo la excepcion.
s que para en el mismo lugar
lli colocaremos las condiciones del traceo, hay miles posibles, ya que puedo colocar que chequee s valores iniciales de los registros y cuando se cumplan que todos estan igual que antes de correr l programa, estare en el OEP, por ejemplo, pero miremos si funciona estas dos.
A lo e
La prim e ver en el LOGUEO del paramos en el m
onemos las dos tildes en la configuracion para intentar si funciona con ellas, lo cual es lo mas robable, si no, probaremos quitandolas.
Tambien hacemos que loguee a una fila.
Apretamos TRACE INTO y me molesta la condicion de ESP que me hace parar muchas veces, si la quito y sigo con el trace into, para en el falso OEP, y en la fila de texto tengo todas las instrucciones que ejecuto antes, pero no me funciono lo de parar en el VERDADERO OEP, bueno mala suerte.
era parara en el falso OEP pero traceando, lo cual puede dejarm traceo, las instrucciones que ejecut antes de llegar al mismo, la segunda tilde, es para ver si omento del VERDADERO OEP ya que alli vimos que esp=12ffc4.
P p
Una de las posibilidades que se puede intentar es poner que pare en cualquier PUSH EBP o POPAD que generalmente o son el OEP en el primer caso, o la recuperacion de registros en otros casos, uede funcionar o no, ya que muchas vece esto s los push EBP son emulados, pero bueno veamos, ongamos a tracear.
Por supuesto como instrucciones verdaderas no debemos considerar los saltos ni los SAL o cualquier otra instruccin basura.
p p
Podria ser el verdadero OEP, traceemos un poco.
Esta parece ser la segun as directamente del original es facil d
Y asi seguimos tracean falso OEP.
da instruccin faltante, al no ser emuladas y estar copiad etectarlas. do y copiando las buenas instrucciones que va ejecutando hasta llegar al
RET asi que salta alli.
or supuesto ahora hay que copiar todos los bytes de las instrucciones faltantes fijarse cuantos son y pegarlos antes del OEP FALSO vea
Alli vemo o ya verificamos que es todo correcto volvem
Y aqu llegamos al falso OEP ya que hizo PUSH 4271D6 que era la direccion del falso OEP y luego P mos en el DUMP: s la zona del falso OEP, y arriba donde deben ir los bytes faltantes, com os para atrs apretando el menos hasta el verdadero OEP
en un bloc de notas notepad sin colocar el push final y el ret pues esos son un salto al OEP falso no son stolen bytes.
asi que le resto a la direccion del
Asi hallam ubiera quitado. Y ahora si, hare binary copy de cada linea que ejecuto y voy copiando los bytes o
falso OEP esos 26 bytes faltantes. os la direccion de donde deberia haber estado el verdadero OEP si el packer no lo h
O sea que a partir de 4271b0 debemos pegar los bytes que hallamos.
Marco los bytes del notepad y hago COPY y aqu hago click derecho BINARY PASTE. bytes. s los cuales son necesarios para reparar esta IAT Hasta la parte 40 Ricardo Narvaja 4/04/06
Alli se copiaron miremos como quedo el codigo
Ahora si quedo mejor, podria dumpear desde aqu y cambiar el OEP a 4271B0 con lo cual estarian olucionados los stolen s En la parte siguiente vamos a comenzar con script demas lios que cometio el packer. y
0
INTRODUCCION AL CRACKING CON OLLYDBG PARTE 40
Antes de continuar con la tabla IAT del pelock, y los antidumps, en esta parte veremos dos temas, uno que quedo en el tintero y otro que es una gran ayuda para continuar con el tpelock o cualquier otro programa similar que anula o detecta los HBP ya veremos.
El primer tema es que en la pate 39 si descargaron el tutorial apenas salio, no se dieron cuenta, pero luego fue modificado y aparecia un mensaje de texto que decia.
Para realizar este tute se debe utilizar el ollydbg parcheado 4 que esta dentro del rar actual, es un OLLYDBG parcheado que se debe colocar en la misma carpeta que el OLLYDBG.exe, porque el OLLYDBG normal tiene un bug al manejar las ILLEGAL INSTRUCTION, que hace que salga un cartel si o si cuando le pones la tilde en debugging options-exceptions para saltearla, con el parcheado 4, el bug esta reparado, al momento de hacer el tute lo habia olvidado, pero Solid me recordo al no poderlo hacerlo al tute, el problema y al pasarle el parcheado 4 para que ponga en la carpeta del OLLYDBG y usarlo, no tiene ningun problema.
Ricardo Narvaja
Y traia un OLLYDBG modificado llamado PARCHEADO 4 que se coloca en la misma carpeta del OLLYDBG.exe y usando este ultimo sirve mejor para hacer el tutorial de PELOCK.
Lo que queria explicar como primer punto que tiene de especial este parcheado 4.
Bueno el OLLYDBG posee un bug al manejar las excepciones ILLEGAL INSTRUCTION; Si en un OLLYDBG normal (sea renombrado o no) con los plugins para ocultarlo, marcamos todas las tildes en DEBUGGING OPTIONS-EXCEPTIONS y damos RUN.
Obtenemos este error, mientras que en el parcheado 4, corre perfectamente que ocurre aqu veamos en el momento que aparece el cartel de error, lo aceptamos y miramos el LOG del OLLYDBG.exe normal.
Vemos que la ultima excepcion antes de que salga el cartel es una ILLEGAL INSTRUCTION, ahora vayamos a debugging options- exceptions y quitemos la tilde de ese tipo de excepcion.
Esa es la tilde que corresponde a esa excepcion, la quitamos y arrancamos el pelock y damos RUN.
Para en la excepcion y si la pasamos con SHIFT +f9, no hay problema para en dos oportunidades mas en excepciones de este tipo y arranca el pelock.
Eso quiere decir que OLLYDBG tiene un problema cuando le pones la tilde para que pase esa excepcion automaticamente.
Si solo fuera apretar SHIFT +f9 y todo se arregla no habra problema, pero alertados de este bug muchos programadores generaban 200 o 300 excepciones de este tipo las cuales habia que pasar todas a mano con SHIFT +f9 lo cual era pesado al menos.
Ahora volvamos a colocarle la tilde y hagamos que aparezca el cartle de error nuevamente.
Al mejor estilo cracker, lo que haremos sera crackear el OLLYDBG para arreglarle el bug, para lo cual abrimos un segundo OLLYDBG vacio, con el cual crackearemos al que esta detenido en el cartel de error.
En este OLLYDBG vacio iremos a FILE -ATTACH para atachear y debuggear al otro OLLYDBG que este detenido en el cartel de error.
En la ventana que se abre buscamos el proceso OLLYDBG.exe cuya ventana o WINDOW tiene el eror como muestra alli, y apretamos attach.
Alli paro ahora damos RUN
Ahora miraremos el mapa de memoria.
Por supuesto la victima es el otro OLLYDBG cuyas secciones vemos alli, lo que haremos sera colocar un Bp MessageBoxA
Pero ese no es tan importante solo nos sirve como guia para poner el BP en el RET de la api MessageBoxA, y al aceptar el error, parara en el RET al volver de dicho cartel.
Alli vemos cuando retornamos al programa de la api, al apretar f7.
Si recordamos el texto del cartel decia lo que vemos arriba.
Si buscamos entre las strings del OLLYDBG
y alli buscamos la palabra bypass que esta en el mensaje.
Vemos que esa es la string correcta, hagamos doble click para ir al lugar donde esta la misma en el listado.
Vemos que cualquiera de esos J NZ evita que salga el cartel de error podriamos cambialo por J MP y tendriamos nuestro programa parcheado, la guardar los cambios definituvos en memoria con COPY TO EXECUTABLE y SAVE FILE.
Abramos el parcheado 4 en OLLYDBG para mirarlo y veamos esta misma zona a ver como es.
Vemos que en este directamente en vez de parchear los saltos que de cualquier manera nos llevan a saltear el cartel, lo que hice en su momento, fue cambiar el ultimo salto justo antes del cartel y cambiarlo a J MP 43528d, por si acaso salte de algun otro lugar siempre evite el cartel por cualquier camino,
Bueno esto es todo el secreto del parcheado 4 y porque no tiene el bug de ILLEGAL INSTRUCTION como el OLLYDBG.exe normal, asi que pueden parchearlo por ustedes mismos o usar el que esta dentro de la leccion 39, en la correcion fue agregado dentro tambien el PARCHEADO 4.
La segunda parte de este tutorial sera hacer un simple script, para lo cual usaremos el s del hora abrimos el Parcheado 4
emos que aparece el PLUGIN hora abro el pelock que estabamos estudiando, el tema sera hacer un minisript para que funcionen era un sencillo script veremos los comandos que por supuesto los consultamos en el README del OLLYSCRIPT 0.92 que adjunto a este tutorial, y pondremos la dll en la carpeta plugin OLLYDBG.
A
V
A los hardware bpx y que no sean detectados por el packer.
S plugin OLLYSCRIPT.
La idea es la siguiente como vimos en la parte anterior cada vez que para en legue al manejador de
omo es nuestro primer script y para no complicarlo demasiado, los BP en estas direcciones tanto ionDispatcher y en el CALL que va a ZwContinue como vemos en la imagen. hora que ya pusimos a mano empezaremos el script el cual normalmente se comienza con un icio: sto se coloca para que si necesitamos saltar al principio del script facilmente con un J mp inicio esta phws 12ffc4, "r" phws es el comando que coloca un hardware breakpoint en la direccion en este caso 12ffc4, y entre icio: phws 12ffc4, "r" abajo: uego de la colocacion del o los hardware bpx que quiero usar, pongo otra etiqueta llamada trabajo KiUserExceptionDispatcher estamos justo antes de que el sistema operativo l excepciones donde sabemos que pueden ser detectador los HBP y borrados, asi que la idea es hacer un script que cada vez que el programa pare en el Bp KiUserExceptionDispatcher, borre el HBP y cuando llegue al CALL a ZwContinue lo restaure.
C en KiUserExceptionDispatcher y en el call que va a ZwContinue los colocaremos a mano pues ya sabemos ubicarlos, facilmente y logicamente se pueden colocar sin problemas con el mismo script, pero eso ya lo veremos mas adelante no quiero complicarlo de mas, asi que la idea es ir y colocar a mano un BP KiUserExcept
A etiqueta arbitraria en mi caso use inicio:
in
e solucionado, luego de inicio viene el Hardware Breakpoint que queremos colocar por ejemplo.
b
b comillas la r significa on access o read que es lo mismo, si fuera w seria on write y si fuera x seria on execution.
in
b
tr
L por si quiero retornar luego de la colocacion de los HBP.
inicio: phws 12ffc4, "r" abajo: ob pirulo emos alli el comando eob, lo que hace el mismo es que cada vez que el OLLYDBG detecte una o ste es la parte principal, alli cuando ejecute el script el OLLYDBG comenzara a correr la victima, irulo: , 7c91eaec c91eb03 n mi maquina 7c91eaec es la direccion de KiUserExceptionDispatcher o sea cuando pare en ese o pare por el otro BP que esta en CONTINUE y cuando uego solo me queda uitar: 2ffc4 uando salto a quitar para borrar los HBP el comando bphwc sirve para borrar los mismos y luego a otra etiqueta es restaurar que s eactiva en el Call a ZwContinue estaurar: ue directamente salta al inicio donde se vuelven a colocar los HBP y se reinicia el ciclo.
b
tr
e run
v excepcion o breakpoint, pasa la ejecucion a la etiqueta que esta al lado del comando en este caso eob pirulo, significa que cuando el programa pare en una excepcion o breakpoint seguira corriend desde la etiqueta pirulo, y luego doy RUN con el comando llamado run.
E debemos preparar que vamos a hacer cuando detecte una excepcion o BREAKPOINT , para ello escribiremos la etiqueta pirulo:
p cmp eip je quitar cmp eip, 7 je restaurar jmp final
e BP, el eip de mi maquina sera 7c91eaec, por lo tanto compruebo que estoy realmente alli y salto a la etiqueta quitar, para borrar los HBP. Luego hay otra comparacion para cuand detecte que el programa paro por ese BP, vaya a la etiqueta restaurar, para poner nuevamente los HBP.
L
q bphwc 1 jmp trabajo
C de borrarlos salto a trabajo, para que vuelva a ejecutarse todo y a correr el programa pero sin colocar los HBP.
L
r jmp inicio
q
Por supuesto debemos tener una posibilidad de parar el programa cuando OLLYDBG pare por omo cuando ejecuta eob para tambien por cualquier breakpoint o excepcion, cuando para por ra irulo: , 7c91eaec c91eb03 lli en final: nal: N "Continuar?" SGYN es que hacemos aparecer un messagebox con la opcion continuar, para que veamos si nos l nte los BP en Bp KiUserExceptionDispatcher y el nuestro HBP, en ese caso es esta parte final.
C nuestro HBP, tambien ira a pirulo y como no es ninguno de los BP que colocamos a mano segui hasta la etiqueta final:
p cmp eip je quitar cmp eip, 7 je restaurar jmp final
a
fi MSGY cmp $RESULT,1 je inicio ret
M gusta el lugar donde paro o queremos que siga corriendo hasta la proxima vez que pare por el HBP. Si apretamos YES en la variable reservada $RESULT habra un 1, y si apretamos no un 0, por lo cual cuando queremos que continue, al apretar YES el script compara $RESULT con 1 y vuelve a inicio a continuar trabajando, si no es 1 va al ret donde termina y para el script y queda el OLLYDBG parado donde nosotros queriamos. El script completo es (recordar poner manualme CALL que va a ZwContinue) inicio: bphws 12ffc4, "r" trabajo: eob pirulo run
pirulo: cmp eip, 7c91eaec je quitar cmp eip, 7c91eb03 je restaurar jmp final
quitar: bphwc 12ffc4 jmp trabajo
restaurar: jmp inicio
final: MSGYN "Continuar?" cmp $RESULT,1 je inicio ret
Abajo lo vemos mejor con unas flechas explicativas, al inicio ponemos los HB y corremos el r las distintas ue no sean a el BP del CALL a ZwContinue saltara nuevamente a pirulo y ahora comparando eip, nos l robaremos el script lo guardo en una fila de texto y arranco el pelock, luego pongo manualmente programa dejando la trampa lista que cuando encuente BP o excepcion salte a pirulo. A pirulo solo saltara cuando hay BP o excepcion y en ese momento tenemos que testea posibildades, de que sea por los BP que colocamos a mano, o por el HE o por cualquier excepcion. Testeando el eip, podemos determinar si se disparo el salto a pirulo, por el BP de KiUserExceptionDispatcher con lo cual si se verifica, salta a quitar los HBP para q detectados en el manejador de excepciones, y retorna a trabajo donde vuelve a correr el program sin HE. Luego en llevara a restaurar ya que en este momento ya paso el manejador de excepciones y los puedo volover a colocar, y luego para cualquier otro BP o excepcion o si para por el HE, salta a fina donde decido si parar o continuar, si paro va al ret si continuo va a inicio.
P los 2 BP y voy al menu del plugin
.
Veo que para por el HBP, igual apreto YES para que siga
Veo que el programa corrio perfectam
El mism ismos sin ningun problema
En la parte 41 y despues de esta introducci s haciendo scripts y repararemo
Hasta la parte 41 icardo Narvaja ente y veo en la ventana dehardware breakpoints o se encuentra colocado por lo cual el programa corre con HBP y para en los m , que era lo que queriamos lograr, jeje. on que nos ayudara seguiremo s el pelock completamente. R 07/04/06