Está en la página 1de 193

INTRODUCCION AL CRACKING CON OLLYDBG parte 21

Seguiremos ahondando sobre diferentes mtodos antidebugging, hoy usaremos un crackme modificado por m para la explicacin. Es el crackme buggers3, al cual le hice algunos arreglos para poder explicar nuevamente la deteccin por nombre del proceso con otras apis, que trae este crackme, y adems la deteccin por el nombre o clase de la ventana del OLLYDBG que tambin trae este crackme buggers3. Lo abrimos con el OLLYDBG original, no el renombrado, porque estudiaremos tambin una variante del mtodo que vimos en el tutorial 20, por lo tanto necesitamos que el OLLYDBG se llame OLLYDB.exe para que sea pueda ser detectado y estudiar esa proteccin. Lo abrimos entonces en el OLLYDBG.exe, solo protegido por el HideDebugger 1.23f contra la deteccin por la api IsDebuggerPresent.

All esta abierto, vemos que el plugin HideDebugger esta configurado

Solo para proteger al OLLYDBG contra la deteccin por medio de la api IsDebuggerPresent, y adems vemos en la lista de procesos que usamos el OLLYDBG original, pues el proceso se llama OLLYDBG.exe

Bueno volvamos al buggers3 veamos las apis que utiliza en la lista de apis

Glup, solo tiene en la lista la api ExitProcess, el resto las debera cargar con GetProcAddress, pero GetProcAddress si ni siquiera esta en la lista si intento.

Veo que me la toma, pues nos evitamos mayores complicaciones, ahora si demos RUN.

Vemos las apis que va cargando, por supuesto si vemos alguna que nos interesa, llegamos al RET para ver la direccin de la misma, y le ponemos un BP EAX, ya que en EAX estar la direccin que devuelve GetProcAddress. En este caso no nos interesa, seguimos con F9

Para varias veces hasta que hallamos la primera sospechosa de homicidio, ustedes dirn como sabe, pues porque conozco esta proteccin, y por eso se las enseo, para que conozcan cuales son las apis que se pueden utilizar tanto en la versin del tute 20, como en esta diferente versin de la proteccin. Bueno hago EXECUTE TILL RETURN para llegar al RET

All llegamos al RET y por supuesto en EAX esta la direccin de la api en nuestra maquina, que busca el programa, en este caso la de CreateToolhelp32SnapShot ya veremos cuando la utilice para que sirve esta api, por ahora pongmosle un BP, con BP EAX

All quedo puesto el BP en la api.

Demos RUN nuevamente a ver si carga ms apis sospechosas.

Bueno esta ya sabemos que es peligrosa, pues para terminar el proceso, debe obtener el manejador o handle como vimos en la parte 20, y eso lo hace con OpenProcess, as que lleguemos al ret y pongmosle un BP EAX a esta api tambin.

Otra culpable de asesinato el primer grado, jeje, ya vern porque por ahora pongmosle un BP tambin con el mismo mtodo y a su hermanita Process32Next.

Luego viene TerminateProcess

Esta ya sabemos que nos cerrara el OLLY, sin chistar no le ponemos BP porque antes debe pasar por las otras, pero es candidata al BP siempre y culpable seguro jeje.

Otra reculpable jeje le ponemos un BP tambin con el mtodo acostumbrado. Bueno y eso es todo, la prxima vez ya para en la api CreateToolhelp32SnapShot

El stack

Pues busquemos en el winapis32 que hace la dichosa api

Pues lo que hace esta api es tomar como una fotografa o instantnea (SNAPSHOT) de los procesos que estn corriendo en la maquina, pero de esta foto, solo nos devuelve el handle o manejador de la misma ya que en los parmetros no hay ningn buffer donde guardara la lista de procesos, veamos lleguemos hasta el RET.

Y en EAX devuelve el handle

Que es 2C en mi caso, podemos ver si esta en la lista de handles que esta usando el programa

Apretamos el botn H que es la ventana de handles.

All vemos el handle 2C que no nos aclara muy bien que es, pero bueno, el programa maneja el handle de la foto de la lista de procesos, veamos como accede a dicha lista hagamos RUN.

Para en la api Process32First que junto con Process32Next son las encargadas de leer el resultado de la foto, e ir sacando la informacin de los procesos que estn corriendo en nuestra maquina.

Bueno si miramos el Winapis32 vemos la info sobre esta api

All dice que devuelve la informacin del primer proceso que encuentra en el snapshot o foto que se tomo anteriormente y que los parmetros son el handle de la snapshot que en mi caso es 2C y la direccin donde guardara la info o buffer que en mi maquina es 403134.

Esta api solo devuelve la info sobre el primer proceso de la lista, para los siguientes se utiliza Process32Next que es la compaera de esta, en la tarea de leer los datos sobre los procesos.

All esta en el dump, el buffer donde guardara la info sobre el primer proceso, as que ejecutemos hasta el RET para que guarde all la info.

All vemos el nombre del primer proceso de la lista que siempre es el proceso SYSTEM PROCESS continuemos con RUN.

Ajaja aqu hay otro truco, en este caso usa la api FindWindowA y le esta preguntando si la ventana superior que esta a la vista, tiene OLLYDBG como clase de la misma, aqu podra preguntar por el nombre de la ventana tambin, ambos datos se encuentran en los parmetros, pero en este caso, pregunta por la clase de la ventana principal que esta en uso, que obviamente es la del OLLYDBG y cuya clase es OLLYDBG. Como podemos saber eso, pues usemos una utilidad que se encuentra en mi http http://www.ricnar456.dyndns.org/HERRAMIENTAS/V-W-X-Y-Z/WindowseGREATIS5setup.exe Yo se que hay plugins de OLLYDBG que permiten hallar la class y otros datos de una ventana, pero la verdad lo mas completo que vi es este programa veamos, lo instalo y lo arranco.

Vemos que en la ventana WINDOW nos da el nombre de la ventana del OLLYDBG y en la ventana CLASS nos da la clase de la misma.

Que como vemos es OLLYDBG Vemos que la api FindWindowA nos devuelve el handle de la ventana, con lo cual ya sabemos puede cerrarla, o hacer lo que quiera con ella.

O sea no se necesita poner ambos datos el nombre y la clase, podemos buscar uno solo de los dos, y el otro se pone a cero como en nuestro caso.

Bueno lleguemos al RET de la api a ver si nos devuelve el handle de la ventana

Que por supuesto coincide con el que nos averigua el Windowse. Bueno traceemos a ver que hace el programa con el handle de la ventana

O sea compara si es cero, ese seria el caso de que no hubiera una ventana con la clase OLLYDBG o sea en ese caso correra pues no hay OLLYDBG, ahora, al hallar un handle que es diferente de cero, eso significa que hay una ventana con el Class OLLYDBG y salta a ExitProcess.

Al saltar all va directo a la salida del programa sin haber mostrado aun nada.

O sea que el tema es que al volver de FindWindowA, EAX debe ser cero y no saltar. Bueno el plugin HideDebugger 1.23f ahora que ya sabemos evitarlo a mano, tambin viene preparado, para esta deteccin, si vemos en las opciones del PLUGIN

Si ponemos la tilde en el segundo lugar vemos que nos protege contra la deteccin por medio de las apis FindWindow y EnumWindows que es la otra que detecta el nombre de la ventana, as que aprendimos a verlo a mano, a evitarlo, y a entender como funciona, ahora no le ponemos aun la tilde, porque deberamos reiniciar el OLLYDBG para que haga efecto, lo haremos al terminar, por ahora hacemos que el salto que nos lleva a ExitProcess, no salte as continua el programa.

Hago doble click en el flag Z lo cual lo pone a 1 y hace que el JNZ no salte.

Y ahora el JNZ no salta

Y llegamos al JMP que saltea el call a ExitProcess

Bueno continuemos ya terminado el truco de FindWindowA ahora continuara con el de los nombres de los procesos demos RUN

Vemos que llama a Process32Next para ver el segundo proceso de la foto y guardara la info en 403134. Hagamos execute till return y veamos lo que guardo

Ahora el nombre es SYSTEM y su PID es 4 veamos la lista de procesos

All esta veamos que hace con cada proceso volvamos al programa traceando

Vemos que aqu llama a la api lstrcmpA con la cual compara la string SYSTEM que es el nombre del proceso, con el la del crackme buggers3.exe, vemos que esa ser la salida del crackme, cuando llegue a encontrar el nombre de su mismo proceso, pues ira a un MessageBoxA que vemos debajo que nos dice NOT DEBUGGED, pero aun no llegamos all, as que sigamos traceando

Al no ser iguales las strings, el resultado de la comparacin es FFFFFFFF

Y por lo tanto al no ser cero, o sea iguales salta a 40119f sigamos all

Aqu vemos la parte caliente, compara el nombre del primer proceso con OLLYDBG.exe y si es igual, pues el resultado es cero y no salta, con lo cual ira a OpenProcess a ver el handle del mismo y luego a TerminateProcess para cerrarlo como vimos en la parte 20.

Vemos que al no ser el primer proceso OLLYDBG.exe pues salta a Process32Next a buscar el segundo proceso lleguemos all.

Pues guardara en el mismo lugar el nombre del segundo proceso hagamos execute till return

El segundo proceso es smss.exe y su PID es 026C si vemos en la lista de procesos

All esta el PID es 620 decimal o sea 026C en hexa Bueno pues repetir lo mismo con todos los procesos que hay en la maquina uno a uno los comparara con OLLYDBG.exe

Y siempre el resultado de la comparacin nos llevara al salto condicional de 4011b1 el cual cuando halle el proceso OLLYDBG.exe no saltara y nos cerrara el OLLYDBG, as que podemos cambiarlo por un JMP, lo cual evitara que se cierre.

Ahora si desactivamos todos los BP y damos RUN

Con lo cual la proteccin ha sido vencida, ahora ya sabemos que con el plugin HideDebugger nos ocultara la ventana del OLLYDBG de la deteccin de FindWindowA y usando el OLLYDBG renombrado como PIRULO.exe no detectara ningn proceso llamado OLLYDBG, por lo cual all debera correr sin problemas, veamos. Abramos el PIRULO.exe

Coloqumosle la tilde en la opcin para ocultar de la api FindWindowA y apretemos SAVE

Pues reinicimoslo cerrndolo completamente y volvindolo a abrir

Y cargo el buggers3 pero antes me voy a sacar una duda, voy a ver con el Windowse, que cambios realizo el plugin en la ventana del OLLY para que no sea detectada

Vemos que ahora no aparece el nombre OLLYDBG en el titulo de la ventana y la clase ?

Vemos que por el lado de la clase no nos protege para nada debemos hallar otra cosa. La herramienta que no es un plugin que nos ayuda con esto es el Repair 0.6, es un parcheador de OLLYDBG que se encuentra en mi http aqu http://www.ricnar456.dyndns.org/HERRAMIENTAS/Q-R-S-T-U/repair0.6.zip Si lo bajamos y cerramos el OLLYDBG y arrancamos el parcheador

Bueno as que tenemos un tercer OLLYDBG parcheado que se llama NVP11.exe veamos en la carpeta del OLLYDBG donde esta

All esta, abrmoslo y veamos que CLASS tiene el mismo

Vemos que tiene como CLASS Nvp11 y por supuesto el nombre del proceso tambin es ese, por lo cual el buggers3 debera correr aqu perfectamente sin cambiar nada, probemos

Doy Run y

Quiere decir que nuestro OLLYDBG parcheado, es cada da menos detectado, al menos ya no se lo puede detectar ni por el nombre del proceso OLLYDBG ni por el titulo ni la clase de la ventana, jeje en la parte 22 seguiremos fortificando nuestro OLLYDBG y aprendiendo como funcionan mas detecciones antidebugger, como entenderlas, arreglarlas a mano y al final con algn plugin , para evitar trabajar de mas jeje. Hasta la parte 22 Ricardo Narvaja 27 de diciembre de 2005

INTRODUCCION AL CRACKING CON OLLYDBG parte 22


Bueno seguiremos con mas trucos antidebugging en esta parte veremos dos trucos antidebugging simultneamente, ya que uno trabaja con el otro, por lo tanto estudiaremos los dos. Es de mencionar que siempre estamos dando por sabido todo lo visto anteriormente y que iniciaremos este tute con el OLLYDBG que parcheamos en la parte 21, que se llama NVP11, con el plugin HideDebugger 1.23f por ahora configurado as.

All vemos que hay una tilde llamada UNHANDLED EXCEPTION TRICKS, bueno estudiaremos este truco, a su vez que trabaja conjuntamente con otro truco que podemos encontrar tambin usado en forma separada, es el llamado a la api ZwQueryInformationProcess para detectar el debugger. Usaremos el crackme adjunto llamado sphynx.zip, ya sabemos desde aqu que si le ponemos la tilde en UNHANDLED EXCEPTION TRICKS corre perfectamente, pero veremos un poco como trabajan ambos mtodos. Otra cosa de aclarar que estos crackmes que no estamos solucionando, los veremos mas adelante, por ejemplo este necesita para solucionarse usar el mtodo de fuerza bruta para hallar el serial correcto, y es posible que lo usemos como ejemplo cuando veamos ese mtodo de ataque, por ahora solo lo haremos correr en OLLYDBG y explicaremos su mtodo de proteccin.

Cargo el crackme en el Nvp11 (OLLYDBG parcheado) y verifico que las opciones del plugin HideDebugger 1.23f, estn como en la primera imagen y adems dejo por ahora las excepciones todas marcadas.

Doy RUN

Y el crackme llega a la ventana principal pero la proteccin esta despus. Coloco un serial falso y apreto check

Me dice que no es posible procesar la excepcin y se cierra si doy RUN.

Bueno me doy cuenta de que si lo pruebo fuera de OLLYDBG, el crackme no se cierra, continua funcionando y dndonos la posibilidad de seguir intentando con diferentes seriales. Bueno reinicimoslo y veamos las apis que utiliza

Recordamos que el plugin HideDebugger tena la opcin para protegernos de los trucos de esta api

Pero antes de poner la tilde aprenderemos a pasarlo a mano y a ver como trabaja Veamos la definicin de la api SetUnhandledExceptionFilter en el WINAPI32

Bueno vemos que uno de los parmetros de la api, es la direccin de donde continuara ejecutndose, cuando el programa encuentre una excepcin, siempre que el programa NO ESTE SIENDO DEBUGGEADO jeje, all lo dice y para comprobar si esta siendo debuggeado o no utiliza un llamado a ZwQueryInformationProcess. Bueno miremos el programa, all mismo en el inicio ya llama a esta api

Como vemos el nico parmetro, es la direccin adonde continuara ejecutndose el programa cuando halle una excepcin, si es que no hay debugger jeje, ira a 401108 si hay debugger ira al tacho de basura. O sea ya veremos que un programa coloca manejadores de excepciones, para cuando se produce una de ellas, el programa siga corriendo a partir de la direccin que indica el manejador, pues esta api hace eso, fuerza al programa a que cuando encuentre una excepcin, contine a partir de la direccin que nos indica el parmetro, pero eso si siempre y cuando no haya un debugger. Bueno pongamos un BP en las dos apis que trabajan juntas estas son SetUnhandledExceptionFilter y UnhandledExceptionFilter las hermanas jeje.

Ahora demos RUN

Para al inicio del programa cuando instala la direccin donde continuara cuando halle una excepcin.

Como vemos la direccin es 401108 pongamos un BP alli

Ahora demos RUN y vemos que para en SetUnhandledExceptionFilter llamado desde dlls

Como estas no nos interesan y ya esta colocado el manejador del programa le quito el bp a esta api.

Ahora tipeo un serial falso y apreto CHECK y para en la otra api en UnhandledExceptionFilter, porque ha hallado una excepcin que seguramente ha sido generada por el programa intencionalmente para llegar aqu y que esta api decida si esta siendo debuggeado o no y de esta forma ir a la zona caliente en 401108 o al tacho de residuos jeje.

Esta api verificara si el proceso no esta siendo debuggeado y har el salto a 401108, traceemos con f8 la api a ver como detecta el debugger.

Llegamos, aqu este el segundo truco antidebugger que veremos hoy, es una forma de detectar el debugger que usa esta api y que puede usar un programa separadamente llamando a la api directamente ZwQueryInformationProcess con el parmetro INFO CLASS=7

Esta api devuelve informacin del proceso que esta corriendo y con el parmetro INFOCLASS=7 devuelve la informacin en el buffer de si el proceso esta siendo debuggeado o no. Veamos el buffer en el dump

