Karpoff Spanish Tutor 1999-2001

Programa:

eNotes 1.10 Build 1.1.6.160


 

PROTECCION:

Serial distinto en cada instalación.

Objetivo:

Simular estar registrados.

Descripcion:

Permite escribir notas y pegarlas en el escritorio.

Dificultad:

Aficionado.

DOWNLOAD:

http://www.simtel.net/pub/simtelnet/win95/desktop/enotes11.zip

Herramientas:

Softice, W32dasm, file insPEctor, ProcDump, UltraEdit.

CRACKER:

CaoS ReptantE

  FECHA:

10/09/2001

 

 INTRODUCCION

La verdad, cuando empecé a trabajar este programa lo hice pensando en otro tema del que quizá algún día hablaremos, y no tenía intención de escribir un tuto sobre él, pero según lo iba viendo, me daba cuenta de que era un perfecto cobaya, porque tiene una serie de características que hacen que su estudio resulte instructivo. La verdad es que resulta dudoso que la utilidad del programa por sí sola, justifique los esfuerzos que vamos a realizar, pero lo cierto es que estamos en esto para aprender, no para disfrutar de programas de calidad dudosa sin pagar un céntimo ;-)

 

 AL ATAKE

Empezamos -como siempre- con el SoftIce cargado y ejecutamos el programa, que se va de cabeza a la barra de tareas. Vamos allí y le damos al botón derecho del ratón y vamos a Help/Register. Allí aparece una ventana en la que nos piden nada menos que 25 $ por registrarnos y aparece también un código llamado Serial ID y debajo el recuadro para introducir nuestro serial. Este Serial ID podemos comprobar que varía en cada instalación, con lo cual también variará el serial que deberíamos introducir para registrarnos. No nos preocupemos por eso de momento. Introducimos nuestro serial chungo, ctrl+D para entrar en el SIce, introducimos nuestro breakpoint favorito: bpx hmemcpy, F5 para salir de SIce y OK para registrarnos. Salta el SIce, le damos varias veces a F12 hasta que regresamos al programa en:

:0042C63A 5E                      pop esi

Ahora se trata de buscar mediante la instrucción s 30:00 l ffffffff 'serial_chungo' la posición o posiciones que ocupa en la memoria el número introducido. A continuación, empleando las instrucciones bpm dirección_obtenida r o bpr inicio_dirección_obtenida final_dirección_obtenida r sabremos cuando el programa lee este número para compararlo con el correcto. Una vez hecho esto, le damos a F5 y nos detenemos en varios lugares que no nos llaman la atención, pero de pronto...

:00403F31 8B0E                    mov ecx, dword ptr [esi]
:00403F33 8B1F                    mov ebx, dword ptr [edi]
:00403F35 39D9                    cmp ecx, ebx
:00403F37 7558                    jne 00403F91

