Bueno, para que la gente se anime a estudiar el Crackme me he propuesto analizarlo y crear un sencillo Keygen.
Para el keygen, aunque valen muchos caracteres, solo voy a usar números para evitar poner muchas condiciones en el código fuente. Pongo un enlace al final con el código fuente del keygen, el exe del mismo y una copia del crackme por si desapareciera en un futuro.
Carga el crackme en un depurador, yo lo hice con varios, pero para explicarlo lo hago con OllyDBGv2 en W10. Lo primero que llama la atención es que pesa muchísimo para el poco código que lleva, a ver si Flamer nos comenta el porqué.
Encontrar el código es sencillo buscando en las strings: botón dcho > search for > all referenced strings. Así se llega rápido al código.
Explicación del código
00401700 cmp eax,0A
Nos indica que el serial tiene que tener exactamente 10 caracteres:
XXXXXXXXXXEl primer valor, voy a poner uno cualquiera: "1" = 31h
1XXXXXXXXXAquí trabaja con valor1 y valor6:
CPU Disasm
Address Hex dump Command Comments
00401750 |. 83E8 60 sub eax,60
00401753 |. 8945 DC mov dword ptr ss:[ebp-24],eax
00401756 |. 837D DC 08 cmp dword ptr ss:[ebp-24],8
0040175A |. 0F8E 62020000 jle 004019C2
En esa parte hace estas operaciones (todo en HEX):
valor6 + valor1 - 60 > 8; valor6 + 31h - 60h > 8h;
valor6 > 37h; Por lo tanto, valor6 = 38h ("8") o 39h.
1XXXX8XXXXEl valor 2 es un número aleatorio entre 0 y 9. Pongo por ej 7:
17XXX8XXXXUn poco más adelante, empieza a realizar un montón de operaciones con los valores 1, 2, 6 desde 4017E3 hasta 401818. En este ejemplo, poniendo en el depurador el serial anterior, y BP en 401818, el resultado en eax de esas operaciones es: 6
Ahora volvemos a analizar un poco más arriba y verás que resta 30h al valor5 en 4017D7 y la comparación en 401821 compara el 6 del párrafo anterior con esto último:
valor5 = 6 + 30;
valor5 = 36h = "6"
17XX68XXXXvalor3 tiene que ser menor que 33h, mira en:
CPU Disasm
Address Hex dump Command Comments
00401861 |. 837D CC 32 cmp dword ptr ss:[ebp-34],32
00401865 |. 7F 73 jg short 004018DA
valor3 puede ser 32h("2"), 31h("1") o 30h("0")
172X68XXXXvalor4 tiene que ser mayor que 35h, mira en:
CPU Disasm
Address Hex dump Command Comments
00401867 |. 837D C8 35 cmp dword ptr ss:[ebp-38],35
0040186B |. 7E 6D jle short 004018DA
valor4 puede ser 36h, 37h, 38h o 39h.
172668XXXXY los 4 últimos caracteres pueden ser cualquier valor:
172668FORODejo el código fuente que he realizado para el keygen, en Visual C++ 2019:
// Keygen Loki-Mouse.cpp
//
#include <iostream>
#include<time.h>
#include <sstream>
using namespace std;
int codigo_asm(int num1, int num2)
{
int resultado;
_asm
{
mov eax, num1
mov edx, num2
imul edx
sar edx, 2
mov eax, num1
sar eax, 0x1F
sub edx, eax
mov num2, edx
shl edx, 2
add edx, num2
add edx, edx
mov eax, num1
sub eax, edx
add eax, 0x30
mov resultado, eax
}
return resultado;
}
int main()
{
int numHex = 0x00;
int hexCaracter[11] = {};
string caracter[11] = {};
srand(time(NULL)); //Inicializa números aleatorios
cout << "Keygen Crackme Loki-Mouse\n==========================\n\n";
cin.clear();
cout << "Para generar autom\240ticamente un serial v\240lido, pulsa una tecla...";
cin.ignore();
// El serial tiene que tener exactamente 10 caracteres
// ----------------
// Caracteres 1 y 6
// ----------------
// El carácter 1 va a ser un número aleatorio entre el 0(30hex) y 9(39hex):
hexCaracter[1] = 0x30 + rand() % (10);
// El carácter 6 responde a esta fórmula: c6 + c1 - 60 > 8; c6 > 68 - c1;
hexCaracter[6] = 0x69 - hexCaracter[1]; // Este es el primer valor válido
hexCaracter[0] = 0x39 - hexCaracter[6]; //Número de valores también válidos hasta el 9 (39h)
if (hexCaracter[0] != 0)
{
hexCaracter[6] = hexCaracter[6] + rand() % hexCaracter[0]; //Calcula aleatoriamente un valor válido entre todos los posibles.
}
// ----------
// Caracter 2
// ----------
// Un número aleatorio entre 0 y 9
hexCaracter[2] = 0x30 + rand() % (10);
// -----------------------------------------
// Realiza operaciones en ASM con C1, C2, C6
// -----------------------------------------
hexCaracter[0] = hexCaracter[2] + hexCaracter[1] + hexCaracter[6] - 0x90;
// ----------
// Caracter 5
// ----------
hexCaracter[5] = codigo_asm(hexCaracter[0], 0x66666667);
// ----------
// Caracter 3
// ----------
// Tiene que ser < 33h
hexCaracter[3] = 0x30 + rand() % (2);
// ----------
// Caracter 4
// ----------
// Tiene que ser > 35h
hexCaracter[4] = 0x36 + rand() % (3);
// --------------------
// Caracter 7, 8, 9, 10
// --------------------
// Cualquiera, yo voy a usar solo números, pero vale cualquier otro carácter
for (int i = 7; i < 11; i++)
{
hexCaracter[i] = 0x30 + rand() % (10);
}
// Convertir números en cadena de texto y mostrarlos en pantalla
for (int i = 1; i < 11; i++)
{
caracter[i] = hexCaracter[i];
cout << caracter[i];
}
cout << "\n";
system("pause");
return 0;
}
Y aquí la descarga:
Descargar Keygen desde MegaMuchas gracias Flamer por el reto