Ese es el buffer vimos que su tamao es 4 bytes, y all la api devolver FFFFFFFF si esta siendo debuggeado el proceso o cero si no lo esta, pasemos con f8 la api a ver que guarda all.

All vemos que devuelve FFFFFFFF o sea que hay debugger mi amigo jeje

Vemos que luego viene una comparacin que ve si el valor ese es cero o no, ya que EDI vale cero.

Y all no salta

Al no ser igual a cero el buffer, el salto decisivo no salta y vamos al muere.

Vemos que se va al error y se cierra. Ahora reiniciare y repetir el proceso pero esta vez modificare el resultado de la api ZwQueryInformationProcess. Reiniciemos y cuando llegamos a

Vemos el buffer en el dump

Pasamos la api con F8

Y all guardo al igual que antes el FFFFFFFF de que hay debugger lo cambio a cero

Cambio el contenido a todos ceros

Ahora llego a la comparacin

Como ambos miembros son cero

Ahora si saltara

Y si doy RUN

Vemos que ahora si llega a 401108 y mas abajo veo la parte caliente

Y el messageboxa de correcto, pueden probar que

Al invertir este salto y forzarlo a que no salte, mostrara el mensaje correcto de que el crackme esta solucionado.

Ahora doy RUN

Bueno como he dicho todo esto puede ser evitado si ponemos la tilde en el plugin HideDebugger en UnhandledExceptionTricks y cierro y vuelvo a abrir el OLLYDBG veo que correr perfectamente. El nico tema que queda por ver es como evitar la deteccin por la api ZwQueryInformationProcess, cuando esta es llamada en forma directa y no dentro de la api UnhandledExceptionFilter. Por supuesto ya vimos como pasarlo a mano cambiando a cero el valor de retorno del buffer, pero existe algn plugin que lo haga automticamente, as nos olvidamos de esto? http://www.pediy.com/tools/Debuggers/ollydbg/plugin/hideOD/hideod.rar Este plugin permite que el programa sin tener que cambiarlo a mano nos proteja de la deteccion de esta api.

Vemos que tiene muchas mas opciones que el otro Hidedebugger, as que puede complementarse, es importante si se activa cualquier opcin, siempre poner la tilde tambin en AUTORUNHIDEOD para que proteja automticamente y no tener que apretar HIDE cada vez que arrancamos OLLYDBG.

Vemos que aun quitando la proteccin contra UnhandledExceptionFilter, como esta detecta el debugger por medio de ZwQueryInformationProcess igual corre ya que el plugin nos protege tambin de esta ltima que es la usada para detectar si hay debugger o no como vimos. Bueno ya vimos como protegernos de estos dos trucos manualmente y por medio de plugins, nuestro OLLYDBG parcheado y con ambos plugins es casi una fortaleza jeje igual seguiremos viendo los trucos antidebugging que faltan, que aun hay mas. Hasta la parte 23 Ricardo Narvaja 31 de diciembre de 2005

INTRODUCCION AL CRACKING CON OLLYDBG parte 23


Vamos a ver aqu la ultima parte sobre antidebugging que versara sobre los ProcessHeap Flag y NTGlobalFlag y con eso ya tenemos una idea de los trucos antidebugging mas conocidos, por supuesto no son todos pero creo que son los bsicos que hay que saber y con eso corrern la mayora de los programas en OLLYDBG, por supuesto hay algunos protectores como execryptor que son campeones de la deteccin de OLLYDBG y adems de todos los trucos que enseamos aqu, aaden 4 o 5 mas de su propia cosecha, pero eso es algo mas especifico para leer tutes sobre dicho packer como los escritos por Juan Jose y adems saber que execryptor cada versin que saca nueva, trata de agregarle nuevas detecciones y trucos por lo cual es necesario hacer un estudio sobre los antidebugging de execriptor mas que sobre antidebugging en general. Ya sabemos que con los plugins que tenemos ambos flags no sern detectados, pero es bueno saber como ubicarlos en nuestra maquina.

All estn en el PLUGIN HIDEOD, las opciones para ocultar el OLLYDBG de la deteccin por ambos flags, pero como podemos localizarlos en nuestra maquina a mano, pues eso es saber y el saber no ocupa lugar. Estos dos ltimos flags muestran que el proceso esta siendo debuggeador, son fcilmente localizables, si no recuerdan como hallar la zona del byte IsDebuggerPresent relean la parte 19 que es la que explicbamos como hallar a mano la zona del byte IsDebuggerPresent ya que estos bytes son vecinos de ese.

Quitmosle un minuto la tilde en el plugin para ver los valores que tienen los flags, sin utilizar el plugin para ocultarlos. Para practicar con estos flags utilizaremos el CRACKME DE CRUEHEAD 1 en el cual localizaremos ambos flags. Abrmoslo en OLLYDBG, recordando verificar que la tilde en el plugin HideOdbg como muestra la imagen anterior este sin marcar.

Pues bien, veamos como localizar y cambiar a mano ambos flags. Lo que debemos hallar es la zona del byte IsDebuggerPresent como vimos en el tutorial 19, la forma facil de hallar esa zona es marcar el registro EBX aqu en el ENTRY POINT, y hacer FOLLOW IN DUMP, la forma completa puede leerse en ese tutorial si alguien no la recuerda. Estoy en el ENTRY POINT Marco EBX-FOLLOW IN DUMP

Y en el dump vemos la zona deseada, recuerden que en su maquina puede cambiar la direccin, con respecto a la ma y cada vez que reinicien un programa tambin variara.

Por supuesto recordamos que ese es el Byte detectado por la api IsDebuggerPresent, pues el NTGlobalFlag es vecino de este lo vemos sumando 68 a la direccin, que nos mostraba EBX, en mi caso EBX era 7ffda000 le sumo 68, ser 7ffda068.

Ese es el famoso NTGlobalFlag que es diferente de cero si hay un debugger y cero si no lo hay, pongamos a mano el flag este a cero, modificando ese valor a mano.

Lo pongo a cero

All esta localizado y puesto a mano a cero el NtGlobalFlag Ahora debemos localizar el otro byte el ProcessHeap Flag, ese tambin se localiza fcil. Al valor que me otorgaba EBX en el entry point en este caso le sumo 18, y nos da una direccin que es en mi caso 014000, que es la direccin del heap o sea una zona de memoria creada al arrancar el programa que guarda ciertos datos del mismo, no especificaremos mucho aqu sobre eso.

Vayamos a ver esa zona del heap

Marcamos los bytes y elegimos FOLLOW DWORD IN DUMP con lo cual nos llevara a la zona del heap

Y sumndole 10 a la direccin base del heap llegamos al dword que esta alli marcado, el cual esta a cero como si no hay debugger, debe ser por tanto plugin que tenemos, si abro el mismo crackme en un ollydbg sin ningn plugin.

Veo que all no esta a cero, que es el valor cuando hay debugger quiere decir que entre tanto plugin este byte se pone a cero, por alguno de ellos aun sin estar la tilde marcada. Por lo dems volvamos a poner las tildes en el HideOdb

Y reiniciemos el crackme de cruehead

Vemos que parados en el entrypoint tanto el flag de la api IsDebuggerPresent como el NtGlobalFlag estn a cero, y si busco el ProcessHeapFlag

Tambin esta a cero, quiere decir que verifique que el plugin funciona correctamente y que el OLLYDBG no ser descubierto por alguno de estos flags, y adems aprendimos a hallarlos y cambiarlos a mano. El ultimo truco antiolly que solo lo mocionare pues al parchear con el repair ya dimos cuenta de el y ambos plugins lo solucionan es el

Se refiere a un bug del OLLYDBG que cuando el programa enva una determinada string muy larga a esa api el OLLYDBG no la puede procesar y se cuelga, teniendo los plugins por supuesto esto no afecta en nada solo lo pongo aqu como dato ilustrativo aqu extractado del tutorial de Juan Jose de execryptor le copiamos la parte que explica esto.

Bueno como el tute esta genial, para que abundar, all esta clara la explicacin y los plugins dan cuenta de este bug del OLLYDBG perfectamente. Para practicar les dejo el crackme adjunto antisocial tiene todos los trucos que vimos en la parte de antidebugging , mas un par de trucos caseros jeje, el tema es hacerlo correr en OLLYDBG, si alguien hace un olly sin plugins ni nada en otra carpeta y lo hace correr a mano aplicando todo lo que vimos, pues se recibe de genio antidebugger a mano, por supuesto deber poner un poco de imaginacin pues tiene un truco que le impide correr mas que ser un truco antidebugger hay que reparar una lnea nopeandola, para que pase ese primer error, luego de eso tiene los antidebuggers que hemos visto, mas uno que no hemos visto y es el siguiente si al quitarle todas las tildes de DEBUGGING OPTION-EXCEPTIONS les para en un INT68 es un comando que provocara un error, el cual hay que nopear para que continu corriendo el programa, lamentablemente si ponemos todas las tildes al tratar de pasar esa excepcion nos dara error el OLLY y se terminara todo. O sea sepan que si les para en cualquier excepcin si no estn puestas las tildes, se debe apretar SHIFT mas F9 para pasarlas, eso lo veremos en la parte siguiente de excepciones, pero si la excepcin se genero en un INT68, solo se debe nopear ese comando y dar RUN con eso pasara bien. Bueno les dejo una dura diversin, si quieren pueden tratar de repararlo y hacerlo correr primero con los plugins con lo cual podrn ver el error y ver donde esta el INT68 y ver que el programa corre, y como segundo paso pueden abrirlo en un OLLYDBG sin plugins y tratar de evitar todo a mano, a ver si les sale, eso si ser duro, jeje Hasta la parte 24 Ricardo Narvaja

04 de enero de 2006

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 24


Me pidieron que antes de empezar con la parte que versa sobre excepciones, muestre como se hace correr en OLLYDBG el antisocial que deje como ejemplo, la vez anterior. Antes que nada sabemos que es un programa empacado, y eso aun no se ha enseado por lo cual lo haremos correr en OLLYDBG haciendo los cambios en la memoria solamente sin guardarlos, cuando ya sepamos desempacar pues podremos guardar los cambios definitivos. Primero lo haremos correr en un OLLYDBG renombrado con todos los plugins puestos para ver porque no corre y tratar de arreglarlo. Arrancamos el antisocial en mi OLLYDBG renombrado, parcheado y con todos los plugins habilitados.

Esto ya nos da una idea que puede estar empacado, llegamos el ENTRY POINT

All ya vemos algo extrao, pues POPAD es la sentencia que se usa para recuperar del stack, los valores que guardo previamente un PUSHAD, y aqu no hay ningn PUSHAD antes, por lo tanto hay algo sospechoso all. Lo corremos igual a ver que pasa

Para aqu

O sea da error cuando quiere hacer el PUSH como si el stack no tuviera permiso para escribir alli, pero el stack siempre tiene permiso de escritura que ocurri aqu, veamos el stack

O sea el valor superior del stack es 130000, y si reiniciamos el programa

Y vemos las secciones, vemos que el stack va en mi maquina desde 12c000 hasta 12ffff, el error fue que el stack se salio de esa seccin, y ahora apunta a la seccin siguiente que empieza en 130000 y que como no es el stack, no tiene permiso de escritura y da error. Lleguemos nuevamente a la zona del error

Vemos que el programa ejecuta otro popad y hace un salto JNZ al PUSH que da error veamos, pongamos un BPX en ese popad antes del error.

Ahora reiniciemos el programa y demos RUN para que pare all.

Veamos el stack

Esta aun en la seccin correcta ejecutemos el popad

All ya se salio de seccin, as que el problema se puede resolver nopeando este popad, pero lo correcto es que el popad inicial debe ser un pushad, que guarda los valores de los registros iniciales en el stack, y este popad es la sentencia opuesta los recupera, veamos que pasa si reemplazamos el popad inicial por un PUSHAD, reiniciemos. Apreto la barra espaciadora

Y escribo PUSHAD

Ahora doy RUN y para en el segundo POPAD

Pero esta vez el stack esta mas arriba

Por lo cual hacer un POPAD no lo sacara de seccin, veamos pasmoslo con F8

Vemos que se mantiene todo correcto

Llegamos al PUSH y al RET, traceando, y con f8 pasamos el RET

Bueno aqu hay un problema de anlisis

Ahora si se ve bien Veamos que ocurre si damos RUN

Veamos en el LOG del OLLYDBG si vemos algo ya que el programa se termina

Vemos que hay una excepcin, luego de parar en el BPX del popad Reiniciemos y repitamos los pasos para llegar nuevamente adonde estbamos.

Quitemos todas las tildes, menos la primera para que pare en las excepciones

Demos RUN

Para en la excepcin que vimos en el LOG

INT68 es una de las pocas excepciones que el OLLYDBG no puede manejar, podemos pasarla nopeandola.

Por otro lado sabemos que puede haber mas INT68 que molesten busquemos a ver si halla alguna mas, as lo nopeamos directamente.

Vemos que halla otro lo nopeamos

Buscamos nuevamente hay otro mas, lo nopeamos

Si hacemos CTRL + L continua buscando a partir del ultimo que hallo Ya no halla mas ahora si damos RUN

Como ven todo eso hay que hacer para que corra el OLLYDBG con los plugins, ahora tratemos de correrlo en un OLLYDBG sin plugins, y sin renombrar ni parchear.

All descomprim un OLLYDBG sin plugins, bah el nico que tiene es el command bar, ya que ese no protege de nada es solo por comodidad, a este OLLYDBG, le hice una carpeta diferente de plugins y el path a los plugins lo apunte all.

Como vemos all hay solo dos plugins, lo arranco en ese OLLYDBG

Repito las operaciones de cambiar el popad

Poner el BPX en el POPAD veamos si llega alli demos RUN

Lleguemos hasta el cdigo del programa desempacado.

Podemos nopearle los INT68 o quitar las tildes en exceptions y cada vez que pare si es un INT68 nopearlo y si no pasarlo con SHIFT +f9 como a cualquier excepcin.

Veamos que apis usa el programa para esto debemos recordar que la tilde en

Debe estar colocada alli para que muestre la informacin de la seccion en que estamos.

Bueno vemos que no hay apis de las sospechosas, pero usa muy pocas apis y esta alli GetProcAddress para cargar mas apis nuevas, asi que pongamos un BPX en la api GetProcAddress.

Demos RUN

No es sospechosa sigamos dando RUN hasta que pare en alguna sospechosa

Aqu vemos la primera sospechosa la api que nos hace la foto de todos los procesos que estn corriendo en nuestra maquina, lleguemos al RET y pongamos un BP EAX ya que en EAX estar la direccin de la api en nuestra maquina.

All esta el BP le pondr el comentario para saber que api es

Listo continuemos

Hmm otra parecida a la anterior por si acaso pongmosle un BP tambin

Demos RUN

Bueno esta es conocida BP en ella

Lo mismo

All para en la api que saca foto y como toda la proteccin depende de la foto, desde la cual de donde trabaja con la lista de procesos, threads, y no se cuantas cosas mas testea todo de la bendita foto, podemos intentar parchear esta api de la foto para que no devuelva el handle de la misma sino cero, para ellos vamos al ret de la api.

Vemos que alli hay un espacio vacio asi que podemos hacer EAX igual a cero antes de volver

Con eso devolver cero y el programa no tendr handle para poder manejar las fotos ni averiguar sobre ellas, esa es una posibilidad la otra cambiando en el codigo del programa llegamos al ret dela api la cual no modificamos.

Alli vemos un poco mas abajo unos saltos JNZ y justo abajo los call a TerminateProcess que cerrarian el OLLYDBG con la llamada anterior a OpenProcess para obtener el handle, y vemos que hay como cinco de estas partes justo una debajo de otra

Por supuesto cambiando todos los saltos JNZ por JMP, evitamos que el programa llegue a TerminateProcess evitamos y que cierre el OLLYDBG. Esta primera parte esta solucionada ahora sigamos con la segunda parte de la proteccin, demos RUN

Nopeamos y damos RUN y corre pero se cierra el programa, si le pongo solo el plugin HideDebugger 1.23f y lo protejo contra FindWindows/EnumWindows corre bien con los pasos anteriores que vimos. El tema del lugar de donde se cierra es aqu

Cuando corremos el programa cuando para alli en el call superior.

Vemos que en una de esas tantas comparaciones, que para alli.

La cuestin, es que aqu compara si hay cosas malas, jeje y que todo eso se evita con el jnz que esta a la salida del primer CALL si lo cambio por JMP

Ese es el salto clave si lo cambio por JMP