¡BIEN! ¡Lo tenemos! En ESI tenemos la dirección de nuestro serial chungo y en EDI la del serial verdadero. Así pues, ya podemos registrarnos. Pero... un momento, ¿no habíamos quedado en que el serial sería distinto a cada instalación? Así, este serial sólo nos sirve a nosotros. ¡No pasa nada! parchearemos el salto. Pero... ¡ay! que poco dura la alegría en la casa del pobre :-( Como ya he dicho, estaba yo investigando otra cosa y en vez de parchear el salto, puse un bpx en 403F31, y me lleve la desagradable sorpresa de ver que el programa se detenía varias veces en este punto comparando cadenas de texto que unas veces eran iguales y otras no. Así que hay que olvidarse de parchear el salto. Está claro que después de esta comparación debe haber otra que nos lleve al éxito o al fracaso. Pero esto debemos verlo en el listado muerto del W32dsam. Antes, vamos a ver que nos dice el file insPEctor...¡Arghhh! empaquetado con Aspack v1.08.04. Bueeeeeeno, vamos a desempacarlo. Ejecutamos el Symbol Loader para tracear con el SIce desde el inicio del programa, cargamos el módulo del programa, le damos a las ruedecitas, le decimos que sí al mensaje de error y... nos encontramos que el programa, sin detenerse para nada, se ha ido a la barra de tareas. Que no cunda el pánico, cerramos el programa, vamos al ProcDump y en PE Editor seleccionamos nuestro programa, después en Sections, nos ponemos sobre la primera (CODE) y le damos al botón derecho del ratón, escogemos Edit Section y vemos que en Section characteristics tenemos el valor C0000040, que cambiamos por E0000020. OK y a la calle.

No tengo muchas ganas de explicar la razón de esto y citaré a nuMIT_or (Descabezando archivos ejecutables portables):
----------------------------------------------------------------
El campo Characteristics indica las propiedades de la sección, es decir, si se trata de código objeto, de datos inicializados o no inicializados, si se puede escribir y leer sobre la sección, si es ejecutable, si es compartible, etc. PROCDUMP llama a este campo "CHARACTERISTICS". A continuación las equivalencias:

      000000020h __Código.
      000000040h __Datos inicializados.
      000000080h __Datos no inicializados.
      040000000h __Sección cacheable.
      080000000h __Sección paginable.
      100000000h __Sección compartida.
      200000000h __Ejecutable.
      400000000h __Se puede leer.
      800000000h __Se puede escribir en la sección.
-----------------------------------------------------------------
Esto quiere decir que teníamos una sección en la que se podía leer y escribir y tenía datos inicializados. Ahora tenemos una sección en la que además de poderse leer y escribir, es ejecutable y contiene código. Repetimos el intento de tracear el programa desde el inicio y ahora sí, el SIce se detiene en:

:004D4001 60                      pushad
:004D4002 E870050000              call 004D4577

A partir de aquí se trata de tracear con F10 y sobre todo con mucha paciencia. Nos encontraremos con un montón de bucles con una estructura similar a esta:

Inicio del bucle.
Instrucciones
...
Salto condicional a siguiente.
Más instrucciones
...
Salto incondicional al inicio del bucle.
siguiente.

El salto al inicio del bucle se reconoce fácilmente porque es un salto hacia atrás. Para ahorrar tiempo y energías, es recomendable ir directamente a la instrucción siguiente mediante un doble click con el ratón o con bpx siguiente o g siguiente.
Finalmente, nuestros esfuerzos se ven recompensados y llegamos al final del proceso:

:004D44F1 61                      popad
:004D44F2 7508                    jne 004D44FC
:004D44F4 B801000000              mov eax, 00000001
:004D44F9 C20C00                  ret 000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D44F2(C)
|
:004D44FC 6848AE4900              push 0049AE48
:004D4501 C3                      ret

¿Y ahora que hacemos? Cuando estemos situados sobre la instrucción PUSH 0049AE48, introducimos la instrucción a eip y seguidamente, tras la dirección de la instrucción, jmp eip. Otra vez RETURN para dejar el ensamblado (veréis que el código 6848AE4900(PUSH 0049AE48) ha sido substituido por EBFE(JMP 4D44FC)) y F5 para que el programa se siga ejecutando. Al seguir ejecutándose, lo que hace es entrar en un bucle infinito, lo cual aprovecharemos para ejecutar el ProcDump, buscar en Task el programa que hemos dejado ejecutándose, y tras clickear encima con el botón derecho del ratón, elegiremos la opción Dump (Full). Le damos el nombre que nos parezca para diferenciarlo del empacado (por ejemplo eDump.exe) y repetimos este último proceso, pero eligiendo la opción Kill task para terminar la ejecución del programa y del interminable bucle.
Ahora tenemos un ejecutable desempaquetado, lo ejecutamos y:
"Este programa ha efectuado una operación no admitida y..." ¿Y ahora que pasa? Que tendremos que dejar como estaba la instrucción que hemos modificado. Vamos a echar mano de un editor hexadecimal y buscaremos "EBFEAE4900" que es lo que ha quedado al superponer a la instrucción PUSH que teníamos, la instrucción JMP. Lo encontramos sin problemas y substituimos "EBFE" por "6848" con lo que volvemos a tener la instrucción original. Volvemos a ejecutar eDump.exe y FUNCIONA :-)
Ahora por fin, podemos desensamblar el programa con el W32Dsam y lo primero que haremos es buscar entre las
String Data References alguna referencia a password incorrecto o algo parecido. Encontramos lo que buscábamos y ello nos conduce a esta parte del programa: 

