| ESTUDIO COLECTIVO DE DESPROTECCIONES Última Actualizacion: 25/10/2001 |
Programa | G6 FTP Server v2.0 beta 7 | W95 / W98 / NT
Descripción | Este software nos permite montar un servidor FTP en nuestra máquina.
Tipo | Limitación de 5 downloads y 5 uploads
Tipo de Tutorial | [X]Original, []Adaptación, []Aplicación, []Traducción
Url | Desconocida
Protección | Limitado el número de downloads y uploads
Dificultad | 1) Principiante, 2) Amateur, 3) Aficionado, 4) Profesional, 5) Especialista
Herramientas | SoftIce v4, W32dasm v8.9, ProcDump, UltraEdit, Topo v1.1
Objetivo | Eliminar las limitaciones mediante el parcheado del código en tiempo de ejecución.
Cracker | Black Fenix
Grupo | http://kickme.to/wkt
Fecha | Noviembre del 2000
INTRODUCCION
En este tutorial vamos a tratar un programa llamado G6 FTP Server. El programa en cuestión nos permite crear un servidor FTP en nuestra máquina. La limitación es la siguiente: tan solo podemos bajar o subir (upload y download) un máximo de 5 archivos a la vez, como podrás deducir esto es un gran inconveniente ya que normalmente se necesitan transferir todos los archivos de golpe y esperar a que termine la transferencia.
AL ATAQUE
El primer paso a dar antes de iniciar la sesión es examinar la cobaya y familiarizarse con su entorno. Deberemos crear un usuario preferiblemente con permisos de lectura y escritura (para probar los uploads), darle acceso a un directorio de nuestra máquina y posteriormente ejecutar un programa de FTP para conectarnos (notese que conectamos a nuestra misma máquina ). Para conectarnos usaremos como dirección IP la 127.0.0.1 (correspondiente a nuestra maquina ya que es local) o el nombre de nuestro PC, introduciremos el nombre del usuario y el password que le hubieramos asignado. Ahora probamos a realizar una transferencia de más de 5 archivos al directorio de nuestro servidor (que es nuestra misma máquina). Veremos que se transferirán un máximo de 5 archivos y luego aparecerá un mensaje en nuestro programa de FTP que dice algo así: Unregistered version limited to 5 uploads... Ya tenemos algo, una cadena ahora podriamos intentar desensamblar el ejecutable del programa (G6FTPSrv.exe) pero grata es nuestra sorpresa al ver como no hay tabla de importación ni referencias a cadena. Esto solo puede significar una cosa: el ejecutable está comprimido. Para corroborar este hecho tan solo debemos usar alguna aplicación que identifique los ejecutables (gtw p. ej), pero si conocemos los nombres de los compresores más habituales podremos realizar esta comprobación manualmente. Tan solo necesitamos un editor hexadecimal. Abrimos el ejecutable con el editor y hechamos un vistazo a la cabezera del EXE, vemos que es de Windows (debido a la marca 'PE' Portable Executable) que hay en el offset 100h, si hechamos un vistazo más abajo veremos la cadena UPX repetida varias veces (estos nombres correspondes a los nombres de las secciones del ejecutable), normalmente los ejecutables tienen los siguientes nombres para sus direferentes secciones: .code o .text -> En estas secciónes se encuentra el código ejecutable del programa .idata -> Aquí esta la tabla de importación .rsrc -> Aquí están los recursos de la aplicación (iconos bitmaps y demás) .data -> Aquí están los datos usados por la aplicación (variables etc.) .reloc -> Información para la reubicación del ejecutable (casi siempre en las DLLs) Podemos ver que el nombre UPX no es de los que se usan normalmente. Con toda seguridad podemos afirmar que este archivo esta comprimido con el compresor UPX (un compresor bastante utilizado ultimamente). Llegados a este punto se nos plantea un problema, ¿cómo hacemos para desempaquetar todo el ejecutable?, pues tenemos varias opciones: A) Utilizar el ProcDump (esto es un volcador de procesos) B) Volcar el ejecutable sección a sección y recomponerlo. Yo he elegido la opción A porque el tipo de parche que voy a crear no necesita que exista un EXE desempaquetado totalmente funcional. Lo que voy ha hacer es un injerto de código mediante la creación de una nueva sección que es la opción que mejor me ha funcionado en estos casos (digo esto personalmente). La opción B tiene sentido cuando lo que queremos es reconstruir el EXE original y modificar grandes porciones de código, pero esto a veces resulta muy complicado y normalmente mis experiencias con la opción B producen ejecutables se cuelgan más que una percha ;) y creo que es debido a mi limitado conocimiento sobre la estructura de los PE :(. Pues primero ejecutamos el G6 FTP Server y cuando haya arrancado cargamos el Procdump, nos situamos sobre la ventana donde se encuentran las tareas (Task) y nos desplazaremos hacia abajo hasta que veamos al G6 FTP Server (ver Foto 1) Foto 1 Ahora hacemos click con el botón derecho del ratón y seleccionamos Dump Full. Ahora ProcDump nos pedirá donde queremos guardar el volcado, lo guardaremos en el mismo directorio del G6 FTP Server pero con el nombre G6UPX.exe. Saldremos del G6 FTP server y del ProcDump.Lo que tenemos ahora es una imagen del ejecutable que se encontraba en memória pero resulta que esta imagen no es funcional, es decir si probamos a ejecutar el archivo volcado (G6UPX.exe) Windows nos dirá que ha ejecutado una operación no válida y bla.. bla.... La explicación a esto es muy simple: La imagen es correcta pero no la estructura que la define, me explico: La cabezera del ejecutable volcado pertenece a la cabezera del ejecutable comprimido, por lo que el punto de entrada de la aplicación (a partir de donde se empieza a ejecutar código) no es correcto ya que ahora el código que realizaba la descompresión continua ejecutandose cuando no debería. También sucede que la tabla de importación original haya sido alterada por el compresor UPX y no sea correcta. De todas maneras lo único que necesitamos es el código (death listing) y que las referencias a cadenas existan. Pues adelante, desensamblamos el ejecutable (G6UPX.exe) con el W32Dasm y vemos que efectivamente tenemos el icono de las referencias a cadenas activo, pulsamos sobre este icono para buscar la cadena 'Unregistered Version...' y resulta que por mucho que busquemos no la encontramos, parece que el programador fue listo y la ocultó bien, pero quizás la haya encriptado (no es así ya que podemos encontrarla con un editor hexadecimal) o es probable que no incluyera esta cadena en la tabla de referencias, desconozco si lo hizo aposta o por accidente :) . Pues ahora si que nos han jodido, todo esto para nada. Pero un momento, si miramos en la lista de referencias a cadenas veremos que hay una referencia a la cadena suelta 'Unregistered', está cadena es la que nos aparece al entrar al program G6 FTP Server y hacer click en el menu Help/About. Si hacemos doble click sobre esta veremos que el W32Dasm nos lleva a un código tal que así.
:004CAA29 | 8BC3 | mov eax, ebx |
:004CAA2B | E8489DF6FF | call 00434778 |
:004CAA30 | A120365000 | mov eax, dword ptr [00503620] | // Carga un valor
:004CAA35 | 803800 | cmp byte ptr [eax], 00 | // Y mira si el valor apuntado en esa dirección es igual a 0
:004CAA38 | 7415 | je 004CAA4F | // Si es así salta abajo, no registrado (haz click en el hipervinculo)
:004CAA3A | 8B1520385000 | mov edx, dword ptr [00503820] | // Esta registrado, continua la ejecución
:004CAA40 | 8B12 | mov edx, dword ptr [edx] |
:004CAA42 | 8B8320030000 | mov eax, dword ptr [ebx+00000320] |
:004CAA48 | E847A5F6FF | call 00434F94 |
:004CAA4D | EB10 | jmp 004CAA5F |
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004CAA38(C)
* Possible StringData Ref from Data Obj ->"Unregistered"
:004CAA4F | BAC4AA4C00 | mov edx, 004CAAC4 | // Aquí se hace referencia a la cadena Unregistered
:004CAA54 | 8B8320030000 | mov eax, dword ptr [ebx+00000320] |
:004CAA5A | E835A5F6FF | call 00434F94
Un ligero examen de este código nos revela que es posible que se este utilizando un flag global (TRUE o FALSE -> 1 o 0) si el programa esta registrado, tal y como se puede apreciar en la línea 4CAA35 donde se compará una dirección de memoria con 0. En caso de que esto sea cierto tan solo deberiamos averiguar donde está almacenado este flag y modificarlo para que sea igual a 1 (registrado). De momento apuntamos la dirección donde se hace la comparación (4CAA38), lo que vamos ha hacer ahora es establecer un breakpoint (punto de ruptura) sobre está dirección y así averiguar a que dirección de memória está puntando EAX (esta es la dirección de nuestro flag), esto lo haremos usando el ejecutable comprimido (el que funciona). Para poder hacer esto necesitamos parar la ejecución del programa (G6 FTP Server) y establecer el breakpoint cuando estemos ejecutando su código. Un truco consiste en colocar primero un breakpoint sobre alguna función (API de Windows) de inicio de las que usan la mayoría de los programas y luego ir pulsando F12 y G en el SoftIce hasta que veamos el nombre de la aplicación (g6ftpsrv.exe) en la ventana de código del SoftIce. Yo he utilizado un breakpoint en la función GetProcAddress ya que al estar el ejecutable comprimido, este debe usar esta función para cargar las direcciones de las funciones del API necesarias. Pues nada, con el SoftIce cargado pulsar Ctrl+D y teclear BC para borrar los posibles breakpoints que tuvieramos. Ahora ponemos el breakpoint en GetProcAddress con: BPX GetProcAddress, pulsar Ctrl+D de nuevo y ejecutar el G6 FTP Server. Pronto volveremos a la ventana del SoftIce y tras pulsar F12, G,F12,G y F12, apareceremos en el código perteneciente al G6 FTP Server ya que así me lo indica la ventana de código del SoftIce. Ahora colocamos el breakpoint en 4CAA35 tecleando: BPX 4CAA35, desactivamos el breakpoint en GetProcAddress con: BD 0 y pulsamos G para continuar la ejecución del programa. Hacemos click en el menu Help y luego en About, y antes de que aparezca el cuadro de diálogo SoftIce se activará mostrandonos el código que buscabamos (ver listado más arriba). Ahora vamos a ver la dirección donde apunta EAX, para ello teclearemos: ? EAX Obtendremos el valor 50339C, esta es la posición de memória donde se guarda nuestro supuesto flag, si comprobamos su contenido con db *EAX o db 50339C Fijate que uso db ya que el flag tiene un solo byte de tamaño tal y como indica la comparación de la línea 4CAA35. Si observamos la ventana de datos del SoftIce veremos que el primer byte es 0 (que teóricamente significa no registrado). Ahora vamos a relizar la técnica del prueba y a ver que pasa, vamos a modificar el valor de la posición 50339C para que sea igual a 1 (teóricamente registrado). Para hacer esto teclearemos: e 50339C Ahora estamos en la ventana de datos del SoftIce, sobreescribimos el primer byte con 01 y pulsamos ESC para salir de la ventana. Ahora el flag está cambiado, pero antes de continuar con el programa vamos a hacer un seguimiento de los accesos que se realizan sobre la posición 50339C, esto nos permitirá determinar si se hace más de una copia del flag o si este es único. Para ello vamos a usar un breakpoint de memoria (BPM) estos breakpoints están limitados a un máximo de 4 ya que utilizan los registros internos de depuración que se incluyen en los Pentium. Para crear el breakpoint teclearemos: BPM 50339C Ya tenemos el breakpoint activo, ahora cada vez que se intente leer o escribir sobre esta posición, SoftIce se activará. Para continuar la ejecución pulsa G. Veremos que antes de que aparezca el cuadro de diálogo el SoftIce volverá a activarse mostrando el siguiente código:
:004CAA88 | E8CB9CF6FF | call 00434758 | //
:004CAA8D | A120365000 | mov eax, dword ptr [00503620] | //
:004CAA92 | 803800 | cmp byte ptr [eax], 00 | // ESTAMOS AQUÍ, comparamos el flag
:004CAA95 | 7511 | jne 004CAAA8 | // si el flag no es 0 salta ya que estamos registrados
:004CAA97 | 66BAEBFF | mov dx, FFEB | // no estamos registrados, flag = 0
:004CAA9B | 8B8320030000 | mov eax, dword ptr [ebx+00000320] | //
:004CAAA1 | E8AEA6F6FF | call 00435154 | //
:004CAAA6 | EB0D | jmp 004CAAB5 | //
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004CAA95(C)
:004CAAA8 | 33D2 | xor edx, edx | // OK estamos registrados
:004CAAAA | 8B8320030000 | mov eax, dword ptr [ebx+00000320] | //
:004CAAB0 | E89FA6F6FF | call 00435154
Como puedes comprobar se vuelve a comparar el flag de 50339C, pero esta vez el salto es a la inversa es un JNE en vez de un JE. Esto nos indica que vamos por el buen camino ya que el salto se tomará cuando el flag sea <>0 tal y como nosotros lo hemos modificado :) , continuamos la ejecución del programa sin tocar nada pulsando G. Nos aparecerá el cuadro de dialogo y veremos que pone registered to: y no saldrá ningún nombre. Pulsamos el botón OK y salimos del cuadro de diálogo. Ahora vamos a probar a hacer una transferencia de más de 5 archivos, para comprobar si el flag con el que estamos jugando se utiliza antes de transferir los archivos, es de lógica suponer que si, ya que si estamos registrados no deberá comprobar el número de archivos que estamos transfiriendo y si no estamos registrados si deberá comprobar el número de archivos a transferir. Pues probamos, conectamos con el programa de FTP y veremos que aparecerá de nuevo SoftIce mostrandonos lo siguiente:
:004BE18A | A120365000 | mov eax, dword ptr [00503620] | // Carga puntero el flag (50339C)
:004BE18F | 803800 | cmp byte ptr [eax], 00 | // Comprueba el valor del flag
:004BE192 | 754B | jne 004BE1DF | // Si es <> 0, salta el usuario está registrado
:004BE194 | 68C8F04B00 | push 004BF0C8 | // Lo siguiente muestra un mensaje por el og del G6 FTP
:004BE199 | A1183A5000 | mov eax, dword ptr [00503A18] | // indicandonos que no estamos registrados.
:004BE19E | FFB0C4000000 | push dword ptr [eax+000000C4] |
:004BE1A4 | 68D8F04B00 | push 004BF0D8 |
:004BE1A9 | FF35F8305000 | push dword ptr [005030F8] |
:004BE1AF | 8D85C0FEFFFF | lea eax, dword ptr [ebp+FFFFFEC0] |
:004BE1B5 | BA04000000 | mov edx, 00000004 |
:004BE1BA | E8A95EF4FF | call 00404068 |
:004BE1BF | 8B8DC0FEFFFF | mov ecx, dword ptr [ebp+FFFFFEC0] |
:004BE1C5 | A158365000 | mov eax, dword ptr [00503658] |
:004BE1CA | 8B00 | mov eax, dword ptr [eax] |
:004BE1CC | 8B80D0020000 | mov eax, dword ptr [eax+000002D0] |
:004BE1D2 | 8B55FC | mov edx, dword ptr [ebp-04] |
:004BE1D5 | E8BAC8FCFF | call 0048AA94 |
:004BE1DA | E97F070000 | jmp 004BE95E | // Salto incondicional que nos aleja
:004BE1DF | 807DCC00 | cmp byte ptr [ebp-34], 00 |
:004BE1E3 | 747E | je 004BE263
Como vemos se está realizando un test al efectuar la conexión al servidor, esta comprobación la realiza para mostrarnos un mensaje en el log del G6 FTP Server que nos recuerda que la versión no registrada esta limitada a 5 uploads y 5 downloads. Ahora podemos estar más seguros de que andamos por el buen camino. Vamos a continuar la ejecución del programa pulsando G . Ahora vamos a hacer un upload de 6 o 7 archivos al FTP. Veremos que antes de iniciarse la transferencia SoftIce vuelve a activarse de nuevo mostrandonos lo siguiente.
:004E5D2D | 8BB7D8050000 | mov esi, dword ptr [edi+000005D8] | //
:004E5D33 | 803D9C33500000 | cmp byte ptr [0050339C], 00 | // compara el flag directamente
:004E5D3A | 754F | jne 004E5D8B | // salta abajo si estamos registrados flag <>0
:004E5D3C | 83BEEC00000000 | cmp dword ptr [esi+000000EC], 00000000
:004E5D43 | 750B | jne 004E5D50
:004E5D45 | 83BEE800000005 | cmp dword ptr [esi+000000E8], 00000005 | // Comprueba el número de fichero transferidos
:004E5D4C | 723D | jb 004E5D8B | // si es menos que cinco SALTA y continua la transferencia
:004E5D4E | EB02 | jmp 004E5D52 | // salto incondicional para terminar la transferencia
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004E5D43(C)
:004E5D50 | 7C39 | jl 004E5D8B |
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004E5D4E(U)
:004E5D52 | C60300 | mov byte ptr [ebx], 00 | // pone un flag a 0 si hemos terminado
:004E5D55 | 8D858CFEFFFF | lea eax, dword ptr [ebp+FFFFFE8C]
El análisis de este código nos revela que efectivamente el flag que hemos estado espiando es la clave del asunto, siempre que la conexión continue se termina saltando a la dirección 4E5D8B y cuando termina siempre se pasa por 4E5D52. Apartir de aquí el camino está claro, hacer que el valor en 50339C siempre sea <>0 (en mi ejemplo 1). Si continuamos la ejecución del programa veremos que se transferiran todos y cada uno de los archivos que hubieramos seleccionado ya que antes habiamos cambiado el flag a 1. La cuestión ahora es cómo conseguir que el valor en 50339C sea siempre igual a 1. Pues como bien he dicho antes, mediante un injerto de código en el ejecutable original. Teóricamente no podemos alterar el código para invertir los saltos ya que el código no existe hasta que se descomprime, pero la solución es más sencilla. Todo ejecutable comprimido debe de descomprimirse, y en algún punto cuando la descompresión finaliza se debe de saltar al punto de entrada original del programa. La solución es buscar este punto (donde se salta al punto de entrada original), sustituir el salto allí presente por un salto a la dirección donde coloquemos nuestro código, que debería ser algo así:: mov byte ptr [50339C], 01 y después realizar el salto al punto de entrada original con algo así: jmp dirección_punto_entrada_original El problema es que para realizar esto deberemos de disponer de espacio adicional en la sección donde se encuentre el codigo de descompresión, o en su defecto deberemos crear una sección donde colocar nuestro código. Pero antes de continuar vamos a buscar el punto de entrada del ejecutable original, para ello deberemos desensamblar el EXE comprimido (G6FTPSrv.EXE) con el W32Dasm e ir a su punto de entrada haciendo click en el menu Goto/Program EntryPoint. Veremos algo así:
:00586A70 | 60 | pushad | // guarda los registros en la pila
:00586A71 | BE00305200 | mov esi, 00523000 | //
:00586A76 | 8DBE00E0EDFF | lea edi, dword ptr [esi+FFEDE000] | //
:00586A7C | 57 | push edi | //
:00586A7D | 83CDFF | or ebp, FFFFFFFF | //
:00586A80 | EB10 | jmp 00586A92 | // salta
:00586A82 | 90 | nop
:00586A83 | 90 | nop
:00586A84 | 90 | nop
:00586A85 | 90 | nop
:00586A86 | 90 | nop
:00586A87 | 90 | nop
La primera instrucción que nos encontramos es muy típica en los compresores de ejecutables ya que estos normalmente guardan el estado del programa al iniciarse y luego lo restauran antes de pasar el control al programa descomprimido. Esto quiere decir que seguramente la rutina de descompresión del UPX usará la instrucción inversa a pushad (popad) para volver a obtener los valores originales de los registros. Por lo tanto vamos a buscar esta instrucción en el código que nos muestra el W32DAsm, iremos bajando poco a poco hasta llegar a:
:00586BCC | FF96947B1800 | call dword ptr [esi+00187B94] | //
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00586B94(C)
:00586BD2 | 61 | popad | // Sacamos los registros de la pila
:00586BD3 | E9E8A5F7FF | jmp 005011C0 | // y saltamos al punto de entrada original
:00586BD8 | F06B5800 | DWORD 00586BF0 | // Esto son bytes sobrantes de la sección
:00586BDC | 006C5800 | DWORD 00586C00 | //
:00586BE0 | D444 | aam (base68) | // e intrucciones que nunca se ejecutarán
:00586BE2 | 50 | push eax
Como podemos observar la teória a sido correcta en este caso. lo cual no quiere decir que lo vaya a ser siempre, ya que se hubieran podido sacar los registros de manera manual, pero esta es la manera más fácil (así es como piensan los programadores), por lo tanto tenemos que el punto de entrada original esta en 5011C0, vemos que nos sobran unos cuantos bytes para poder hacer nuestras modificaciones. Si nos fijamos en la barra de estado del W32Dasm veremos que el desplazamiento (offset) dentro del archivo para la instrucción jmp 5011C0 está la posición 63FD3. Vamos a ver que sección comienza a partir de de esta posición. Esto puede comprobarse mediante el ProcDump. Abrimos el ProcDump, click en PE Editor, seleccionamos el EXE comprimido y hacemos click en sections. Vemos tres secciones UPX0, UPX1 y .rsrc lo que estamos buscando es el inicio de cada sección dentro del archivo y esto ProcDump lo llama "Raw Offset", vemos que las dos secciones UPX comienzan en el mismo offset y que la .rsrc comienza en el offset 64000. Por lo tanto sabemos que despues del salto habra un espacio equivalente a 64000-63FD3 = 2D -> 45 bytes no utilizados, suficiente para añadir nuestro injerto. Pero resulta que este espacio es utilizado por el UPX y si lo utilizasemos el ejecutable no funcionaría (lo he probado y me daba un error de memoría insuficiente). La cosa se complica bastante ya que ahora necesitamos un espacio adicional que no tenemos y para poder conseguirlo la única solución es crear una nueva sección en el ejecutable. La cosa sería bastante complicada de hacer a mano por lo que yo he utilizado el programa Topo v1.1 (gracias a Mr. Crimson de WKT) para crear una nueva sección de 16 bytes de longitud, suficiente para nuestros propósitos. Después de crear la nueva sección con el Topo, este nos dirá la dirección Virtual de inicio (en mi caso 589000) y el offset dentro del ejecutable (en mi caso 65E00). La cosa ahora es un poco más complicada ya que primero deberemos cambiar el salto en 568BD3 (JMP 5011C0) por JMP 589000 que es donde empieza nuestra nueva sección, a partir de esta dirección ensamblaremos las siguientes instrucciones. mov byte ptr [50339C], 01 // pone flag de registro a TRUE jmp 5011C0 // Salta al punto de entrada original Tal y como se puede apreciar primero se establece el flag de registro y luego se salta al punto de entrada original. Ahora tenemos que averiguar que opcodes corresponden a estas instrucciones. Nada más sencillo que utilizar el SoftIce para realizar las modificaciones y desde allí copiar los opcodes generados. Para realizar esto necesitamos parar de nuevo la ejecución del programa tal y como hicimos anteriormente unsando un BPX en GetProcAddress. Repetimos el proceso y cuando estemos en la ventana de SoftIce colocamos un breakpoint sobre la dirección donde se encuentra el salto al punto de entrada original, con: BPX 586BD3 Antes de continuar si nos fijamos veremos que al volver de la función GetProcAddress, el código en el cual nos hayamos está cerca de la dirección 586BD3 e incluso podremos ver el salto en la ventana de código del SoftIce, esto es debido, a que como dije anteriormente el UPX carga las direcciones de todas las funciones del API que usa el programa una vez ha descomprimido las secciones, concretamente estamos en el bucle que se encarga de esto.Pues nada, desactivamos el breakpoint que teniamos sobre GetProcAddres con BC 0 y continuamos la ejecución con pulsando G. SoftIce volverá activarse y estaremos sobre la línea de código 586BD3, el salto que buscabamos. Ahora vamos a modificar el código para añadir nuestro injerto. Tecleamos: A 586BD3 Esto entrará en el ensamblador en línea del SoftIce y nos permitira introducir nuestro código sobre la dirección 586BD3. Ahora teclearemos cada una de las instrucciones seguidas de un intro y al finalizar pulsaremos ESC. jmp 589000 + Intro Ya tenemos el código modificado, ahora vamos a ver cuales son los opcodes correspondientes, pare ello volcaremos el código como si de datos se tratara con: d 586BD3 Ahora veremos que en la ventana de datos nos aparecen los opcodes que deben ser tal que así: E9 28 24 00 00 Sabemos que son 5 ya que es la resta entre la dirección 586BD3 (donde empieza nuestro código) y la dirección donde empieza la instrucción siguiente al salto jmp (586BD8). Pues vale, los copiamos para posteriormente modificar el ejecutable.Ahora podemos tomar el salto pulsando F8 una vez, ahora estaremos sobre la direcciíon 589000 y veremos que donde debería haber códigos de operación solo hay 'INVALID', esto es debido a que hemos saltado a una sección diferente y al SoftIce no le ha dado tiempo de procesar los opcodes, pulsaremos F8 de nuevo y veremos que se ejecutará un NOP (esto es debido a que el Topo rellena la sección con este código de operación por defecto), ahora comenzaremos a ensamblar las instrucciones. A 589000 Esto entrará en el ensamblador en línea del SoftIce y nos permitira introducir nuestro código sobre la dirección 586BD3. Ahora teclearemos cada una de las instrucciones seguidas de un intro y al finalizar pulsaremos ESC. mov byte ptr [50339c],1 + Intro jmp 5011c0 + Intro + ESC Ya tenemos el código modificado, ahora vamos a ver cuales son los opcodes correspondientes, pare ello volcaremos el código como si de datos se tratara con: d 589000 Ahora veremos que en la ventana de datos nos aparecen los opcodes que deben ser tal que así: 90 C6 05 9C 33 50 00 01 E9 B3 81 F7 FF Podemos comprobar que el NOP (90) inicial está incluido, por lo que ya nos va bien. Ahora podemos continuar con la ejecución y veremos que ya no tenemos limitación de upload y downloads. Resumiendo ya tenemos los datos necesarios para modificar el ejecutable. En el offset 65E00 (obtenido con el Topo) deberemos escribir con el editor hexadecimal: 90 C6 05 9C 33 50 00 01 E9 B3 81 F7 FF -> Que corresponde al NOP y al MOV BYTE PTR [50339C],1 En el offset 63FD3 (obtenido con el W32Dasm ) deberemos escribir con el editor hexadecimal: E9 28 24 00 00 -> Que corresponde al jmp 589000 y podremos comprobar que ya no tenemos limitación ninguna de uploads ni de downloads. Ya tenemos el offset donde aplicar el parche y los datos a cambiar, por último solo queda hacer el parche para que la modificación sobre el ejecutable sea definitiva. Para ello recomiendo utilizar el WinPatch ya que el archivo parcheado es más grande que el original. También existe otra solución más sencilla que es utilizar un parcheador de procesos, yo recomiendo el R!SC Process Patcher, de esta manera no necesitariamos crear ningún parche que modifique el archivo original.
[ Entrada | Documentos Genéricos | WkT! Web Site ]
[ Todo el ECD | x Tipo de Protección | x Fecha de Publicación | x Orden Alfabético ]
(c) Whiskey Kon Tekila [WkT!] - The Original Spanish Reversers. Si necesitas contactar con nosotros , lee esto antes e infórmate de cómo puedes ayudarnos