Evita el segundo call que si lo vemos dentro

Es el que te lleva a PostQuitMessage y va cerrando la ventana pues esta por terminar el programa lo cual lo hace mas adelante, pero aqu ya la decisin esta tomada, el PostQuitMessage es que se va a cerrar el loop de mensajes y no queda otra que el crackme se cierre ya que no tiene mas ventanas. Por supuesto si me dicen como halle ese JNZ pues es fcil. Una vez que paso la primera parte de la proteccin, pongo un BPX en PostQuitMessage.

Para en la api miro el stack a ver de donde fue llamado

Voy a 4532d7 ya que el stack me dice que fue llamado de alli

Por supuesto prob ese JE que esta antes del PostQuitMessage y no evitaba que se cierre al invertirlo, as que fui al segundo RETURN TO que encontr en el stack.

Este viene de 4532CC

Como vemos este call se evita con el JNZ anterior con lo cual no entra y no va a PostQuitMessage y al cambiarlo por JMP veo que corre perfecto sin ningn plugin. Adjunto el crackme desempacado que corre en cualquier OLLYDBG por supuesto ustedes aun no aprendieron a desempacar en este curso, por lo cual aun eso no se pide, pero si quieren verlo por curiosidad, all esta adjunto pueden probar que corre en cualquier OLLYDBG se llame como se llame y sin ningn plugin, ya que adems de desempacarlo, le hice los cambios permanentes que vimos en este tute y con eso quedo limbito como culito de bebe. Hasta la parte 25 ahora si empezamos con las excepciones Ricardo Narvaja 06 de enero de 2006

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 25 EXCEPCIONES


Veremos en esta parte 25 el manejo de excepciones, que suele ser un problema para los newbies, pero en si no es un tema difcil si leemos un poquito sobre el. Una excepcin se produce en un programa cuando el procesador ejecuta una operacin no valida, veamos algunos ejemplos en el mismo OLLYDBG, abramos el crackme de cruehead para escribir algunos ejemplos de excepcin.

All tenemos el crackme de cruehead 1, parado en el Entry Point y escribiremos en la primera lnea como hacamos cuando veamos la instrucciones de assembler, algunas instrucciones que al ejecutarlas nos producirn una excepcin. Usaremos algunas definiciones del tute de Mr Silver de excepciones y las graficaremos aqu con el ejemplo. Acceso a memoria no vlida: Se producen cuando un thread intenta acceder en un modo no permitido a una posicin de memoria a la cual no tiene acceso. Por ejemplo se puede producir este tipo de excepcin si el thread intenta escribir a una posicin de memoria de solo lectura. Escribo en el OLLYDBG la siguiente linea.

Esto lo vimos cuando explicamos la sentencia MOV, en este caso 401057 tiene solo permiso de lectura y ejecucin, pero no de escritura, por lo tanto al escribir en dicha posicin de memoria dar excepcion, apretemos f8.

Las secciones tienen permisos iniciales, que estn guardados en el header, hasta que el programa no los cambie mientras corre con alguna api como por ejemplo VirtualProtect que sirve para cambiar permisos en tiempo de ejecucin, tendr el permiso inicial. Donde podemos ver los permisos iniciales de cada seccin y modificarlos si queremos en el OLLYDBG? Vayamos a ver las secciones apretando el botn M

Vemos que la seccin que empieza en 400000 o sea la primera realmente es el PE HEADER, es una pequea seccin de 1000 bytes que guarda los datos de las secciones, nombres, largo, todo sobre el archivo para arrancarlo. Por supuesto el PEHEADER se puede editar con cuidado y siempre en una copia del archivo ya que si metemos mal la mano el programa no arrancara. Veamos en el dump el header

Ponemos 400000 ya que el header, ya vimos que comienza all.

Ahora el OLLYDBG tiene una opcin para interpretar mejor los parmetros del header, haciendo en el dump, click derecho.

Vemos que el OLLYDBG nos interpreta que es cada cosa

Si vamos bajando lo primero que hallamos es el offset a la PE SIGNATURE que es un valor que nos dice donde esta ubicada en el Header la informacin realmente, vemos que el puntero es 100, as que debemos sumarle los 400000 del inicio del header y nos dar 400100, bajemos hasta all.

Como vemos no estbamos equivocados, aqu empieza la info importante sobre el programa. Ya explicaremos mas detalladamente muchos de estos valores solo mencionemos al pasar

O sea ese puntero que es 1000 le sumamos los 400000 y tenemos el entry point del programa, si lo queremos cambiar, por ejemplo a 2000, hacemos click derecho

Y podemos escribir el valor que queramos por ejemplo si queremos que el programa empiece de 402000, escribiremos all 2000 ya que siempre hay que restarle la imagebase 400000 o sea donde realmente empieza el header que es la primera seccin del programa.

Luego para que quede definitivo guardado en el archivo, hacemos CLICK DERECHO-COPY TO EXECUTABLE y en la ventana que aparece CLICK DERECHO - SAVE FILE como guardamos los cambios normalmente, igual esto no lo haremos ahora solo quera mostrar otra posibilidad. Bueno sigamos bajando en el header

All empiezan los datos de las secciones vemos que la seccin que comenzara en la posicin de memoria 1000 o sea 401000, y su caractersticas son CODE, EXECUTE, READ. Si quisiramos que esta seccin tuviera permiso de escritura deberamos cambiar ese 60000020 por E0000020 que es el valor que deja la seccin con permiso para todo, jeje, probemos.

Ahora guardamos los cambios con el procedimiento usual

Le cambiare el nombre a CRACKME 3 para saber que este es el que modifique.

Ahora busquemos ese crackme 3 y abrmoselo en OLLYDBG

Volvamos a la visualizacin normal del dump Probemos ahora la instruccin que hicimos antes

Apretemos F8 Vemos que no se produjo excepcin y guardo el valor de EAX en el contenido de 401057 perfectamente. Otro tipo de excepcin es Divisin entre 0: Se produce cuando se intenta dividir un nmero con 0. Por ejemplo escribo en OLLYDBG

Eso dividira ECX por EAX, si EAX es cero se producir una excepcin.

Apreto f8

No siempre OLLYDBG aclara bien las excepciones, no me dice que fue una divisin por cero, pero salto la excepcin.

Instruccin no valida intento de ejecucin de instruccin privilegiada: Se produce cuando el procesador intenta ejecutar una instruccin que no pertenece a su juego de instrucciones, es decir al encontrar un cdigo de operacin desconocido Eso no lo podemos probar porque OLLYDBG no nos deja escribir instrucciones que no existen para el procesador, pero el programador puede haber deslizado alguna instruccin invlida que no corresponde al juego de instrucciones que el procesador puede interpretar y lgico dar error al no saber que hacer. La otra muy conocida es el INT 3 que provoca una excepcin y es usada por el debugger cuando ponemos un BPX comn para detener el programa y tomar el mando del mismo en el momento que se ejecuta el INT 3. Tambin algunos programas colocan INT 3 directamente escribiendo la sentencia, lo cual es una excepcin ms de todas las posibles.

Hay muchsimas excepciones por supuesto no veremos todas esto es un simple ejemplo. Ahora sabemos que en el programa se pueden producir excepciones, pero que ocurre cuando se genera una, veamos el siguiente esquema.

Aqu hay un grafico que le afanamos al tute de SILVER, all vemos que al producirse una excepcin, lo primero que ve el sistema es si el proceso esta siendo debuggeado. En el caso que este siendo debuggeado, toma el control el DEBUGGER O DEPURADOR el cual en la imagen vemos que vemos que puede controlar la excepcin o no, casi siempre CONTROLA LA EXCEPCION, y en el caso del OLLYDBG se fija si esta puesta la tilde en DEBUGGING OPTIONSEXCEPTIONS para saltear ese tipo de excepcin con lo cual si esta marcada, le devuelve el control al programa, de no estar la tilde espera que apretes SHIFT mas f9 para devolver el control al programa, o sea all en el grafico donde dice CONTROLA LA EXCEPCION-SI, falta que una vez que toma por ese camino decide parar o continuar segn haya tilde o no, y luego continua segn la imagen de abajo.

All vemos el trabajo completo, luego de CONTROLAR LA EXCEPCION decide si para o continua si esta la tilde o no, si para, espera que apretes SHIFT mas F9 para volver donde muestra la flecha roja que agregue, y si no para, vuelve adonde muestra la flecha roja directamente. All vemos que cuando retorna del OLLYDBG pregunta si tenemos SEH instalado, si tenemos va a el, y si no va al SEH genrico, expliquemos un poco esto que parece difcil pero no lo es. QUE ES EL SEH El SEH o Structured Exception Handling (Manejo Estructurado de Excepciones), es una manejador que se instala para poder recuperar a un programa de un error, ya que si no tenemos instalado un SEH propio, al encontrar un ERROR, se ejecuta el SEH GENERICO del sistema que en un 90% de los casos termina en el cartel que nos muestra que ha habido un error en la aplicacin y se debe cerrar el programa y chau. Con nuestro propio SEH, podemos interceptar un error, arreglarlo, y volver al programa y que contine corriendo sin que salga el molesto cartel del sistema y nos cierre la aplicacin. Tambin debemos decir que aunque aun no hemos visto que son los threads a fondo, una mnima definicin de threads es que son hilos del programa o partes que se pueden ejecutar simultneamente, hago esta definicin porque cada thread tiene su propio manejo de excepciones, si a un thread le colocas un manejador de excepciones solo funcionara en el thread que fue colocado y no en los otros. Como se coloca un Manejador de excepciones Bueno veamos el crackme de cruehead nuevamente en el stack vemos

Ese es el SEH GENERICO que instala el sistema, mientras no se instale uno propio, cualquier error ira directo a este manejador que nos lleva casi siempre, al fatdico cartelito de error, veamos la ubicacin de los punteros del SEH GENERICO. Como habamos visto que en FS :[0] estaba el puntero al manejador de excepciones que esta vigente, podemos ir en el dump all, tambin mirando en OLLYDBG

Como habamos visto Fs:[0] es el contenido de la direccin de memoria que me marca el OLLYDBG puede variar en cada maquina, pero en la ma es entonces FS: [0] es 12ffe0

Como vemos en el stack 12ffe0 apunta al final de la cadena de manejadores, o sea al manejador que se encuentra en funcionamiento en este thread actualmente, una posicin mas abajo esta la direccin donde

saltara al encontrar una excepcin, es este caso como es el manejador genrico saltara a una direccin del sistema que terminara mostrndonos el famoso cartelito de error.

Y si vamos a VIEW-SEH CHAIN

Vemos la direccin del manejador genrico que es el nico instalado, si hubiera aqu mas de uno, el que funciona al encontrar una excepcin es el superior de toda la lista. Ya que el crackme de cruehead no instala manejadores de excepcin propios, utilizaremos un programita llamado SMARTMOUSE que adjunto al tutorial. Lo arranco en OLLYDBG

Ali noms veo que al inicio el programa va a instalar su manejador de excepciones propio, OLLYDBG nos lo indica en el comentario. Como se hace esto traceemos y expliqumoslo paso a paso.

Llegamos traceando a la instruccin que el OLLYDBG nos indica que empieza la instalacin del manejador de excepciones, lo primero es hacer un PUSH con la direccin a la cual queremos que salte el programa, cuando halle una excepcin, en este caso, ser 4066d8, ejecutamos el push.

All coloco la direccin en el stack

La siguiente lnea mueve el valor actual de fs : [0] a EAX vayamos a ver cuanto vale Fs [0] en el dump

Vamos all

All vemos que fs: [0] vale 12ffe0, podemos ver que el olly nos lo aclara tambin

Ahora ejecutamos esta lnea

Movi a EAX ese valor Ahora hace un PUSH con ese valor

Vemos porque se le dice SEH CHAIN que significa cadena ya que este valor que guardo, apunta al manejador anterior que por ahora esta activo.

La ultima lnea cambia fs:[0], le coloca el valor de ESP o sea apunta a donde esta ubicada esta estructura nueva que escribimos

Al ejecutar la lnea

Tenemos nuestro manejador instalado en 12ffb0, como siempre vemos que fs:[0] queda apuntando al manejador actual

El cual OLLYDBG nos indica que es un SEH, el primer valor apunta al viejo SEH, y el segundo valor es la direccin que cuando halle una excepcin el programa saltara a tratar de arreglar las cosas.

O sea que cuando ocurra una excepcin en este ejemplo

El sistema le dar control al debugger el cual parara o no segn este la tilde de ese tipo de excepcin marcada, y volver al programa, directamente o apretando SHIFT +f9, adonde muestra el dibujo y como ahora tenemos SEH instalado, pues continuara en 4066d8. Si vemos el men SEH CHAIN ahora

Vemos que quedo como manejador activo el que instalamos y el genrico quedo debajo sin funcionar. Forcemos una excepcin en el programa

Veamos all, cambiemos esa lnea por

Lo cual dar error pues no se puede escribir en la direccin 0. Quitemos todas las tildes en debugging option-exceptions, salvo la 1ra.

Demos RUN

Para en el error mostrando

Entonces segn lo que vimos el programa debera ahora continuar ejecutndose en el manejador para tratar de recuperar el error. El manejador estaba en 4066d8 vayamos all y pongamos un BP,

Como vemos OLLYDBG siempre nos aclara todo jeje, apretemos SHIFT + f9 para pasar la excepcin

Como vemos paro en el manejador, veremos que hace el mismo y si es capaz de recuperarse de un error tan grave ya que altere el cdigo del programa para generarlo.

Vemos que no pudo continuar y salto al manejador genrico

Ocurri este caso como el error es muy grave no lo pudo recuperar y salto al manejador genrico que saco el cartel fatdico y cierra el programa. Obviamente el manejador de excepciones esta diseado para otro tipo de excepciones las cuales espera, no esta que es una alteracin del cdigo lisa y llana, pero vemos igual como funciona en el caso de no controlar la excepcin. Para ver la otra rama del grafico que es cuando un manejador controla las excepciones en forma exitosa, veamos este crackme SDUE que adjunto. Lo arranco en OLLYDBG y veo que esta empacado por el mensaje del OLLYDBG de puede ser automodificable etc etc.

Quito todas las marcas en debugging options- exceptions, menos la 1ra

Y doy RUN

Vemos que para en una excepcin veamos

Donde se encuentra el manejador

En sus maquinas esta direccin puede variar ya que es una seccin creada mientras se ejecuta el programa. Pongamos un BP alli

Pongamos UN BPX alli

Apretemos SHIFT mas f9

Para en el manejador, el cual debe retornar si no hace cambios raros a la lnea siguiente de donde se provoco la excepcin para continuar el programa.

Pongo UN BP en la lnea siguiente donde se genero al excepcin y doy RUN

Vemos que para y el error fue salvado y el programa continuara su ejecucin perfectamente sin cartel de error. Como yo vi que era una rutina simple, y no hay modificaciones asumo que retornara a la lnea siguiente de donde se provoco la excepcin, este es el comportamiento normal, aunque la direccin de retorno puede ser modificada en el mismo manejador, en ese caso lo mejor es poner un BPM ON ACCESS en la seccin donde se provoco la excepcin e ir apretando F9, lo cual nos har saltar lnea a lnea, hasta que termine la rutina del manejador y vuelva al programa, all quitamos el BPM ON ACCESS y continuamos ejecutando y vemos claramente donde retorno. Por supuesto si queremos parar en el momento que el programa coloca el manejador de excepciones lo mejor es poner un HARDWARE BPX ON WRITE en Fs:[0] aunque para muchsimas veces ya que las dll tambin colocan manejadores luego los quitan y al volver al programa dejan el que estaba activo antes, pero es una forma de ver como se van colocando y quitando manejadores a medida que corre el programa. La otra forma de colocar un manejador de excepcin es por medio de la api SetUnhandledExceptionFilter, la cual ya vimos su funcionamiento, el parmetro es la direccin del manejador donde continuara la excepcin siempre y cuando no haya debugger como vimos anteriormente. Bueno creo que es un primer pantallazo sobre excepciones que nos permitir ir manejndonos con mas profundidad en el cracking, a medida que veamos ejemplos profundizaremos el tema para no ser tediosos. Hasta la parte 26 Ricardo Narvaja 08 de enero de 2006

INTRODUCCION AL CRACKING EN OLLYDBG PARTE 26 CRACKEANDO VISUAL BASIC EN OLLYDBG