:0048D415 E8EE6AF7FF              call 00403F08
:0048D41A 7527                    jne 0048D443
:0048D41C A160C64900              mov eax, dword ptr [0049C660]
:0048D421 8B00                    mov eax, dword ptr [eax]
:0048D423 8B4030                  mov eax, dword ptr [eax+30]
:0048D426 8B55FC                  mov edx, dword ptr [ebp-04]
:0048D429 E8BAD6FEFF              call 0047AAE8
:0048D42E 668B0D84D44800          mov cx, word ptr [0048D484]
:0048D435 B202                    mov dl, 02

* Possible StringData Ref from Code Obj ->"Thank you for registering eNotes!"
                                  |
:0048D437 B890D44800              mov eax, 0048D490
:0048D43C E833F1FFFF              call 0048C574
:0048D441 EB13                    jmp 0048D456

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0048D41A(C)
|
:0048D443 668B0D84D44800          mov cx, word ptr [0048D484]
:0048D44A B201                    mov dl, 01

* Possible StringData Ref from Code Obj ->"Registration password is invalid!"
                                  |
:0048D44C B8BCD44800              mov eax, 0048D4BC
:0048D451 E81EF1FFFF              call 0048C574

Si miramos esto con una mínima atención, veremos que la diferencia entre "chico bueno" y "chico malo" está en: 0048D41A  7527  jne 0048D443 ¿Qué os parece si hacemos que nunca salte? para ello podemos substituir 7527 por 9090 o si somos perfeccionistas, por 7500. Pues venga, tomamos nota del offset correspondiente a 48D41A, que es 8CA1A y volvemos al editor. Ya estamos de vuelta. Naturalmente hemos elegido la opción de substituir 27 por 00. Y ahora ejecutamos el programa de nuevo. Introducimos nuestros datos, aparentemente los acepta. Reiniciamos el programa y... ESTAMOS REGISTRADOS. Pues ya está ya hemos terminado. Pero un momento, supongamos que queremos pasarle el parche a un colega para que pueda evaluar el programa con toda tranquilidad ;-) ¿Le vamos a dar un ejecutable de 800 KB? A estas alturas, debemos ser capaces de algo mejor. Vamos a ver que podemos hacer...

Lo ideal sería parchear el ejecutable empaquetado para que cuando se efectúa el salto desde la rutina de desempacado al programa propiamente dicho, no fuera a la dirección de inicio del programa sino a un trocito de código y de allí al inicio del programa. Vamos a desensamblar el programa empacado. Lo desensamblamos con el W32Dsam pero el código desensamblado sólo llega a la posición 43B9FF. Por lo tanto, no aparecen las instrucciones que buscamos, que están a partir de 4D44F1. Hummm... eso debe estar en la sección .aspack. Vamos a probar de cambiar sus características igual que hicimos con la sección CODE. Lo hacemos, y de nuevo en el desensamblador tenemos a la vista el código que necesitamos:

:004D44F1 61                      popad
:004D44F2 7508                    jne 004D44FC
:004D44F4 B801000000              mov eax, 00000001
:004D44F9 C20C00                  ret 000C

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004D44F2(C)
|
:004D44FC 6800000000              push 00000000
:004D4501 C3                      ret

Bueno, esto es casi igual que antes, pero algo falla: el parámetro de la instrucción PUSH que antes era la dirección de inicio del programa desempacado, ahora es 0. Por si alguien se ha perdido, os recuerdo que lo que hemos visto antes era esta zona justo cuando había terminado el desempacado del programa y lo que vemos ahora es el listado muerto o desensamblado del programa antes de ejecutarse. Lo que está claro, es que en algún momento del desempacado, se ponen en la dirección 4D44FD los cuatro bytes que definen la dirección del inicio del programa y que son los que queremos cambiar para dirigirnos al lugar donde pondremos nuestro código. Volvemos al Symbol Loader y ejecutamos de nuevo el programa empaquetado. Cuando el SIce se detiene al principio de la ejecución, introducimos: bpm 4d44fd y le damos a F5. Se detiene el SoftIce y vemos que los cuatro bytes que buscamos se ponen en la instrucción anterior al POPAD y que proceden de EAX.

:004D44DB 8B856A3A4400            mov eax, dword ptr [ebp+00443A6A]
:004D44E1 50                      push eax
:004D44E2 0385F8474400            add eax, dword ptr [ebp+004447F8]
:004D44E8 59                      pop ecx
:004D44E9 0BC9                    or ecx, ecx
:004D44EB 8985953E4400            mov dword ptr [ebp+00443E95], eax

