Professional Documents
Culture Documents
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.
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
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.
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 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.
Que es 2C en mi caso, podemos ver si esta en la lista de handles que esta usando el programa
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.
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.
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.
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
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
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
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.
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
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 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
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
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
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.
Para al inicio del programa cuando instala la direccin donde continuara cuando halle una excepcin.
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
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
Y all guardo al igual que antes el FFFFFFFF de que hay debugger lo cambio a cero
Ahora si saltara
Y si doy RUN
Vemos que ahora si llega a 401108 y mas abajo veo la parte caliente
Al invertir este salto y forzarlo a que no salte, mostrara el mensaje correcto de que el crackme esta solucionado.
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
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.
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
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
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
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.
Veamos el stack
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
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
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.
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
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
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.
Listo continuemos
Demos RUN
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
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
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.
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.
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
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
Ahora el OLLYDBG tiene una opcin para interpretar mejor los parmetros del header, haciendo en el dump, click derecho.
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.
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.
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.
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
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.
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
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
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.
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.
Y doy RUN
En sus maquinas esta direccin puede variar ya que es una seccin creada mientras se ejecuta el programa. Pongamos un BP alli
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.
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
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,
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.
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.
All esta el call a la api y abajo lgico el punto de retorno que es 4032d9.
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.
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.
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
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
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.
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
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.
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.
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.
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
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.
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.
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.
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
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.
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.
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.
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 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.
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.
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.
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.
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.
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
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
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) .
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.
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
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.
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
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.
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.
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
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.
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.
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
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.
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
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.
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.
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 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
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.
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.
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.
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 esta.
Lee los parmetros con MOVSX y como es negativo los completa con FFs
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.
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.
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
Y lo pasa a EDI Luego lee el contenido de EAX que es el inicio de otra tabla
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
Uff costo sangre pero llegamos al punto donde ley el serial falso.
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.
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.
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.
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
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.
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.
Ojo no borro el serial falso, este sigue estando en 15d3bc lo que borro es el puntero al mismo que estaba en EBP-8c.
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.
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.
El prximo OPCODE es
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
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
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
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
Jeje ya sabemos algo pero no se libraran tan fcil de esto, lleguemos a la comparacin.
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.
Lo suma a EBP para hallar EBP-9c que es 12f444 que por ahora esta vaco
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
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
As que para saltear todo lo anterior pongo un BPM ON ACCESS en 401c17, para que pare cuando lea el OPCODE.
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
Y llega al call eax donde EAX vale 401000, veamos donde va, va a la api susodicha.
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
Llego al siguiente OPCODE 401C1C: Lead2/6b CVarR8 Pues all estamos entremos en el opcode
Bueno all hay unos comandos de punto flotante que aun no hemos visto Pero vemos que al inicio esta cargando parmetros
En este caso
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.
All termina el OPCODE 401C20: 5d HardType Bueno este no tengo la ms mnima idea de lo que es pero lo descubriremos
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
Pues uno es un puntero al serial verdadero, otro al falso transformado, ser la comparacin aqu?
Pongamos un BP alli
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
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
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
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.
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 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
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
Y veamos si guardo el serial falso en la variable local que usara 401DFB: 0d VCallHresult 401E00: 3e FLdZeroAd get__ipropTEXTEDIT local_008C
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
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
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
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.
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
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
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.
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 (....) ;
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
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_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
; Convierte a minusculas
(1)
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_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
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
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