En las subsiguientes partes aprenderemos a crackear programas hechos en VISUAL BASIC en OLLYDBG, ya se me dirn algunos que para que existe una herramienta tan buena como SMARTCHECK, pero aqu este curso trata sobre cracking en OLLYDBG y trataremos siempre de utilizarlo al mismo antes de otras herramientas, en caso de que no podamos de ninguna forma con OLLYDBG o que se nos complique mucho, solo en ese caso, recurriremos a otras TOOLS. Antes que nada les har un regalito es este OLLYDBG ya conocido en la lista crackslatinos y es especial. http://www.ricnar456.dyndns.org/HERRAMIENTAS/L-M-N--OP/OLLY%20PARCHEADO%20PARA%20BUSCAR%20OEPs.rar Se llama OLLYDBG PARCHEADO PARA BUSCAR OEPs, que como vemos se utiliza mas que nada para desempacar, pero en Crackslatinos yo lo dije cuando lo envi, tambin es muy til, para los programas en VISUAL BASIC en NATIVE code, no as para los hechos en P-CODE. Pues cuales la diferencia entre ambos, ya veremos tambin captulos de P-CODE pero el VISUAL BASIC NATIVE CODE es el visual comn que ejecuta instrucciones en la seccin code del programa, mientras que el P-CODE no ejecuta la seccin code, solo se ejecuta la dll de visual y lee bytes del la seccin code del programa como indicacin de que comando quers ejecutar. O sea si un programa de VisualBasic nunca vuelve a ejecutar lneas de cdigo en la seccin code, pues es casi seguro que es P-CODE del cual estudiaremos su forma de trabajar mas adelante. Pues que particularidad tiene el OLLY este que parchee?, que si colocas un BPM ON ACCESS no para ON READ y ON EXECUTE, sino que para solo ON EXECUTE y esto es muy til para hallar OEPs y para Visual Basic ya que si no el programa para miles de veces en la dll de Visual, y el tema es aqu siempre volver al cdigo del programa, no empantanarnos traceando en las dll de VisualBasic lo cual te lleva a error seguro y a trabajar de mas. Tambin para trabajar en Visual Basic es necesario conocer las apis de VB, las cuales son diferentes a las apis comunes y no se encuentran en el WINAPIS32. Por lo dems hay muchsimos tutes con Puntos especiales para VB, y tcnicas geniales que no usaremos y el que quiere consultarlas, puede ver al el NUEVO CURSO de Crackslatinos los tutes de COCO y otros integrantes de la lista que pueden hacer mas fcil la tarea, aqu lo haremos como si no conocemos ninguna de esas tcnicas y lo tenemos que crackear solo con este OLLY especial. El mismo se coloca en la misma carpeta del OLLYDBG comn, y lgicamente elegiremos usar este OLLY solo cuando crackeemos VB o cuando busquemos OEPs o alguna tarea que requiera que los BPM ON ACCESS funcionen realmente como BPM ON EXECUTION solamente. Por supuesto si estamos crackeando con este OLLY, si necesitamos un BPM ON ACCESS real que pare ON READ y ON EXECUTE no podremos usarlo, o debemos arreglarnos con los HARDWARE BPX ON ACCESS que pueden a veces cumplir la funcin. El problema mximo que hay con las apis de Visual Basic es que no es una informacin que Microsoft suministro ni suministra, por lo cual no hay un winapis32 con apis de VisualBasic ni nada de eso, lo mas que podes hacer es buscar el nombre de la api en GOOGLE y ver si tenes suerte de encontrar alguna pagina donde se use y explique como y para que sirve, antes de comenzar a crackear recopilare en este tute lo poco que encontr sobre apis y info. en general sobre visual Basic, cosa de que tambin puedan consultar este tute para saber algunas apis que significan.

SIGNIFICADO DE LAS PARTES DEL NOMBRE DE UNA API DE VISUAL En las apis encontraremos estas abreviaturas como parte del nombre de las mismas. bool str i2 ui2 i4 r4 r8 cy var fp cmp comp Boolean String Integer (2 bytes) Unsigned integer (2 bytes unsigned integer) Long (4 bytes integer) Single (4 bytes real) Double (8 bytes real) Currency Variant or variable Floating point compare compare

Aqu en esta la tabla se ven las definiciones de los tipos de variables, pues combinando los tipos de variables se entiende mucho sobre que hace cada api.

Por ejemplo: __vbaI2Str quiere decir que convierte una string en un entero, por ejemplo. Aqu hay ms definiciones: 1) Ejemplos de apis de conversin de datos: i) ii) iii) iv) v) vi) __vbaI2Str Convierte una String a Integer __vbaI4Str Convierte una String a Long __vbar4Str Convierte una String a Single __vbar8Str Convierte una String a Double VarCyFromStr Convierte String a Currency VarBstrFromI2 Convierte Integer a String

Vemos que con las abreviaturas que vimos al inicio nos damos cuenta por donde vienen los tiros, aqu hay mas apis.

2) Moviendo datos i) ii) iii) __vbaStrCopy - Copia una String a memoria __vbaVarCopy - Copia una Variable a memoria __vbaVarMove Mueve una Variable en la memoria

3) Mathematical i) ii) iii) iv) v) __vbavaradd Suma de dos Variables __vbavarsub Resta dos Variables __vbavarmul Multiplica dos Variables __vbavaridiv - Divide dos variables dando como resultado un Integer __vbavarxor function XOR

4) Miscelaneas: i) ii) iii) iv) v) vi) vii) viii) ix) x) xi) xii) xiii) xiv) xv) xvi) xvii) xviii) xix) __vbavarfornext - Loop __vbafreestr Libera una String que no se utiliza __vbafreeobj Libera un Objeto que no se utiliza __vbastrvarval Toma el valor de una ubicacin especifica en una String multibytetowidechar Cambia una String a formato ancho rtcMsgBox Muestra un message box similar a Windows API messagebox/a/exa __vbavarcat Une dos variables __vbafreevar Libera una Variable que no se utiliza __vbaobjset Activa un Objeto __vbaLenBstr Obtiene el largo de una string rtcInputBox Muestra una Input Box de Visual Basic similar a Windows API getwindowtext/a, GetDlgItemtext/a __vbaNew Muestra una caja de dialogo Similar a Windows API Dialogbox __vbaNew2 - Muestra una caja de dialogo Similar a Windows API Dialogboxparam/a rtcTrimBstr Recorta una String __vbaEnd Finalizacion del Programa __vbaLenVar - Obtiene el largo de una variable rtcMidCharVar Toma un determinado carcter de una string para trabajar con el. _rtcDir Busca si existe una fila. __vbaFileOpen Abre una fila.

5) Comparaciones: i) ii) iii) iv) v) __vbastrcomp Compara dos Strins - Similar a Windows API lstrcmp __vbastrcmp - Compara dos strings - Similar a Windows API lstrcmp __vbavartsteq - Compara dos variables si son iguales __vbaFpCmpCy - Compara Floating point con Currency __vbavartstNe - Compara dos variables si no son iguales

Estas definiciones son para dar una idea de que esta haciendo el programa en ese momento, ya que no tenemos mucha ayuda, quizs no sean perfectas, pero nos ayudaran, asimismo hay muchas mas combinando lo que vimos nos daremos cuenta que hace la api. Asimismo aunque por ahora no veremos cracking en SMART CHECK en esta pagina tiene lo que quieren decir los comandos extraos para el cracker que vemos en el. http://www.w3schools.com/vbscript/vbscript_ref_functions.asp Por ejemplo el Smartcheck nos muestra la funcin ASC, o MID que no corresponde a lo que vemos en OLLYDBG si no al lenguaje de Visual Basic de programacin, pero en esa pgina esta detallado que

significa cada posible comando y sus parmetros por lo cual el cracking en SMART CHECK se facilita mucho. Por ejemplo en SMART CHECK vemos el comando LEN que corresponde a la api __vbaLenVar,

En la pagina vemos que esta la definicin de LEN.

Pues para los que tienen problemas para usar el SMART CHECK eso los ayudara, aunque en este tute no veremos su uso, creo que ningn tute de SMART CHECK da una ayuda sobre ciertas expresiones usadas por el mismo, creo que eso servir, por eso lo agregue aqu. Bueno ya sabido todo lo anterior encaremos el cracking del CrackMePls Abramos el mismo en el OLLYDBG parcheado por mi, que les di el link al inicio.

Este crackme es muy sencillo tiene una nag que eliminar y el serial que hallar, veamos, demos RUN.

Sale la nag, la cual varia de texto cada vez que la corremos, es tipo MessageBoxA, as que en VisualBasic eso corresponde a la api rtcMsgBox, si pongo un BP en dicha api.

Y reinicio a ver si para antes de que salga la nag

All paro, no tenemos ayuda de parmetros ni nada, pero no importa. Veamos de donde fue llamada esta api como siempre aunque no diga RETURN TO el primer valor del stack es la direccin de retorno de la api, si no, lo analizamos aqu nuevamente y aparece la info.

Vayamos a ver de donde fue llamada esta api.

All esta el call a la api y abajo lgico el punto de retorno que es 4032d9.

Pongo un BP en el punto de retorno de la api, y doy RUN

Acepto y para en el retorno.

EAX =1 significa que la api se ejecuto con xito, ahora reiniciemos, intentaremos nopear la nag de alguna forma. Reiniciamos y para en el call

Si hago en la lnea de retorno CLICK DERECHO -NEW ORIGIN HERE continuara ejecutndose desde alli, sin salir el cartel, es como una simulacin de que ocurrira si nopeo el call.

All esta demos Run a ver que pasa

Evidentemente la solucin de nopear el call a la api no funciona, probemos otra, reiniciemos.

Lleguemos hasta 4032d9, y sigamos traceando con f8

Llego al JMP y sigo traceando con F8

Antes del JMP hizo un PUSH 403341 y salta a un RET quiere decir que esta usando el RET como un salto a 403341, all ollydbg lo aclara RET USED AS A JUMP TO 403341, por eso no aparece en el stack, jeje este truquito es para evitar que nos fijemos en el stack hacia abajo los retornos de los calls y lleguemos a la zona de 403341 mirando solamente el stack, este truco previene eso, sigamos traceando.

Llegamos hasta el RETN 8

All esta acabamos de salir del call que esta en 402f95 pero eso no estaba en el stack gracias al truquito que uso para disimular este CALL y no mostrar la direccin de retorno. Pongamos un BP en este call y reiniciemos

Nopeemos el call a ver si corre sin la nag

Demos RUN

Bye bye nag, jeje ya veremos mas adelante muchos ejemplos de remover nags, pero bueno este es sencillo salvo ese pequeo truco, la cuestin es ir saliendo desde la nag hacia los retornos de los calls, para ver si se puede nopear alguno de los calls anteriores, para evitar la aparicin de la misma. All tenemos el crackme tipeemos el serial bueno y dejmoslo RUNNING.

Ahora veremos el uso que le damos al OLLY este parcheado, lo mejor es intentar poner un BPM ON ACCESS (execute) en la seccin code, vayamos a M.

Recordemos que en este OLLY eso es un BPM ON EXECUTION, no para cuando lee y escribe en la seccin ejecutando la dll de visual y eso es lo que necesitamos, volver rpido al programa y evitar las miles de veces que para ON READ antes de volver. Apreto OK

Paramos aqu traceemos un poco

Llegamos a ese call recordamos pasar por encima los calls a apis, y entrar en los calls internos del programa. Entonces entramos con F7

Llegamos a la posible parte caliente abajo vemos __vbaStrCmp que es una posible comparacin de strings, pongamos un BP all y quitemos el BPM antes de dar RUN.

Vemos que compara la string que ingrese 989898 con el serial correcto, copimoslo.

Y pegumoslo en el bloc de notas

De all lo podemos copiar al serial correcto fcilmente

Probmoslo pegndolo en la ventana del crackme

Bueno resuelto, por supuesto hay que guardar los cambios del nopeo de la nag para que corra para siempre sin la misma. En la parte 27 seguiremos profundizando el cracking en Visual Basic, con ejemplos mas complejos y ya empezaran a trabajar ustedes tambien. Hasta la parte 27 Ricardo Narvaja 10 de enero de 2006

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 27 Seguimos con Visual Basic


Bueno seguiremos con Visual Basic aqu tenemos un crackme en el que hay que quitar una nag, yo lo hice a mi modo, que me sirve para cualquier caso (me gusta razonar e intentar), y quite la nag a mi forma, por supuesto use el OLLYDBG especial para VB que vimos en la parte anterior, luego de ver como lo solucione, veremos el mtodo mecnico que ahorra tiempo, pero yo pienso que hay que saber solucionar o por lo menos intentar usando los mtodos de intentar y probar, lo que uno aprende intentando es muy importante, de all que hago este tute con mi forma de quitar la nag, al final les mostrar el mtodo mecnico tambin porque hay que saber y usar de todo. Killme es el adjunto que tiene el crackme que vamos a estudiar, en este no hay serial solo una nag molesta que hay que evitar que aparezca y que corra el programa que viene a continuacin. Si lo corro fuera de OLLYDBG veo la nag

Veo que tiene un botn deshabilitado y un timer que va desde cinco disminuyendo hasta cero y cuando llega a cero, se habilita el botn CONTINUE y al apretarlo.

Aparece la supuesta aplicacin, que debe correr directamente sin aparecer ninguna nag, iremos estudiando de a poco como funciona el crackme, todo con OLLYDBG. La primera tentacin en cualquier programa con NAG es ver los JMPS que dirigen a diferentes partes del programa.

Arranco el programa y apreto F9

Ah paso el tiempo y apareci habilitado el botn CONTINUE. Sabemos que al cerrar la nag, pasara por un JMP en la seccin code, por lo cual pongo un BPM ON ACCESS en dicha seccin (que ser en realidad ON EXECUTION) y apreto el botn Continue.

Para aqu

O sea que la parte del programa se comienza a ejecutar en 40d090 ya que all vemos el salto JMP 40d090, a donde se inicia dicha parte, y vemos los restantes JMPS a las diferentes partes del programa, pongamos BP en todos estos JMPS para ver cuando para y en que caso.

Reiniciemos el programa

Vemos que antes de salir la nag para aqu, una buena tentacin es cambiar el JMP por JMP 40d090 as salta al programa directamente, pero da error y no arranca, as que demos RUN de nuevo.

Vemos que para en el siguiente JMP y si doy RUN de nuevo.

Tarda unos segundos y vuelve a parar y as 5 veces lo cual me dice que esa rutina tiene que ver con el temporizador, ya que para cada paso que el mismo disminuye. Veamos que hay en dicha rutina traceemos en ella.

Nada lindo sigamos traceando con f8 Llego a algunos saltos condicionales, puedo probar que pasa si los invierto a ver si termina el temporizador y se habilita el botn, mirando un poco e intentando veo que el que sirve es este

Es una comparacin en punto flotante, que si no se que es por ahora, pues probando invertir los diferentes saltos de la rutina que son pocos, me dar cuenta.

Veo que las primeras veces que pasa por all salta y la ltima vez no salta, calculo que es la comparacin de si el temporizador termino de contar y llego a 0, invirtamos nopeandolo a ver que pasa.

Lo nopeo para que no salte Y doy RUN

Veo que acert pues aun siendo la segunda vez que paso por dicha rutina, al invertir el salto termino la cuenta del temporizador y habilito el botn CONTINUE, as que por ah viene la cosa, Ahora si ya forzamos a que el botn se habilite que ocurrir si al retornar de esa rutina, obligamos a saltar al inicio del programa, pues ya esta todo inicializado y solo falta apretar el botn, nada mas. Reiniciemos el programa Vayamos a la lnea que nopeamos antes de ejecutar nada

y quitemos todos los BP y pongamos uno all, demos RUN

All paro traceemos a ver cuando la rutina termina y vuelve a la dll de visual Basic

Vemos que llega al RETN pero no sale a la dll de visual sino que sigue a 40d714 Sigamos traceando

All si llega al RETN que vemos en la aclaracin que volver al dll de visual, aqu ya esta todo inicializado para arrancar el programa, as que puedo intentar cambiar ese RETN 4 por un salto al inicio del programa veamos.

Salto all que hay mas lugar para escribir y luego salto a 40d090 que era el inicio del programa.

Probemos si arranca demos RUN

Ahora podemos guardar los cambios, el nop inicial y estos dos saltos

Hago click derecho COPY TO EXECUTABLE ALL MODIFICATIONS y guardara todo lo que cambie.

Apreto COPY ALL

Ahora click derecho SAVE FILE

Bueno ya estoy mas cerca, ahora arranca la nag queda unos segundos y sola desaparece, as que pongo nuevamente los BPX en los JMPS