Si miramos las instrucciones anteriores, veremos que hay que poner un bpx 4d44db y volver a empezar para ver donde podemos meter la zarpa :-) Se detiene de nuevo el SIce, podemos ver en la parte superior izquierda, que la dirección EBP + 443A6A corresponde a 4D40D2 y que el valor que hay en ella es 48AE09, por lo que en EAX se coloca el valor 00009AE48 a lo que se suma 00400000. Podemos comprobar que el valor 48AE09 está en esta dirección mirando el listado muerto del programa empaquetado W32dsam:

:004D40D1 0048AE                  add byte ptr [eax-52], cl
:004D40D4 0900                    or dword ptr [eax], eax

Fijaos como el pobrecillo ha tratado de desensamblarlo como parte del código.
Por ahora ya sabemos que podemos cambiar la dirección del salto hacia nuestro código, ahora vamos a buscar un lugar para éste. Un poco más abajo de este punto, encontramos lo siguiente:

:004D41B2 00000000000000000000    BYTE 10 DUP(0)
:004D41BC 00000000000000000000    BYTE 10 DUP(0)

Parece que este lugar es ideal para nosotros. Una manera de confirmarlo es escribir algo de texto en él, ejecutar el programa y durante la ejecución, mirar si el texto existe y está entero. En nuestro caso no hay problema. Si hubiera problemas, lo mejor es usar los ceros que hay siempre en el final de alguna sección. Así pues está decidido que nuestro código va a ir en la dirección 4D41B2. Entonces ¿qué vamos a poner en la posición 4D40D2 en lugar de 48AE09? Debemos poner B2410D. Buscamos en el editor hexa la cadena "0048AE0900" que tenemos arriba y una vez hallada, substituimos 48AE09 por B2410D. ¿Funcionará?
Vamos a comprobarlo. Una vez más, ejecutamos el programa desde el Symbol Loader y ponemos un bpx 4d44db. Se detiene el SIce y BINGO se coloca la dirección correcta, traceamos con F10 y ahora que va a saltar a la zona de ceros es el momento de ensamblar nuestro código. Al llegar a la dirección 4D41B2, tecleamos a eip y a continuación vamos introduciendo instrucciones: push eax / xor eax, eax / mov byte ptr [48d41b], al / jmp 49ae48 / pop eax y finalmente ret. Ahora debemos tomar nota de los códigos generados para introducirlos posteriormente con el editor. Estos códigos son:

50 33 C0 A2 1B D4 48 00 58 E9 88 6C FC FF C3

Los introduciremos en el programa empacado mediante el editor hexadecimal, en el offset correspondiente a la dirección 4D41B2 que podemos calcular o ver en el W32dsam. El resultado es: 449B2. Una vez entrados los datos en el programa, nuestro código queda así:

:004D41B2 50                      push eax
:004D41B3 33C0                    xor eax, eax
:004D41B5 A21BD44800              mov byte ptr [0048D41B], al
:004D41BA 58                      pop eax
:004D41BB E9886CFCFF              jmp 0049AE48
:004D41C0 C3                      ret

Con esto, me parece que queda explicado el procedimiento que hemos seguido para parchear el programa empacado de modo que al desempacarse quedara parcheado y operativo. Si alguna cosa no ha quedado clara, podéis darme un toque. Así terminamos con un programa que en cualquier caso, tiene una característica que lo hace distinto de cualquier otro programa que yo haya visto: que teniendo la clásica estructura de: serial chungo en un registro / serial bueno en otro / comparación entre ambos / salto condicional, no hay que parchear el salto para registrar el programa.

Antes de despedirme quiero recordaros como siempre que debéis pagar los programas que utilicéis regularmente. No hagáis que me avergüence de vosotros ;-)

Finalmente quiero saludar a mis amigos Act MagO, Pr@fEsOr X y ByTESCRK. También a Karpoff, Silver Storm, KuaTo_ThoR, y DeK_OiN.

Si queréis alguna aclaración sobre mis tutos, mi dirección de e-mail es: caos_reptante@hotmail.com

 

Karpoff Spanish Tutor: Pagina dedicada a la divulgacion de informacion en Castellano, sobre Ingenieria Inversa y Programacion. Email "Colabora con tus Proyectos"

www.000webhost.com