Escogiendo
Números de serie ficticios (MisterE) con apéndice de
Suby
Cuando
crackeas programas que necesitan un Numero de
serie #, yo recomiendo siempre usar el mismo, para
que sepas, que aspecto tiene en
hexadecimal.
Suby:
Yo sugiero usar un numero de serie con caracteres
diferentes como "1234567890" (uno
que yo uso) porque si el programa no verifica
los caracteres del primero al último pero
verifica el tercero y el segundo después el
último etc. puedes saber fácilmente cuál se
verifica.
Si usas "1122334455" y tomara el
"1" no sabes si toma el primero o el
segundo en cambio si usas "1234567890"
y toma "2" estás seguro que
verificará el segundo carácter del numero de
serie. |
Llamadas (CrackZ)
Siempre
que elijas caminar sobre una LLAMADA en una
protección, verifica los contenidos de cualquier
registro que haya cambiado, puedes encontrar el
numero de serie # allí, alternativamente cuando
has agotado todas las posibilidades, has
re-rastreado tus pasos y has examinado las
funciones. |
Cómo piensa un Cracker/Programador (rudeboy)
Se
enseña a los programadores que siempre que
tengas una tarea que va a ser hecha más de una
vez, debes crear una función para hacer esa
tarea, y simplemente llamar a la función cuando
necesitas realizar la tarea. Ahora, la mayoría
de programas que usan una combinación de
nombre/serial # verifican por lo menos dos veces
el código, una vez cuando entras en el código,
y otra vez cuando el programa se pone en marcha.
Debido a esto el programador llamará normalmente
una función para probar tu código de reg. Y
normalmente, esta función se llamará cada vez
que el código se verifica. A estas alturas
probablemente debes ver a donde voy con esto. Si
remiendas la función que se llama para probar el
código de reg, lo mostrará como válido siempre
que el programa haga que se verifique.
Las técnicas empleadas aquí no sólo se aplican
para crackear los programas con rutinas de
código de nombre/reg. No te limites pensando
"Dentro de la Caja", estas técnicas
también pueden usarse con muchos otros tipos de
protecciones (por ejemplo, muchas veces
una comprobación de fecha y una nag screen están
hechas a través de una función) . |
Usando INT 3 (josephCo)
En
caso de que no lo hayas oído ya, INT 3 se puso
para los propósitos de "debugging".
Así si quieres romper una rutina especificada,
puedes usar esta instrucción. Puedes simplemente
"parchear" (el código op para INT 3
es simplemente CC) una COPIA del
archivo. Intenta reemplazar un solo byte del
código op con CC. Si no puedes encontrar uno,
tienes que ponerlo dentro de una instrucción
completa: no te olvides de "NOPear" (el
código op para NOP es simplemente 90) los
bytes restantes. Entonces puedes utilizar SoftICE
para romper en INT 3. No te olvides de anotar los
datos originales, porque los necesitarás cuando
SoftICE rompa en esta dirección. Cuando estás
allí (antes de que INT 3 sea ejecutado),
teclea A y entonces introduce los comandos
anotados - si no haces esto, causarás un Error
de Protección General. Simplemente continúa
como quieras para... |
Valores de retorno
Cuando
una función devuelve un valor para ver si un
control ha tenido éxito principalmente 1 (o a
veces 0) indicará éxito. -1 normalmente es
usado para indicar ¡NO ÉXITO! |
SoftICE breakpoints condicionales (Rhayader)
En
mi temprana experiencia en cracking, yo ponía
normalmente un BPX para GetDlgItemTextA y
GetWindowTextA dentro de SoftICE, siempre que
encontrara un programa que pidiese un numero de
serie. Introduciendo un código ficticio, y '
esperando' a que SoftICE rompiese. La mayoría de
las veces funcionaba. El problema es que,
después de apretar F12 (P RET),
normalmente me pierdo dentro del código.
Preguntándome en que lugar del sangriento texto
del buffer puedo poner un BPR.
Después de excavar en los docs de SoftICE,
finalmente encontré una manera mejor de hacerlo (está
en el Capítulo 7 de la Guía del Usuario).
En mi opinión, debes leerlo también. Algunos de
los términos podría ser difíciles de entender
si simplemente estas empezado. Pero, eh, para eso
está El Foro , ¿no?
:)
Mi
objetivo aquí es conseguir que SoftICE nos
muestre el texto del buffer para los dos APIs
Win32 arriba indicados. Usaré breakpoint
"acción" para hacer eso.
Echemos una mirada primero a GetWindowTextA. Es
declarado como:
int GetWindowText(HWND hWnd, LPTSTR lpString, int
nMaxCount);
GetWindowText usa un convenio de llamada stdcall.
Eso significa que ese argumento se empujará de
derecha a izquierda. Puesto que SoftIce rompe
antes de que el código prólogo sea ejecutado,
el marco de pila EBP todavía no está preparado.
Así que nosotros tendremos que utilizar ESP para
el direccionar el argumento. Aquí es cómo la
pila parecerá cuando SoftIce rompa:
...
[ESP+0Ch] - nMaxCount
[ESP+08h] - lpString
[ESP+04h] - hwnd
[ESP+00h] - return EIP
Cuando el retorno de la función, GetWindowTextA
ponga el texto recuperado para la situación
apuntada por lpString (LPTSTR es un puntero
largo para un string terminado nulo).
Así, tendremos que usar el operador indirecto de
SoftICE (es el carácter * , igual que en el
lenguaje C, ve Capítulo 8;). Por ejemplo, el
comando:
D *(esp+8)
significa, "muestra en la ventana de datos,
la situación apuntada por el contenido de
esp+8." Ya que, esto es un funcionamiento
muy común, SoftICE tenía un comando para él:
esp->8. Bien entonces, ahora podemos poner el
breakpoint como esto:
BPX GetWindowTextA DO "D esp->8;"
Y cuando apretemos F12, volvemos al llamador y el
texto en el que nosotros entramos se sentará muy
bien en la parte superior de la ventana de datos,
esperando a que preparemos un BPR con él:) ¿Por
qué no hacemos automáticamente un retorno al
llamador? Bien, en mi caso, la pantalla parpadea,
y yo lo odio.
Pero, si quieres intentar, puedes poner el
breakpoint como:
BPX GetWindowTextA DO "D esp->8;P
RET;"
Ahora, echemos una mirada a GetDlgItemTextA. Es
declarado como:
UINT GetDlgItemText(HWND hDlg, int nIDDlgItem,
LPTSTR lpString, int nMaxCount);
La única diferencia es nIDDlgItem que es el ID
del control para conseguir el texto. La pila se
parecerá a:
...
[ESP+10h] - nMaxCount
[ESP+0Ch] - lpString < Aquí está
[ESP+08h] - nIDDlgItem
[ESP+04h] - hwnd
[ESP+00h] - return EIP
Y el breakpoint para poner (realmente siento que
ya lo descubres;)
BPX GetDlgItemTextA DO "D esp->C;"
Bien, eso es todos amigos. Si no quieres
teclearlo todas las veces que quieras usarlo,
entonces tendrás que preparar un macro para él.
Lee el capítulo 11 :D Me gustaría decírtelo,
pero esto ya se volvió un correo muy laaargo.
Mira ya...
|
Tip para NUEVOS Ingenieros Inversos (CrackZ)
Cuando
estas empezando a invertir el código de un
blanco puede ser muy tentador usar una variedad
de técnicas intrusivas inmediatamente, yo por mi
estoy ansioso de disparar SoftICE y comenzar el
trazado. En la mayoría casos este acercamiento
funcionará, pero para invertir a un nivel
superior quizás debas emprender un análisis del
código previamente a usar SoftICE - harías bien
para sentir el código antes de entrar en SoftICE
e intentar estudiar la protección en detalle.
Usando WDasm32 fácilmente localizarán algunas
Referencias de String interesantes. Por un simple
trazado atrás podrías fácilmente localizar un
chequeo decisivo. |
Unregistred? (CbD)
Si
crackeas un programa y dice unregistred,
cambiaste un jmp aquí y allí e hiciste que el
programa tomase un código inválido como uno
real pero el programa escribió tu código al
registro o a un archivo ini cuando lo
reiniciaste, él leyó el número o clave y era
uno inválido, así que debes encontrar donde el
programa busca una entrada de registro (RegQueryValueEx[A]
o un GetPrivateProfile[A]) y obliga al
programa validar cualquier clave que vea. Esto
puede ser un proceso muy difícil así que estate
preparado para un infierno. Pero la mejor idea es
usar W32DASM para desmontar el blanco entonces
mira en las funciones importadas para encontrar
las funciones anteriores, entonces rastrea cada
una de ellas (será muchas) entonces
después de que rastreas el código y encuentras
la correcta probablemente será una cuestión de
cambiar un jnz a jz o algo así de simple. Si
todavía no puedes hacerlo busca la ayuda de un
cracker sabio. |
Relojes (Mammon)
Los
relojes permiten rastrear una variable mientras
estás "debuggeando" un programa; es
innecesario decir, que esto es una función muy
importante para el cracking y la ingeniería
inversa. Para abrir la ventana de reloj, teclea
ww en la línea de comandos de Soft-Ice;
tecleando watch seguido por un nombre de variable
(ej. watch user_id) agrega esa variable (y
su valor) a la ventana de reloj. Registros y
offsets de pila (para no mencionar valores de
memoria) pueden ser mirados usándolos en
lugar del nombre de la variable, como watch es:di
y watch [ebp 18]. Además, puesto que muchos
registros y offsets de pila son meramente el
punto para dirigirse donde las variables reales
se guardan, puedes mirar el valor de referencia
por el registro u offset de pila tecleando un *
antes del nombre del registro/offset (eg, watch
*es:di). Buenas variables para watch son es:di,
*es:di, eax, y cualquier [esp?] o [ebp?] aquellas
referencias introducidas por un usuario. |
|