Doy RUN

Veo que el primero que para es el que crea la nag el de 404b7a, y recuerdo que luego de pasar unos segundos de que sale la nag, para en el de 404b87 y de alli, ya arranca el programa directo gracias a que lo parchee, as que cambio el salto que crea la nag, por el que maneja de la rutina parcheada y va al inicio del programa.

Nopeando el salto que crea la nag, va directo al otro que maneja el timer y arranca el programa, veamos probemos con f9.

Guardemos los cambios y probemoslo

All corre limpio y ni se ve la nag, quedo limpio como culo de bebe, jeje.y a mano je. El mtodo del 4c es un mtodo mecnico, muy til para hacerlo rpido y sencillo y se basa en conocer como esta compuesto un archivo en VISUAL BASIC. Lo usaremos vemos el entry point

Vemos que los programas en VB empiezan por un PUSH y un CALL (si no encontramos esta estructura, pues el exe ha sido modificado, pues necesitamos encontrar el PUSH y anotar la direccin que esta enviando al stack, en este caso 40436C.

Que como vemos es el header de Visual Basic A esa direccin hay que sumarle 4C o sea 40436c + 4c

Es 4043b8

All esta, ahora buscamos la direccin que encontramos all en 4043b8 que es 4044c0

Busquemos dicha direccion en el dump

Vemos entradas de 50 hexa de largo, cada una corresponde a un FORM, en cada una de esas partes el byte 24 nos muestra el orden que tienen las forms para aparecer, veamos 40440c +24=404430

All esta el 00 significa que esa form es la primera que aparecer y el 01 significa que es la segunda que aparecer, as que podemos alterar el orden.

Ah esta ahora lo primero que aparecer ser el programa jeje y la nag segundo o nunca ya que al cerrar el programa ya se cierra y no sale una segunda form.

Listo solucionado con el mtodo 4c, ya saben las dos formas, por supuesto esta segunda es mas sencilla y rpida, pero es bueno siempre razonar y pelear un programa, por eso les mostr ambos mtodos ya que no siempre habr un mtodo automtico para cada caso y siempre estaremos nosotros razonando e intentado delante del programa. Les dejare una tarea all adjuntos hay dos crackmes uno sencillo y uno mas difcil, practiquen a ver que pueden hacer con ellos si pueden hallar los seriales, quitar las nags etc, en la prxima parte los solucionaremos Hasta la parte 28 Ricardo Narvaja 17 de enero de 2006

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 28 Mas tcnicas para Visual Basic (la guerra total)
Personalmente he escuchado muchos crackers que dicen que hacer tal o cual mtodo no es cracking puro, o cracking elegante, o no queda bien, o cosas por el estilo, pues para mi el cracking elegante es el que funciona, y vale todo, es como una guerra y le puedo asegurar que los programadores y sobretodo los packers y protectores no se detienen en pensar que es elegante o no, usan los mtodos mas guarros que pueden, sin pensar que puede afectar nuestras mquinas, ya veremos ejemplos de guarradas cometidas por packers en su desesperado intento de que no se pueda desempacar su programa protegido. Por lo tanto creo que si el enemigo usa misiles, limitarme yo a pelear con un revolver es una clara desventaja, por lo tanto yo uso CUALQUIER METODO lo aclaro desde ya, el que no le guste alguno, pues que busque alguno aprobado por la ACE (Asociacin de Crackers Elegantes, jeje), yo no me detengo en pavadas, si funciona bien, no perjudica otros programas, es correcto y sirve. Aclarado el punto vamos a ver el crackme que deje de la semana pasada, que ser objeto de estudio para este mtodo, me refiero al

Pues el otro que deje, con el mtodo del 4c se puede quitar la nag perfectamente y la parte del serial esta hecha en PCODE por lo cual lo dejaremos para cuando lleguemos a esa instancia. En este crackme hallar el serial es una pavada, el tema pasa por esa ventana, que no se si es nag o no, pero yo la quiero sacar, el que aplico el mtodo del 4c habr visto que hay dos forms, y que no hay forma de evitar que aparezcan ambas juntas usando ese mtodo. Antes que nada veamos el serial es muy simple.

Llego a la ventana del crackme y tipeo mi serial falso

Utilizo antes que nada la api mas usada de comparacin __vbaStrCmp

Pongo un BP en ella a ver si encuentro la comparacin del serial bueno con el serial malo. Como para muchsimas veces y tengo fiaca de apretar tantas veces f9, ver si puedo interceptar el cartel de error y de all llegar a la comparacin que debe estar por all cerca, quito el BP en la comparacin y pongo uno en el cartel Bp rtcMsgBox

All para cuando va a mostrar el cartel de que no acert el serial, veamos de donde es llamado este call en la primera lnea del stack, que es la direccin de retorno de esta api.

Vayamos all

All esta donde retornara de la api justo antes, esta el call a la api y veamos subiendo si hay alguna comparacin.

Un poco antes veo esta, pongamos un BP a ver si es la correcta, apreto f9

All veo que compara mi serial falso con otro numero, en mi caso es 4887649, veamos si es el serial correcto quito todos los BPs y llego de nuevo a la ventana de ingresar serial.

Ah esta era el serial correcto, el keygen lo dejamos para mas adelante. Lo primero para quitar la nag, es habilitar la posibilidad de modificar el crackme, o sea darle permiso de escritura a la seccin code del mismo para eso vamos al header que comienza en 400000.

Y lo cambiamos a modo PE HEADER

Bajamos hasta que comienza la PE SIGNATURE en el header, ah bajo hasta que veo la primera seccin.

All vemos las caractersticas, sabemos que si cambiamos a E0000020 podremos escribir en dicha seccin.

Bueno ahora guardamos los cambios.

Lo guardo como CrackmeA.exe

Bueno abro el CrackmeA en el parcheado 5 que es el OLLYDBG modificado para OEPs y VISUAL BASIC. Pongo un BPM ON ACCESS (que sera on execution) en la seccion CODE.

Demos RUN varias veces para aqu.

Seguimos hasta que paremos en los conocidos JMPS que nos desvan a las diferentes parte del programa.

Vemos que la primera vez, para en el primer JMP, y salta a 40bd80, o sea que all se ejecuta la primera parte del programa, veamos si aparece la nag, antes de volver a los saltos, quitamos el BPM ON ACCESS ya que ahora ejecuta una larga parte en la seccin code y si no nos volver loco parando en cada lnea, lo que hacemos es poner BPs en los distintos saltos a las diferentes partes del programa.

Veamos si sale la nag o si vuelve a otro JMP antes, demos RUN

Ahora para en el ltimo salto que va a 40c470, sin haber aparecido la nag. Demos RUN nuevamente

All apareci la nag quiere decir que esta parte que se esta ejecutando que empez en 40c470 es la responsable de la nag, apretemos el botn register.

Al volver de la nag para en el segundo JMP que supuestamente ya ira al inicio del programa, as que podemos probar que ocurre si al JMP anterior que hace salir la nag lo desviamos a 40bdf0, que ocurre, salteara la nag?.

All esta cambie el segundo salto que es el que va a la parte que hace aparecer la nag, por el tercero que debera arrancar el programa guardemos los cambios y veamos que pasa. Corramos el CrackmeA ya modificado fuera de OLLY

Vemos que nuestra modificacin mejoro algo el problema, pero aun no esta terminado o sea, no sale la nag inicial que tenes que apretar el botn register para que aparezca la ventana para ingresar el serial falso, si no que aparecen las dos juntas, adelante la nag, tapando la otra, eso es un gran paso, porque si antes hacamos a la nag invisible, la otra no aparecera al no haber apretado el botn register, ahora al menos solo nos queda hacer invisible la nag pues la otra ya apareci debajo y quedara sola, visible y funcional, al anular la que la tapa. Haciendo intentos con los dems JMPs no mejora la cosa, as que no queda otra que injertar. Ahora completemos la batalla, muchos crackers dicen que no corresponde modificar la dll de visual, eso poda ser cierto cuando hablamos de la que se encuentra en system32 y es usada por todos los programas, de forma que si la modificamos, puede afectar a otros programas, pero nosotros no haremos eso, si no que la copiaremos a la carpeta del crackme, de forma que esa solo ser usada por el mismo, ser una dll especial para el, los restantes programas de mi maquina continuaran usando, la que se encuentra en system32 por supuesto, o si tienen alguna en su propia carpeta pues usaran antes esa. La cuestin que copiamos la dll de visual que se llama.

A la carpeta del programa

All esta jusnto al CrackmeA, esto puedo realizarlo porque la dll de visual no es una dll de sistema, en el caso que sea una dll de sistema, necesitare cambiar algunas cosas del programa para que acepte una dll en su carpeta. O sea que cualquier programa que usa una cierta dll que no sea de sistema, primero busca en su carpeta y si no la halla, la busca en system32, en este caso al haber una en su propia carpeta usa esa, lo cual es muy bueno para nosotros jeje ya que nos permite modificarla sin que afecte a otros programas. Arranquemos el CrackmeA nuevamente en OLLYDBG, en este caso usamos un OLLYDBG comn ya que para escribir injertos o lneas de cdigo a veces los parcheados fallan.

Verifiquemos en el botn E si esta usando la dll de su carpeta en vez de la de system32.

All vemos que cargo la de la carpeta del crackme, en vez de la de system32 todos los cambios que hagamos en esta dll, solo afectaran al crackme y a ningn programa ms de VB. Bueno ya tenemos la dll de visual ahora lo que nos falta es que podamos escribir en la seccin code de la misma, o sea que tenga permiso de escritura, eso lo hacemos de la siguiente manera. Abrimos un OLLYDBG y vamos al men OPEN

Vemos que viene predeterminado para abrir exes, pero tambin puede abrir dlls, si abrimos el men desplegable elegimos

Dynamic link library (*.dll) con lo cual podremos abrir la dll de Visual.

All esta parado en su Entry Point. Bueno ahora debemos buscar el header que en este caso no estar ubicado en 400000 como normalmente, miremos la imagebase del archivo que es donde se inicia, apretando el botn E.

All en la columna base encontramos la imagebase de la dll que es 66000000 en mi caso, en sus maquinas puede variar. Vayamos en el dump a ver el header

Y cambiemos al modo Special- PE HEADER repitiendo el procedimiento que hicimos en el crackme, bajamos buscando la seccin CODE.

All cambiamos a E0000020 para que tenga permiso de escritura.

Ahora guardamos los cambios como sabemos.

Aqu no le cambiamos el nombre lo guardamos con el mismo nombre si no el crackme no lo cargara

Una vez que ya tenemos ambos el crackme y la dll con posibilidad de escribir en ellos, antes de realizar el injerto, mostrare cual es la idea de lo que tenemos que hacer para que no aparezca la nag. Abramos en OLLYDBG el crackme que ya tenamos parcheado, para que aparezca la nag encima de la ventana del serial, y pongamos un BP en la api de creacin de ventanas Bp CreateWindowExA

Ahora arranco el crackme

Parara varias veces cuando va creando las diferentes ventanas y botones que tiene el crackme, lleguemos hasta cuando crea la nag.

Aqu esta la localizamos fcilmente por el nombre, all en WindowName dice el titulo de la nag recordemos que era este

Bueno all se esta creando la nag, si cambio el style o estilo del mismo, veamos que pasa intentando algunos valores veo que si pongo 40000000

Cambia el estilo a WS CHILD ustedes pueden experimentar poniendo diferentes valores, a ver que pasa, ahora quito todos los BP y doy RUN.

Vemos que sale sola la ventana de registro y la nag no aparece, el tema que injertar en VB es complejo si no cambias la dll, pero si podemos hacerlo y no afectamos ningn otro programa, porque vamos a boxear con las manos atadas, jeje. Bueno repitamos el procedimiento, hasta parar cuando crea la ventana en la api a injertar CreateWindowExA

Vemos que la api es llamada desde la dll de Visual Basic, que mejor que injertar all, veamos de donde viene llamada, la primera lnea del stack nos indica de donde se llamo a la api, vayamos all.

Pongamos un BP alli y quitemos el de la api. Ahora veamos cuando para, reiniciemos y demos RUN

All paro y vemos en el stack

Vemos que la primera vez que para es cuando crea la nag, ya que las veces anteriores que paro en la api, fue llamado desde otras direcciones no de aqu. Lamentablemente no es la nica vez que pasa por aqu, cuando crea la ventana de registro tambin lo hace desde aqu, as que debemos ser cuidadosos y hacer un injerto selectivo. Todo injerto se inicia con un JMP a una zona vaca donde se pueda escribir, si busco al final de la seccin, veo que hay una zona vaca en

En mi maquina esta all en la suya estar al final de la seccion code, ven que hay muchos ceros, lo primero que har ser verificar si sirve.

Hago click derecho VIEW EXECUTABLE para ver la zona, la cual si aparece, me habilita para guardar los cambios en el exe.

Veo que la zona aparece en el ejecutable. Bueno esto es importante al hacer un injerto, verificar si se puede guardar los cambios en la zona que elegimos porque muchas veces hay partes de una seccin que son ceros, pero existen solamente en memoria, y no en el ejecutable, por lo cual no te deja guardar cambios en el exe (ya lo explicaremos mejor cuando veamos desempacado) .

Primero en donde estaba el call a la api hago un salto al injerto,

Lo hago un salto indirecto porque cabe justo sin modificar la siguiente lnea luego del call, que era un MOV EDI, EAX, siempre me tengo que fijar que al agregar cdigo no rompa las instrucciones que siguen, y se mantenga la continuidad del programa, si sobrescribo algn byte de MOV EDI, EAX dar error all al retornar del injerto. Hice un salto indirecto que toma la direccin donde saltara de 660fc400 que es una direccin un poco anterior a mi injerto donde guardo la direccin de inicio del mismo, podra haber hecho un salto directo, pero bueno, ambas posibilidades son validas (ya lo hice asi y me da fiaca cambiarlo si quieren puene poner JMP 660fc500, jeje)

Como ven all guardo la direccin de inicio del injerto, en resumidas cuentas cuando llegue al JMP saltara all.

Por supuesto en el stack aunque no estn marcados, estn los parmetros de la api, all se ve el nombre de la ventana. Debemos chequear primero que exista un nombre porque a veces llega aqu con el nombre puesto a cero, y si no chequeamos eso dar error.

Si hago doble click all en el stack veo que cambia

Eso quiere decir que la primera linea es ESP, la segunda ESP+4 y as, vemos que la que nos interesa es ESP+8, movemos el valor ese a EAX.

Voy traceando el injerto para que entiendan como funciona, al ejecutar esa lnea en EAX queda

El puntero a la string del titulo, luego la siguiente lnea testea si EAX es cero, lo cual ocurre en el caso de ventanas sin titulo.

All vemos que si EAX es cero no modifica nada y va directo al call a la api. Si EAX no es cero como en este caso continua, a la lnea siguiente

Donde compara si es la string que buscamos o sea si los 4 primeros bytes del titulo son 756f7243

Como en este caso la comparacin es cierta, y es que va a crear la nag, no salta, si fuera cualquier otra ventana, saltara directo a la api sin hacer cambios.

All vemos que si no es igual, salta a la api sin cambiar nada, ahora si es igual o sea,es la ventana buscada o nag, continua y cambia el parmetro que esta en ESP+C que es el estilo de la ventana por 40000000

All esta, al ejecutar la linea

Llega a la api y all vemos como quedaron los parmetros

Vemos que como cambiamos ESP+C por 40000000 ahora el estilo es WS_CHILD como queramos. La siguiente lnea es el call a la api que no debe hacerse en forma directa sino al igual que como lo hace en la llamada original recordamos que era.

All vemos que es un CALL indirecto, que lee el valor correcto de la api de 660014e8, por lo tanto hacemos lo mismo escribimos. CALL [660014e8] Y OLLY cambiara y colocara el nombre de la api donde saltara, pero es importante respetar siempre que sea un call indirecto similar al original, para que funcione en cualquier maquina, ya veremos eso con mas profundidad en la parte de desempacados e IATs.

Luego del CALL a la api vuelve a la lnea siguiente al call original, que es en mi maquina el MOV EDI,EAX.

Donde contina ejecutando el programa

Como vemos lo que he hecho es reemplazar el call a una api, por una rutina propia, que para cualquier ventana que no sea la nag funcione como siempre, solamente una vez que chequea que es la nag a matar, all le cambia el estilo para que no se vea. Guardemos todos estos cambios y probemos.

Vemos que con el crackme parcheado y la dll parcheada elimine la nag perfectamente y funciona, probemos el serial correcto anterior que averiguamos. Lo tipeo en la ventana

Apreto OK

Vemos que funciona perfectamente, el tema es no ser mojigatos y injertar probar y hacer lo que sea mas sencillo, que soluciones hay muchas, pero si podemos hacerla que funcione y no perjudique otro programa, estaramos jugando casi con las mismas herramientas que el programador (ellos si perjudican otros programas a veces, nosotros no) pero estaramos mas a mano.

Me gustara que para practicar vean si pueden quitar la nag del otro crackme que les di en la parte anterior, pero esta vez sin el mtodo del 4c, si no usando este mtodo de parchear el crackme y la dll, a ver si pueden con el. Hasta la parte 29 Ricardo Narvaja 24 de enero de 2006

INTRODUCCION AL CRACKING CON OLLYDBG PARTE 29


Creo que con lo que hemos visto sobre Visual Basic ya hemos completado lo bsico, los que quieren profundizar en el tema pueden leer estos tutes de crackslatinos que completaran sus conocimientos y no valdra la pena repetirlos aqu pues estn muy bien hechos. http://www.ricnar456.dyndns.org/CRACKING/NUEVO%20CURSO/TEORIAS/TEORIAS%20POR%20 TEMA/VISUAL%20BASIC/ user y pass: hola En el cual encontraran muy buenos tutes de Visual Basic como los de COCO, los mos de los INVENCIBLES de La Calavera que son bastante difciles y es una buena practica, los de ARAPUMK de los puntos mgicos de Visual Basic y muchos grandes tutes mas que creo innecesario volver a repetir en esta introduccin pues ya fueron escritos y no descubriramos nada nuevo, con esto les dejo el camino abierto a la lectura y profundizacin sobre el tema, y pasaremos al tema siguiente que es el P-CODE. Los programas de VISUAL BASIC pueden ser de dos tipos, los NATIVE que son los que vimos hasta ahora y los P-CODE (PSEUDO CODIGO) que son los que veremos brevemente para introducirlos en el tema. La diferencia principal radica en que los programas en NATIVE code, ejecutan lneas de cdigo en la seccin code del programa, mientras que los que son en P-CODE, si los abrimos con el OLLYDBG modificado para OEPs y VB y le ponemos un BPM ON ACCESS en la seccin CODE, veremos que corren y que nunca para en la seccin code en EJECUCION, salvo cuando ingresa a alguna api, y aun as es evidente que no tiene cdigo ejecutable en dicha seccin. El desensamblado de un programa en P-CODE no sirve pues al no poseer cdigo que se ejecute, no podemos interpretar nada. Como ejemplo sencillo, les digo por ejemplo que siempre se ejecuta la dll de Visual y esta va leyendo valores s de la seccin code que le dicen lo que debe hacer, por ejemplo si lee un 1e har un Salto incondicional.

El 1e significara un salto condicional, y en la misma dll de visual Basic se ejecutara el mismo, o sea que los valores que va leyendo de la seccin code le van indicando a la dll de Visual que debe hacer, aun sin ejecutar cdigo en la seccin code, solo leyendo valores de ella. Ahora como somos guapos, agarraremos el cuchillo para luchar y acometeremos una tarea titnica que nadie ha hecho aun, tracear e interpretar un crackme en PCODE todo en OLLYDBG, opcode por opcode, jeje. Veremos primero un crackme en el cual debemos hallar el serial, llamado clave1, y que se lo robamos al amigo JB DUC que tiene muy buenas teoras sobre el tema. Por supuesto la mayora del cracking en PCODE se realiza usando el excelente programa WKT debugger, el que quiere ver teoras con el mismo, puede ver las del mismo JB DUC o en el nuevo curso de crackslatinos tambin hay grandes teoras sobre P-CODE, aqu usaremos OLLYDBG y del EXDEC nos ayudaremos para ver los nombres de los OPCODES ya que la lista no es suministrada por nuestro amigo BILL GATES je.

All abrimos el crackme en un OLLYDBG comn sin parchear y con los plugins para ocultarlo, como vimos en las partes anteriores. A simple vista parece igual que un NATIVE inclusive el mtodo del 4c se aplica y nos lleva a donde estn las forms de la misma forma que en los natives (buena idea para quitar nags en P-CODE tambin, es usar el mtodo del 4c cuando funcione) Ahora que podemos ver de diferente: Si vamos bajando desde el entry point no vemos lneas de cdigo

Solo basura de ese estilo y que si la forzamos a analizar tambin da cosas sin sentido, recordemos que en un Visual Basic native si bajamos desde el entry point vemos algo as.

Basura parecida pero si continuamos bajando

Encontramos cdigo y es bastante largo continua hasta casi el fin de la seccin todo puro cdigo ejecutable, en cambio en el P-CODE salvo alguna lnea suelta que de casualidad por la cercana de bytes, OLLYDBG interpreta como alguna instruccin, es pura basura. Volvamos al crackme de PCODE

Otra caracterstica es la api esa MethCallEngine la cual encontramos en los crackmes hechos en P-CODE, as que el primer paso, identificar si el programa es P-CODE o no, ya sabemos como hacerlo, tanto sea mirando si hay cdigo ejecutable en la seccin CODE o por la api que acabamos de mencionar. Lo primero que se nos ocurre hacer es ver si hallamos STRINGS

No ayuda mucho eso en este caso, aunque en algn otro podra ayudar. Bueno pongamos un BP tanto en el JMP de la api MethCallEngine como en la misma api directamente, por si es llamada sin usar el JMP en forma directa.

Buscamos arriba del Entry Point y encontramos rpidamente el JMP a la api MethCallEngine, y situndonos encima y haciendo click derecho FOLLOW vamos a la misma, donde tambin ponemos un BP.

Ahora damos RUN.

Vemos que aparece la ventana para ingresar el serial falso antes de parar en la api, lo cual es lgico porque la creacin de las ventanas y todo esto lo realiza en la misma forma que en VB nativo, la misma dll de visual sin ejecutar cdigo del programa, al leer las forms que vemos con el mtodo 4c. Ahora ingresamos el serial falso.

Y apretamos REGISTRAR

Para en el JMP que iniciara la parte verdadera de P-CODE.

All entra a la api veamos que va haciendo

All comienza Ahora si abrimos el mismo crackme con el exdec que es un desensamblador de PCODE para ayudarnos, vemos que nos muestra esto.

O sea el primer byte que lee es un 04 y esta en la posicin 401BD0 ese seria el primer byte ledo, eso debe ocurrir no muy lejos de aqu, as que pongamos un BPM ON ACCESS en dicho byte.

Ese serial el primer byte que leera, cuando para, estaramos en el inicio, de cualquier forma podemos llegar a el sin el EXDEC, una vez que para en el BP de la api MethCallEngine, ponemos un BPM ON ACCESS en la seccin code.

Y damos RUN vemos que para varias veces

Pero la nica que lee del contenido de ESI que apunta al byte susodicho, la hallaremos enseguida, luego de unas cuantas veces que pare.( en mi maquina cont 10 exactas)

La primera vez que para y lee un byte de [ESI] y lo mueve a AL es donde comienza a leer el primer opcode de P-CODE, de esa forma podemos encontrar el primer byte sin siquiera usar el EXDEC. Como vemos los siguientes opcodes que muestra el exdec estn a continuacin del anterior.

Como ven estn en orden, aunque tengan en medio, los parmetros que necesita cada opcode para ejecutarse.

Como vimos all lee el primer byte

Lo que vemos es que ESI apunta al byte actual que se esta ejecutando, pero ya en la lnea siguiente antes de hacer ninguna operacin lo incrementa en 1, para leer los parmetros del opcode.

Luego llega siempre a un JMP indirecto que nos lleva a las lneas que ejecutaran el OPCODE, en este caso 04 como vimos en el EXDEC. 401BD0: 04 FLdRfVar local_008C

Veremos que hace este opcode tan misterioso entramos en el.

All vemos la ejecucin del OPCODE 04 FLdRfVar, son unas pocas lneas de cdigo, nada para asustarse jeje y siempre vemos que termina con un XOR EAX,EAX y a leer el siguiente opcode. Lo primero que hace es cargar los parmetros del OPCODE que son los dos bytes siguientes al mismo.

Bueno los pasa a EAX y como es un MOVSX y el valor FF74 es negativo los completa con FFs como vimos en la parte de assembler, sigamos traceando.

Ese valor es EAX es -8c, pues si hacemos doble click en el

Nos muestra que vale -140 decimal que es -8c en hexa por lo tanto, como vemos el 8c que nos muestra el EXDEC aparece aqu. 401BD0: 04 FLdRfVar local_008C

En la siguiente lnea suma ese valor que leyo de los parmetros con EBP

Y luego le hace PUSH a ese valor

O sea que esto es equivalente a un PUSH EBP- 8c esta mandando el stack una variable local, en mi maquina EBP es 12f4e0 si a eso le restamos 8c nos da 12f454 que es el valor que quedo en EAX y pushea.

Nada del otro mundo sigamos.

Vemos que luego pone EAX a cero lo cual significa que la operacin con este opcode ya finaliza y esta inicializando los registros para leer el siguiente, en la prxima lnea ya lee el opcode siguiente.

El segundo opcode es el 21 Aqu lo lee

Lo mueve a AL como siempre.

Y ahora le suma a ESI el valor 3 para que quede apuntando a los parmetros de este opcode, luego llega al JMP indirecto, que va al cdigo del OPCODE 21. Veamos que hace buscando intensamente en google '21, FLdPrThis 'Load reference pointer into item pointer. Bueno hay aqu algunos punteros que no sabemos bien para que sirven, ni sirve mucho pero el tema es que carga un reference pointer y lo guarda en item pointer, en asm esto nos dice que lee un puntero del stack y lo mueve a otro lugar de nuestro stack.

Si seguimos traceando

Lo que vemos es que lee el contenido de EBP + 8 (reference pointer) y lo guarda en el contenido de EBP-4c ( item pointer) Bueno el valor que lee en mi maquina es 15b000 si vemos en el DUMP

Vemos que alli hay un puntero a 4022e8, y alli si vemos en el DUMP

Vemos que alli comienza una tabla asi que 15b000, el reference pointer apunta a algo que parece una tabla, aunque esto no nos ayuda mucho para el cracking es bueno siempre tratar de ir descifrando un poco lo que hace el programa, lo mas profundamente que podamos y de acuerdo a la poca informacin que tenemos. Por lo dems este es un comando sin parmetros por lo cual, no hay variacin en el mismo, seguramente al ejecutarlo lee siempre el reference pointer y lo guarda en el item pointer y chau, jeje. Bueno continuemos

Luego ya borra EAX y en la prxima lnea lee el tercer opcode

Que es 0F en el EXDEC vemos que se trata de

VCallAd

Bueno aqu vemos la idea de lo que hace el siguiente OPCODE 0F, vemos que tiene un solo parmetro de 2 bytes

El parmetro en mi caso es 0300 y dice que dicho valor es un offset en la item descriptor table, hmm veamos, entremos en el JMP indirecto as miramos si coincide con lo que dice.

All esta lee el famoso contenido de EBP-4c y lo pasa a EBX

All esta el 15b000 dicho valor lo pushea

Luego lee los parmetros que en mi caso es 300

Y aqu el quid de la cuestin como EBX vale 15b000, su contenido es el inicio de la tablita que vimos, que segn la aclaracin es la ITEM DESCRIPTOR TABLE, o sea 4022e8

Y a eso le suma 300 o sea que esta buscando un valor en dicha tabla, el 300 a partir del inicio de la misma.

Recordamos que ese era el inicio de la tabla al sumarle 300 queda en EAX el valor 4025e8.

Dicho valor apunta a esa tabla

O sea que recopilando el opcode anterior guarda el inicio de esta tablita y el 0f, localiza en la tabla segn el parmetro, un valor determinado en la misma.

Luego hay un call a la direccin que lee de dicha tabla ya que como vimos el contenido de EAX es

O sea que ira a 7414c348 no entraremos en el call veremos que nos deja a la salida ya que decia que guardaria el valor en el stack.

Pues sigamos traceando pasemos el CALL con f8

O sea de todo ese chiste quedo el valor ese en el stack, que ya veremos para que sirve, por ahora sabemos como dice la definicin, que es un valor que leyo de la tabla de tems, segn el parmetro 0300, y el retorno produjo ese valor en el stack.

El prximo OPCODE es el 19, aqu trabajara con la variable local 88, que surgir de los parmetros del opcode.

All saltamos a la ejecucin del mismo.

All esta.

Lee los parmetros con MOVSX y como es negativo los completa con FFs

Como ya adivinaron ese es el valor -88 en hexa como dice el EXDEC.

-136 decimal es igual a -88 en hexa

Luego incrementa el puntero ESI en 2 y le suma a EBP el valor -88 que es lo mismo que hacer EBP-88 y el resultado queda en EAX.

Vemos que al llegar al call en el stack tenemos tres parmetros

Al primero es el valor que nos haba encontrado y guardado en el stack el opcode anterior, y dos valores mas en mi caso 12f458 que es la variable local ebp-88 y un tercer parmetro que es -1, sin entrar en el CALL pasmoslo con f8 a ver que pasa. Al ejecutarlo vemos que en ebp-88 se guardo el valor hallado por el opcode anterior

Lo dems quedo todo igual salvo que el stack cambio y que ECX volvi siendo cero, quizs para marcar que el proceso fue exitoso. O sea que esto movi a EBP-88 el valor que obtuvo del opcode anterior.

Llegamos al otro opcode que es 08, que tambin se ve que trabaja con la misma variable local 88 o sea ebp-88.

Entramos el OPCODE

Este es cortito ah abajo vemos que termina pues esta el siguiente XOR EAX,EAX que marca la finalizacin del mismo aunque hay un salto condicional en el medio veamos que hace. Lo primero, pasa a EAX los parmetros del OPCODE

Al igual que antes es el valor FF78 que al moverlo con MOVSX lo completa con FFs al ser negativo y ya vimos que es el -88 hexa.

En esa lnea directamente suma EAX+EBP lo que le da EBP-88 y luego mueve el valor guardado all que era el famoso, que obtuvimos de la tabla de tems.

Ah testea si es cero, si fuera cero saltara, pero como aqu no es cero continua.

Guarda ese valor en EBP-4C Aqu le vemos sentido a lo que decamos en el inicio recordemos Lo que vemos es que lee el contenido de EBP + 8 (reference pointer) y lo guarda en el contenido de EBP4c (item pointer) Como ebp-4c es el puntero de tems, como este ya confirmo que es valido y que no es cero lo guarda alli, en la variable EBP-4c que se usa para eso, por eso se llama ITEM POINTER, ya que este valor lo hallo en relacin a la tabla de ITEMS.

Llegamos al siguiente opcode

Por all en San Google leo que dicho OPCODE sirve para 0d VCallHresult #get the text from textbox O sea que leer el serial falso que tipeamos en el textbox, veamos si es cierto, traceemos

Ah vemos el OPCODE que termina en XOR EAX,EAX como siempre Lo primero que hace es leer del puntero EBP-4c, que como dijimos era el ITEM POINTER y lo mueve a EAX el archiconocido valor que ley de la tabla de ITEMS

Luego lo PUSHEA

Luego lee un parmetro del OPCODE.

Y lo pasa a EDI Luego lee el contenido de EAX que es el inicio de otra tabla

Y en esa tabla le suma el parmetro 00a0 para buscar el ella.

Y el realiza un call a la direccin que obtiene de esa tabla, por supuesto no vamos a tracear ese call por dentro, vemos que en el stack continan los valores que obtuvo de los opcodes anteriores

Ejecuto el CALL con f8 Luego mueve a EDX un valor que obtiene del contenido de EBP-44

Y luego de testear un par de valores llega al prximo OPCODE, pero ustedes dirn, leyo lo que tipeamos o sea nuestro serial falso?, si lo ley si vemos el EXDEC

Vemos que a continuacin trabaja con la variable local 8c que como sabemos esta en EBP-8C Si buscamos el valor de EBP-8c

Es 12f454

Y ese es el puntero al serial falso que escribimos, o sea en 15d3bc

Uff costo sangre pero llegamos al punto donde ley el serial falso.

El siguiente OPCODE es 6c ILdRf

All dice que este OPCODE es LOAD REFERENCE VALUE veamos entremos en el OPCODE

Aqu esta

Lo primero que hace es mover el parmetro con MOVSX asi completa con FFs si es negativo.

Como el parmetro es FF74, pues al pasarlo a EAX quedara

Que es -8c en hexa

En la prxima instruccin lo suma a EBP, con lo cual obtiene EBP-8c y pushea el contenido o sea que seria equivalente a PUSH [ebp-8c]

Pero en el contenido de ebp-8c tenia un puntero al serial falso, por lo cual ahora tenemos el puntero alli en el stack.

Si lo vemos en el dump vemos claramente que apunta al serial falso, vemos porque llaman al OPCODE, LOAD REFERENCE VALUE, pues carga al stack un valor que vamos a usar desde una variable local. El prximo opcode es 1b LitStr por all leo que significa Literal String Veamos que hace

Entremos en el OPCODE

Lo primero lee el parmetro que aqu es 0001 y lo mueve a EAX como es positivo no le agrega FFs

Vemos que en la prxima lnea mueve a EDX un valor 4017E4 no sabemos que es sigamos.

Y que pushea un valor 4016f8 que puede ser?

Vemos que la aclaracin del EXDEC nos muestra unas comillas, o sea que este valor que movio al stack apunta a una string vaca.

Pues si vemos en el dump que apunta a una string vacia que termina en comillas, o sea lo que har en el siguiente opcode ser chequear si tipeamos algo, o si dejamos vaco el textbox y apretamos register.

Que es

Bueno LEAD 0 es una operacion y segn la segunda parte del OPCODE ser la operacin que realiza en este caso 30 Eq Str que vemos en San Google Lead0/30 EqStr <---Compara dos strings O sea que va a comparar esas dos strings este es un OPCODE doble o sea que primero lee el primero que es FB salta el JMP indirecto

Y all noms termina el primer OPCODE con XOR EAX,EAX sin hacer nada y lee el segundo OPCODE

All lee el segundo OPCODE 30, diferenciamos en este caso un OPCODE doble, de leer parmetros del un OPCODE, porque la diferencia esta en que en un OPCODE DOBLE se cierra el primer OPCODE con el XOR EAX.EAX y ah recin se lee el segundo OPCODE, en el caso de lectura de parmetros el primer OPCODE queda abierto y no se cierra al leerlos.

All esta el segundo OPCODE, hace un PUSH 0

Y quedan los tres argumentos al llegar al CALL pasmoslo con f8 y veamos lo que cambio. Vemos que el stack se movi pero los valores continan sin modificacin un poco mas arriba.

Vemos que en la siguiente lnea CMP AL,0 lo cual me dice que all en AL, guarda el resultado en mi caso es

AL=01 Porque las strings no son iguales

Luego de la comparacin mueve a EAX el valor cero y como resultado de todo esto termina PUSHEANDO el cero al stack, lo cual es el resultado del OPCODE, da cero en el stack si no son iguales, si hubieran sido iguales dara FFFFFFF si quieren probar hganlo jeje.

Llegamos al siguiente OPCODE

San Google nos dice que es similar a SysFreeString que libera una string cuando ya no se usa, veamos en este caso liberara la de ebp-8c (local 8c)

Veamos mueve a EDI el valor 1, luego el FF74 que es -8c en hexa como siempre con el MOVSX para llenar con FFs si es negativo.

EBX+EBP es EBP-8c, as que pushea el puntero al serial falso

Vemos que dentro de ese call va a la api SysFreeString , y al retornar

Machaca con cero el puntero a nuestro serial falso

Ojo no borro el serial falso, este sigue estando en 15d3bc lo que borro es el puntero al mismo que estaba en EBP-8c.

Alli llega al siguiente OPCODE

Este seguro borrara el contenido de la variable local ebp-88 Que haba all?

Ah el valor que haba hallado de la tabla de tems, seguro lo borrara veamos, ya nos estamos haciendo mas prcticos jeje.

All lee los parmetros del opcode que son

FF78 que completara con FFs y sera el valor -88 hexa

Luego mueve a EAX el contenido de EBP-88 testea si es cero, como no lo es sigue adelante.

Y ira a un call que como antes liberara el valor este, y luego borrara el contenido de ebp-88.

All esta puesto a cero.

El prximo OPCODE es

Es un salto condicional ya que todos los BRANCH son saltos

O sea que es un salto si es falso y a continuacin hay un JMP o sea que este salto al ver que tipeamos algo en el textbox salta a la comparacin del serial, si no volvera a repetir el proceso con el JMP. Veamos si es cierto, si esto salta, el prximo opcode debera ser

Ya que este salto condicional evita el JMP de 401bf3

All termina el opcode y lee el prximo

Que como suponamos es el FE de 401bf6, as que el salto condicional salto y evito el JMP, jeje. Lead3/c1 LitVarI4 Este es un OPCODE doble veamos que hace

All cierra el primer OPCODE y lee el segundo

Que empieza aqu traceemos con paciencia

Lee los parmetros del opcode

Ya sabemos que los completa con FFs si es negativo como en este caso

Lee mas parmetros en este caso es un DWORD entero que pasa a EAX

Y ese valor lo guarda en una variable local que esta dada por la operacin

EBP+ FFFFFF54 + 8 o sea que le suma el primer parmetro y 8 esto da 12f43c, all guarda el valor

Y esperen que aun no termino que el jmp nos lleva a

Donde pushea 12f434

Que es el puntero a un estructura donde empieza con el 3 que haba guardado, y mas abajo el valor guardado.

Sigamos ya llegamos jeje Cualquiera aqu ya que es un serial fijo probara pasar este valor a decimal y intentar a ver si es el serial correcto, si abro otra instancia del crackme fuera de OLLYDBG

Miro en OLLY cuanto vale ese nmero en decimal

Vale 246810 tipeemoslo en el crackme

Jeje ya sabemos algo pero no se libraran tan fcil de esto, lleguemos a la comparacin.

El prximo OPCODE tambin es doble Es FC y enseguida lo cierra y carga el segundo

Que es F6 entremos en el sin miedo (ya a que podemos temer jeje), recordemos que el exdec nos dice que trabajara con la variable local 9c o sea ebp-9c.

All lee los parmetros y los completa con FFs

Por supuesto ese valor es -9c

Lo suma a EBP para hallar EBP-9c que es 12f444 que por ahora esta vaco

Luego compara si es mas bajo que 8 como es cierto salta.

Luego vuelve a saltar no entraremos en demasiado detalle, llega al final aqu donde se ven las ltimas lneas del OPCODE.

Mueve el 3 que esta en EAX a la variable EBP-9C Y borrara el 3 de la estructura anterior o sea que esta copiando el nmero, desde donde estaba a una nueva direccin. Aqu estaba y borra el 3

Al ejecutar

Luego las siguientes lneas copian todo lo que hay aqu, a la nueva direccin o sea a EBP-9c

All lo vemos al numero que ser el serial correcto en la estructura que comienza en EBP-9c

Llegamos al siguiente OPCODE 401C02: 04 FLdRfVar local_008C

Vemos que repite todo lo que ya vimos hasta aqu al inicio 401C02: 04 FLdRfVar 401C05: 21 FLdPrThis 401C06: 0f VCallAd 401C09: 19 FStAdFunc local_008C text local_0088

401C0C: 08 FLdPr 401C0F: 0d VCallHresult 401C14: 6c ILdRf

local_0088 get__ipropTEXTEDIT local_008C

Es todo similar al inicio, el siguiente OPCODE es

As que para saltear todo lo anterior pongo un BPM ON ACCESS en 401c17, para que pare cuando lea el OPCODE.

All paro y lee el OPCODE 0A que vemos en el EXDEC

ImpAdCallFPR4 vemos que significa el llamado a la api que nos marca el EXDEC Por ejemplo

En este ejemplo seria un llamado a la api rtcMsgBox, en nuestro caso es un llamado a la api 401C17: 0a ImpAdCallFPR4: _rtcR8ValFromBstr

Lee los parmetros del opcode

Los mueve a ECX

Luego mueve a EAX el valor 401000 y lo testea si es cero

Luego lee un segundo parmetro

Y llega al call eax donde EAX vale 401000, veamos donde va, va a la api susodicha.

Y el parmetro que le pasamos en el stack a la api es

Mi serial falso

El cual fue cargado en St0 que es una entrada del stack de punto flotante que aun no hemos explicado, pero bueno, all lo ven esta debajo de los registros, si no le sale visible, pues tienen la vista en otra opcin hagan click derecho

All esta el tipo cargo mi serial falso all.

Llego al siguiente OPCODE 401C1C: Lead2/6b CVarR8 Pues all estamos entremos en el opcode

Como es un opcode doble borra el primero y carga el segundo

Bueno all hay unos comandos de punto flotante que aun no hemos visto Pero vemos que al inicio esta cargando parmetros

En este caso

Lo suma a EBP quedando EAX en

Con FSTP guardara el primer valor del stack de punto flotante ST0, a la direccin de memoria en este caso [EAX+8] o sea 12f43c y har POP el stack de punto flotante bueno eso ya lo explicaremos mas adelante.

Al ejecutar

Ya se que ustedes pueden tener alguna duda que ese es nuestro serial falso, lo que pasa es que esta transformado a 64 bit doble, veamos si hago click derecho

Veo que efectivamente es mi serial falso, solo que cambio de forma de representacin al abarcar 8 bytes o sea doble de 64- bit, lgico de 4 bytes es 32 bit, ahora es doble o sea un numero de 64-bit, por eso se ve diferente.

Volvamos a la visin normal

Eso guarda el STATUS WORD de punto flotante a AX, ejecutemos

All termina el OPCODE 401C20: 5d HardType Bueno este no tengo la ms mnima idea de lo que es pero lo descubriremos

Bueno son solo dos lneas mueve el contenido de ESP a EAX

Vemos que esta agregando al nmero que esta arriba de mi serial falso transformado, posiblemente ese nmero indique el formato en que se encuentra, y ahora lo ajusta.

Siguiente OPCODE

401C21: 04 FLdRfVar

local_009C

Ese es el inicial o sea PUSH ebp-9c en este caso

All esta El siguiente es un opcode doble

401C24: Lead0/40 NeVarBool

All lee el segundo opcode

Llega a ese call y los parmetros en el stack son

Pues uno es un puntero al serial verdadero, otro al falso transformado, ser la comparacin aqu?

Pongamos un BP alli

Vemos que al salir del call EAX vale =1

Y que hace un PUSH al stack con el valor FFFFFFFF, es casi seguro que la comparacin es aqu, as que reinicio el crackme total puse un BP, y pongo el serial correcto que obtuve de esta comparacin

03c41a pasado a decimal es 246810, pongmoslo y lleguemos a la comparacin de nuevo

Al parar veo que compara

246810 con el valor hexa del mismo, la verdad que son diferentes formatos pero como arriba de cada uno hay un numero que identifica el formato es posible que dentro del mismo call los transforme y los compare, veamos que nos da ahora a la salida

Vemos que ahora nos da EAX=0 (antes daba 1)

Y el push al stack tambin da cero Lo cual quiere decir que esta es la comparacin, adems vemos justo abajo unos Branch, que son los saltos que decidirn si ir al cartel correcto o incorrecto, luego de liberar las strings y valores usados

Ustedes dirn esto es mucho trabajo, pero si se dan cuenta el trabajo fuerte, es la primera vez que usas cada opcode pues una vez que descubrs que hace ya no necesitas repetirlo, por lo dems el WKT debugger te muestra el nombre de los OPCODES, pero no sabes que hace cada uno, salvo los mas conocidos y con OLLYDBG , podemos determinar que hace cada uno y tener una mejor idea de cmo funciona el programa.

En la prxima parte har con el mismo mtodo el crackme adjunto clave 2, me gustara que siguiendo el mismo mtodo hallaran la clave si pueden de ese clave2, si no, en la prxima parte lo har yo, y lo podrn leer. UFFFFFFFF Hasta la 30 Ricardo Narvaja

INTRODUCCION AL CRACKING CON OLLYDBG parte 30


Bueno despus de haber practicado y si aun estn vivos seguiremos con PCODE. Tenemos algunos OPCODES ms que juntamos por ah de los tutes de JBDUC 6c -> ILdRf Empuja una direccin a la pila 1b -> LitStr5 Empuja una cadena literal a la pila fb -> Lead0 Compara dos cadenas (jeje, para que podra servir esto :-) 30 -> EqStr Compara dos cadenas (jeje, para que podra servir esto :-) 2f -> FFree1Str Libera la memoria usada 1a -> FFree1Ad Libera la memoria usada 0f -> VCallAd Ejecuta cdigo dentro de la mquina virtual 1c -> BranchF Salta si la comparacin previa era falsa ( vamos lo mismo que un jne/jnz de asm ) 1d -> BranchT Salta si la comparacin previa era cierta ( vamos lo mismo que un je/jz de asm ) 1e -> Branch Salta incondicionalmente ( jeje adivina ke utilidad tiene) fc -> Lead1 Termina la ejecucn del programa (jeje este es bueno...) c8 -> End Termina la ejecucn del programa (jeje este es bueno...) f3 -> LitI2 Guarda el Integer especificado en la pila f4 -> LitI2_Byte Convierte un valor de Byte a Integer y lo mete en la pila 70 -> FStI2 Guarda el ltimo Integer que se haya en la pila en la variable global especificada 6b -> FLdI2 Carga en la pila un Integer desde la variable local especificada a9 -> AddI2 Suma los dos ltimos Integers que se empujaron a la pila y mete en pila el resultado ad -> SubI2 Resta los dos ltimos Integers que se empujaron a la pila y mete en pila el resultado b1 -> MulI2 Multiplica los dos ltimos Integers que se empujaron a la pila y mete en pila el resultado como un Integer, creo que si hay desbordamiento se ignora. Bueno tenemos unos cuantos opcodes mas, que nos evitaran tener que investigarlos, adems adjunto un archivo llamado P-CODE OPCODES que supuestamente distribuye Microsoft que ayuda un poco y que lista los opcodes y que hace cada uno (no todos jeeje), en una muy escueta descripcin (jeje demasiado escueta para mi gusto, pero bueno, antes de entrar a un opcode conviene mirar a ver si en el mismo podemos comprender que hace, as entramos con cierta idea. Como les promet, al inicio haremos el crackme clave 2 que quedo de ejercicio la vez anterior, miremos si podemos hallar un listado con el EXDEC.

Ah tenemos y vemos que comienza en 401cc0, para los que no creen en el EXDEC ya que muchas veces puede ser engaado, veamos si hallamos el primer OPCODE a mano, como vimos en la parte anterior.

Veamos si esta el JMP a la api MethCallEngine por encima del EP.

All esta, por si acaso sea llamada directamente sin usar el JMP; nos posicionamos sobre el y hacemos FOLLOW para ir a la api y ponemos un BP all tambin.

Listo ahora demos RUN hasta que pare en alguno de estos BP que colocamos.

Aparece la ventana antes de parar en el BP, el tema que la ventana aparece antes que entrar a PCODE, debo aclarar que no necesariamente es as, puede parar en el BP y luego aparecer la ventana, en este caso, aparece la ventana antes, coloco un nombre y serial falso.

Y al apretar REGISTRAR para en el BP del JMP ahora voy a la primera seccin (recordar no usar el OLLY parcheado para OEPs y Visual si no, no funcionara) y le coloco un BPM ON ACCESS en la seccin code.

Ahora dar RUN hasta que encuentre la instruccin conocida, de que esta leyendo un OPCODE

All esta, recordemos que siempre ESI debe apuntar al opcode y mover el mismo a AL. Como vemos el EXDEC no se equivoco y el primer OPCODE esta en 401cc0 y es el 04. Proc: 401e90 401CC0: 04 FLdRfVar

local_008C

Recordamos que el 04 era un simple PUSH del argumento que en este caso es EBP-8C si miramos la ayuda que adjuntamos sobre el OPCODE.

04 567B 0B8E 2 1 2

Push arg

All mismo nos aclara que es cada cifra en nuestro caso el 0B8E seria el RVA del opcode, 2 seria la cantidad de bytes que tienen los argumentos en total, 1 nos aclara que tiene un solo argumento, y el ultimo 2 seria el largo en bytes de cada argumento por separado. Bueno es un PUSH EBP-8C sigamos mirando el listado sin necesidad de tracear uno a uno, vemos estos. 401D4C: 0d VCallHresult 401DFB: 0d VCallHresult get__ipropTEXTEDIT get__ipropTEXTEDIT

Vemos que hay dos calls para leer lo que ingreso en la ventana de registro, posiblemente el primero lea el nombre y el segundo el serial falso que tipeo, pongamos un BPM ON ACCESS en el primero o sea en 401d4C.

All esta el opcode y le coloco el BPM y doy RUN.

Bueno ahora traceemos hasta el siguiente opcode, a ver si ingresa el nombre.

All llega al siguiente opcode miremos el stack a ver si lo guardo 401D4C: 0d VCallHresult 401D51: 3e FLdZeroAd get__ipropTEXTEDIT local_008C

Como vemos que a continuacin trabaja con la variable local 8c que equivale a EBP-8C me fijo si lo guardo all, en mi maquina ebp-8c vale 12f454

Busco en el stack esa direccin a ver si esta all mi nombre.

Pues si, all lo veo, as que vamos bien, aqu veo que ingreso mi nombre, lo lgico seria que en el otro, ingrese mi serial falso, pongamos un BPM ON ACCESS en el segundo. 401DFB: 0d VCallHresult get__ipropTEXTEDIT

Listo ahora doy RUN hasta llegar a ese opcode

Como antes traceemos hasta el siguiente opcode.

Y veamos si guardo el serial falso en la variable local que usara 401DFB: 0d VCallHresult 401E00: 3e FLdZeroAd get__ipropTEXTEDIT local_008C

Como antes lo guardara en EBP-8c

Bueno ya llegamos a donde ingresa nuestro serial falso, vemos como conociendo los opcodes no es necesario tracear todo el programa podemos ir poniendo BPM y llegando a las partes calientes sin necesidad de tracear todo, en la parte anterior traceamos todo para que entiendan el mecanismo de cmo funciona PCODE pero normalmente no necesitamos hacer eso, ya lo veremos en la prxima parte cuando crackeemos un extenso programa y localicemos solo la zona caliente que nos interesa y miremos por all. 401E0F: Lead0/ef ConcatVar 401E13: Lead0/40 NeVarBool 401E15: 1a FFree1Ad local_0088 401E18: 36 FFreeVar local_00CC local_00AC 401E1F: 1c BranchF: 401E59 Luego viene esto que tiene todo el aspecto de comparacin, luego liberacin de la variables locales con FREE, y salto condicional que como vemos va a 401e59 que es el rtcMsgBox de clave correcta y si no salta va al cartel de Clave no Valida

All lo vemos claro, la posible comparacin y el salto condicional que decide entre ir a CLAVE NO VALIDA o CLAVE CORRECTA, pues pongamos un BPM ON ACCESS all, a ver si vemos algo. 401E0F: Lead0/ef ConcatVar 401E13: Lead0/40 NeVarBool

Bueno demos RUN

All paro, en el primer opcode, traceemos hasta el segundo que es el que realizara la operacin

All esta el segundo OPCODE es EF Vemos en la lista de opcode FB EF 6BAB 25AD 2 FB F0 6B99 259B 0 FB F1 C423 B981 0

vbaStrCat Push [FC0D134]

Que FB EF no nos aclara que es, igual el EXDEC nos decia algo de concatenar variables, veamos. 401E07: 3a LitVarStr: ( local_009C ) CRK

401E0C: 04 FLdRfVar local_018C 401E0F: Lead0/ef ConcatVar 401E13: Lead0/40 NeVarBool Vemos que justo antes de este opcode trabaja con dos variables locales y en una tiene la STRING CRK y hay otra que esta en EBP-018C veamos que hay en cada variable que menciona.

La primera de las dos variables es EBP-9c que en mi maquina es 12F444 y all esta como dice el EXDEC

Y en la otra sabemos que en el caso de variables hay primero un byte que indica el tipo en este caso el 3 y mas abajo esta la variable realmente que ser 2EA.

Entremos en el OPCODE

All lee los parmetros

Que luego de sumarle EBP se transforma en 12f434

Llegamos a la api vbaVarCat con tres argumentos en el stack

Veamos que hay en cada uno, recordemos que cuando trabaja con Var como en este caso, hay que mirar una pequea estructura ya que el primer byte como vimos antes es el tipo de variable, etc.

Ese es el primer argumento

El segundo con el 3 al inicio y 02EA como valor

Y el tercero con el 8 al inicio nos muestra un puntero 401748 a la string CRK

Bueno hagamos la ensalada de variables a ver que queda jeje. Si entramos dentro de la api vbaVarCat llegamos a una api interior que nos muestra ms claro que va a unir.

O sea que va a unir CRK con 746 ahora vemos que el parmetro que en la vbaVarCat era 02EA

Lo transforma a string ya que 02EA es

O sea que la api vbaVarCat toma una string en este caso y una variable numrica que convierte a string y las unir. Sigamos traceando con f8 Al llegar al RET de la api vemos

Como uni y formo una linda string con ambas variables.

Y como antes de llegar al siguiente opcode la guarda en el primer argumento.

Vemos como el primer argumento ahora es del tipo 8 o sea string, y que apunta a 15d88c que esta la string concatenada.

Pues bien ahora debera venir la comparacin, lleguemos hasta el siguiente OPCODE.

401E13: Lead0/40 NeVarBool Como es doble y es FB40 traceo hasta que lee el segundo OPCODE

Por supuesto la lista de Microsoft no dice nada sobre el, as que traceemos el opcode a ver que hace, jeje.

Vemos que el opcode solo tiene una call y luego enseguida termina veamos los argumentos de esta call.

El primero argumento es cero, luego el segundo es 12f434 miremos que hay alli

Bueno 08 nos indica que es una string miremos cual es ya que nos muestra que 15d88c apunta a ella.

All esta la string veamos el otro argumento.

Y en este caso 15ca94 apunta a la string de nuestro serial falso.

Pues parece que va a comparar ambas strings.

Pongamos un BP para sacarnos la duda, pasemos la call con f8 y lleguemos al otro opcode Vemos que en el stack quedo FFFFFFFF posiblemente porque las strings no son iguales, anotemos el posible serial bueno y probemos hasta que pare en el BP que pusimos nuevamente aqu.

Al apretar registrar

Llego de nuevo a la call la paso con f8 y llego al siguiente opcode como antes

Vemos que en este caso el resultado es cero al ser las strings iguales.

Como ven sin necesidad de tracear todo, solamente encontrando la parte caliente y traceando algn opcode desconocido, me sirvi para encontrar el serial de este programa. Para los que quieran el listado mas detallado aqu va un detalle que me enviaron.
401CC0: 04 FLdRfVar 401CC3: 21 FLdPrThis local_008C ; text local_0088 local_0088 get__ipropTEXTEDIT local_008C & local_008C local_0088 401CE6 401e8c local_008C text local_0088 local_0088 get__ipropTEXTEDIT local_008C 0x6 6 (....) ;

Load reference pointer into item ITEM DESCRIPTOR TABLE

pointer.
401CC4: 401CC7: 401CCA: 401CCD: 401CD2: 401CD5: 401CD8: 401CDA: 401CDD: 401CE0: 401CE3: 401CE6: 401CE9: 0f VCallAd 19 FStAdFunc 08 FLdPr 0d VCallHresult 6c ILdRf 1b LitStr: Lead0/30 EqStr 2f FFree1Str 1a FFree1Ad 1c BranchF: 1e Branch: 04 FLdRfVar 21 FLdPrThis ; Accede a metodo

; ; ; ;

Lee contenido de texbox NOMBRE Empuja cadena a la pila Compara dos cadenas

; Salta si comparacion falsa ; Salto incondicional

401CEA: 0f VCallAd

Accede

metodo

ITEM DESCRIPTOR

TABLE
401CED: 401CF0: 401CF3: 401CF8: 401CFB: 401CFC: 401D01: 401D02: 401D05: 401D08: 401D0B: 401D0E: 401D11: 401D16: 401D19: 401D1C: 401D21: 401D26: 401D29: 401D2C: 401D31: 401D3C: 401D3F: 401D42: 401D43: 401D46: 401D49: 19 08 0d 6c 4a f5 d1 2f 1a 1c 27 27 3a 4e 04 f5 3a 4e 04 0a 36 1e 04 21 0f 19 08 FStAdFunc FLdPr VCallHresult ILdRf FnLenStr LitI4: LtI4 FFree1Str FFree1Ad BranchF: LitVar_Missing LitVar_Missing LitVarStr: FStVarCopyObj FLdRfVar LitI4: LitVarStr: FStVarCopyObj FLdRfVar ImpAdCallFPR4: FFreeVar Branch: FLdRfVar FLdPrThis VCallAd FStAdFunc FLdPr ; Lee contenido de texbox ; NOMBRE ; Pasa entero de 4 bytes (6) ; Comparacion menor que?

local_008C local_0088 401D3F

; Salta si falso (es >= 6)

( local_00BC ) P-Code local_00CC local_00CC 0x40 64 (...@) ( local_009C ) Mnimo 6 caracteres local_00AC local_00AC _rtcMsgBox local_00AC local_00CC local_00EC local_010C 401e8c ;Si < 6 caracteres a la calle local_008C text local_0088 local_0088

401D4C: 401D51: 401D54: 401D57: 401D5A: 401D5F: 401D62: 401D65: 401D6A: 401D6D: 401D71: 401D74: 401D7B: 401D7E: 401D82: 401D86: 401D8B: 401D8E: 401D91: 401D97: 401D9C: 401D9F: 401DA1: 401DA4: 401DA7: 401DAC: 401DAF: 401DB3: 401DB8: 401DBB: 401DBF: 401DC2: 401DC9: 401DCC: 401DCF: 401DD3: 401DD7: 401DDA: 401DE0: 401DE3: 401DE6: 401DEA: 401DEE: 401DF1: 401DF2: 401DF5: 401DF8: 401DFB: 401E00: 401E03: 401E06: 401E07: 401E0C: 401E0F: 401E13: 401E15: 401E18: 401E1F: 401E22: 401E25: 401E28: 401E2D: 401E30: 401E33: 401E38: 401E3D: 401E40: 401E43:

0d VCallHresult get__ipropTEXTEDIT 3e FLdZeroAd local_008C 46 CVarStr local_00AC 04 FLdRfVar local_00CC 0a ImpAdCallFPR4: _rtcLowerCaseVar 04 FLdRfVar local_00CC 04 FLdRfVar local_00EC 0a ImpAdCallFPR4: _rtcTrimVar 04 FLdRfVar local_00EC Lead1/f6 FStVar local_011C 1a FFree1Ad local_0088 36 FFreeVar local_00AC local_00CC 04 FLdRfVar local_011C Lead0/eb FnLenVar Lead1/f6 FStVar local_012C 28 LitVarI2: ( local_00BC ) 0x1 04 FLdRfVar local_013C 04 FLdRfVar local_012C Lead3/68 ForVar: (when done) 401DE0 28 LitVarI2: ( local_00AC ) 0x1 04 FLdRfVar local_013C Lead1/22 CI4Var 04 FLdRfVar local_011C 04 FLdRfVar local_00CC 0a ImpAdCallFPR4: _rtcMidCharVar 04 FLdRfVar local_00CC Lead2/fe CStrVarVal local_008C

; Lee contenido de texbox ; NOMBRE

; Convierte a minusculas

(1)

, Incio bucle for next (1)

; Va tomando los caracteres del ... ; ... nombre

0b ImpAdCallI2 _rtcAnsiValueBstr ; convierte valor carcter a hexadec 44 CVarI2 local_00BC Lead1/f6 FstVar local_016C 2f FFree1Str local_008C 36 FFreeVar local_00AC local_00CC 04 FLdRfVar local_017C 04 FLdRfVar local_016C Lead0/94 AddVar local_00AC Lead1/f6 FStVar local_017C 04 FLdRfVar local_013C Lead3/7e NextStepVar: (continue) 401D97 ; Fin bucle for-next? 04 FLdRfVar local_017C 04 FLdRfVar local_012C Lead0/94 AddVar local_00AC Lead1/f6 FStVar local_018C 04 FLdRfVar local_008C 21 FLdPrThis 0f VCallAd text 19 FStAdFunc local_0088 08 FLdPr local_0088 0d VCallHresult get__ipropTEXTEDIT ; Lee contenido de texbox 3e FLdZeroAd local_008C ; SERIAL 46 CVarStr local_00CC 5d HardType 3a LitVarStr: ( local_009C ) CRK 04 FLdRfVar local_018C Lead0/ef ConcatVar Lead0/40 NeVarBool 1a FFree1Ad local_0088 36 FFreeVar local_00CC local_00AC 1c BranchF: 401E59 27 LitVar_Missing 27 LitVar_Missing 3a LitVarStr: ( local_00BC ) P-Code 4e FStVarCopyObj local_00CC 04 FLdRfVar local_00CC f5 LitI4: 0x10 16 (....) 3a LitVarStr: ( local_009C ) Clave No Vlida! 4e FStVarCopyObj local_00AC 04 FLdRfVar local_00AC 0a ImpAdCallFPR4: _rtcMsgBox

401E48: 401E53: 401E56: 401E59: 401E5C: 401E5F: 401E64: 401E67: 401E6A: 401E6F: 401E74: 401E77: 401E7A: 401E7F: 401E8A: 401E8C:

36 FFreeVar 1e Branch: 1e Branch: 27 LitVar_Missing 27 LitVar_Missing 3a LitVarStr: 4e FStVarCopyObj 04 FLdRfVar f5 LitI4: 3a LitVarStr: 4e FStVarCopyObj 04 FLdRfVar 0a ImpAdCallFPR4: 36 FFreeVar Lead1/c8 End 13 ExitProcHresult

local_00AC local_00CC local_00EC local_010C 401e8c 401e8c

( local_00BC ) P-Code local_00CC local_00CC 0x30 48 (...0) ( local_009C ) Clave Correcta!! local_00AC local_00AC _rtcMsgBox local_00AC local_00CC local_00EC local_010C

Bueno all esta claro todo el trabajo del crackme. Es bueno saber hacerlo con OLLY, porque hay programas que se protegen contra el WKT contra el EXDEC y al menos con OLLY siempre podremos mientras el programa corra en el mismo, lo cual como ya vimos con los plugins que hay para ocultar OLLYDBG, es bastante sencillo salvo muy contadas excepciones. Tomemos el crackme adjunto nags1 que nos pide eliminar la nag inicial, veamos su listado en EXDEC.

Proc: 401a40 401A14: 27 LitVar_Missing 401A17: 27 LitVar_Missing 401A1A: 27 LitVar_Missing 401A1D: f5 LitI4: 0x0 0 (....) 401A22: 3a LitVarStr: ( local_0094 ) NAG 401A27: 4e FStVarCopyObj local_00A4 401A2A: 04 FLdRfVar local_00A4 401A2D: 0a ImpAdCallFPR4: _rtcMsgBox 401A32: 36 FFreeVar local_00A4 local_00C4 local_00E4 local_0104 401A3D: 13 ExitProcHresult

Proc: 401958 401954: Lead1/c8 End 401956: 13 ExitProcHresult

Vemos que la famosa NAG es solo un rtcMsgBox pero por si no saben aqu en PCODE no existe el NOP, jeje asi que hay que nopear con OPCODES que no afecten el resto del programa,

Arranco el programa voy a poner un BPM en el opcode al rtcMsgBox 401A2D: 0a ImpAdCallFPR4: _rtcMsgBox

Ali para cuando lee el opcode

Vemos que el stack esta en 12f9e8, lleguemos hasta el otro opcode por supuesto saldr la nag que tendremos que aceptar antes de llegar al siguiente opcode.

All llego al siguiente opcode luego de pasar por el CALL EAX que es la llamada a la api rtcMsgBox. El stack esta ahora en 12f9fc

O sea para que quede igual deberamos hacer varios pops y no nos cabe alli, pues probaremos con un PUSH solo usaremos f5. F5 5CBE 1377 4 1 4 Push imm#4

Ya que tiene 4 parmetros de largo igual que 0A la que vamos a reemplazar 0A 664E 1F30 4 2 2 2 Probemos cambiemos 0A por F5 y pongamos todos los parmetros a cero

All esta el siguiente opcode es el 36 como nos mostraba el EXDEC, siempre debemos fijarnos que el opcode que reemplaza tenga la misma cantidad de parmetros que el que vamos a reemplazar, as no hay problema y seguir ejecutando el siguiente, guardemos los cambios.

All arranca sin la nag inicial, todo es cuestin de probar, quizs en algn caso habr que usar otro opcode diferente para parchear, ahora como ejercicio me gustara que quiten la nag del otro crackme que adjunto el nags2. Y los espero en la parte 31 con el final de PCODE en un programa comercial. Ricardo Narvaja 08 de febrero de 2006