Lo primero es ver cómo reacciona el programa al intentar registrarnos.
Ponemos un nombre, empresa y clave cualquiera, y nos aparece un mensaje de clave incorrecta.
El mensaje es el típico MessageBox de windows, lo cual nos facilita el poder acercarnos a la rutina de
comprobación de la clave.
Así pues, vamos al SoftIce(Ctrl+D) ,ponemos el breakpoint(BPX MessageBoxA) y volvemos al programa(Ctrl+D).
Intentamos registrarnos nuevamente para ver si nuestro breakpoint hace efecto.
Efectivamente, aparecemos en el SoftIce, en la rutina MessageBoxA de la USER32.DLL del windows.
Le damos a la tecla F12 para ver quién ha llamado a esta rutina.
Después de un Enter, ya estamos en la parte del código del programa FCOMPARE
Con un par más de F12 nos situaremos en 014F:00408FC0, y unas líneas antes podemos ver una parte interesante del código :
014F:00408F9B 8B45E8 MOV EAX,[EBP-18] ;Clave
014F:00408F9E 8B4DE0 MOV ECX,[EBP-20] ;Empresa
014F:00408FA1 50 PUSH EAX
014F:00408FA2 8B55E4 MOV EDX,[EBP-1C] ;Nombre
014F:00408FA5 51 PUSH ECX
014F:00408FA6 52 PUSH EDX
014F:00408FA7 E854020000 CALL 00409200 ;ValidaClave
014F:00408FAC 83C40C ADD ESP,0C
014F:00408FAF 85C0 TEST EAX,EAX
014F:00408FB1 7531 JNZ 00408FE4
014F:00408FB3 6A11 PUSH 11
014F:00408FB5 A1DC5D4400 MOV EAX,[00445DDC]
014F:00408FBA 50 PUSH EAX
014F:00408FBB E8706B0000 CALL 0040FB30
014F:00408FC0 83C408 ADD ESP,08
Así pues, la validación de la clave introducida se hace en la rutina que empieza en :409200
Vamos pallí.... Ponemos un breakpoint en :408FA7 haciendo doble clic en esa línea, quitamos el anterior breakpoint con BD 0, y retornamos al programa con F5.
Volvemos a registrarnos, y el SoftIce se parará por el breakpoint. Podemos ver los datos que se le pasan a la rutina de validación mirando el contenido de eax, ecx y edx (D EDX)
Con F8 entramos en la rutina de :409200
Lo primero que hace, es verificar que la clave tenga exactamente 8 posiciones.
Luego comprueba que sólo contenga letras de '0' a '9', de 'a' a 'f', y de 'A' a 'F'.
Seguidamente las va acumulando en ESI, de tal manera que al final ESI=Clave.
Entonces calcula un número en función de la empresa, que guarda en EDI. Luego calcula otro número esta vez en función del nombre, que se suma a EDI.
Finalmente a EDI se le suma ESI, y se incrementa en 1. En estos momentos, si EDI vale 0, la clave se considera válida, sinó es incorrecta.
Todo esto se puede ver en :
014F:00409200 56 PUSH ESI
014F:00409201 57 PUSH EDI
014F:00409202 33F6 XOR ESI,ESI ; ESI = 0
014F:00409204 8B7C2414 MOV EDI,[ESP+14]
014F:00409208 57 PUSH EDI
014F:00409209 FF1548A84400 CALL [KERNEL32!lstrlen]
014F:0040920F 83F808 CMP EAX,08 ;Clave de 8 posiciones?
014F:00409212 7405 JZ 00409219
014F:00409214 33C0 XOR EAX,EAX ;Clave incorrecta
014F:00409216 5F POP EDI
014F:00409217 5E POP ESI
014F:00409218 C3 RET
014F:00409219 8A07 MOV AL,[EDI] ;Comprueba letra
014F:0040921B 47 INC EDI
014F:0040921C 84C0 TEST AL,AL
014F:0040921E 743A JZ 0040925A
014F:00409220 C1E604 SHL ESI,04
014F:00409223 3C30 CMP AL,30 ;Entre '0'
014F:00409225 7C0C JL 00409233 ; ....
014F:00409227 3C39 CMP AL,39 ; y '9'
014F:00409229 7F08 JG 00409233
014F:0040922B 0FBEC0 MOVSX EAX,AL
014F:0040922E 83E830 SUB EAX,30
014F:00409231 EB1E JMP 00409251
014F:00409233 3C61 CMP AL,61 ;Entre 'a'
014F:00409235 7C0C JL 00409243 ; ....
014F:00409237 3C66 CMP AL,66 ; y 'f'
014F:00409239 7F08 JG 00409243
014F:0040923B 0FBEC0 MOVSX EAX,AL
014F:0040923E 83E857 SUB EAX,57
014F:00409241 EB0E JMP 00409251
014F:00409243 3C41 CMP AL,41 ;Entre 'A'
014F:00409245 7C3E JL 00409285 ; ....
014F:00409247 3C46 CMP AL,46 ; y 'F'
014F:00409249 7F3A JG 00409285
014F:0040924B 0FBEC0 MOVSX EAX,AL
014F:0040924E 83E837 SUB EAX,37
014F:00409251 03F0 ADD ESI,EAX ;Añade letra a ESI
014F:00409253 8A07 MOV AL,[EDI]
014F:00409255 47 INC EDI
014F:00409256 84C0 TEST AL,AL
014F:00409258 75C6 JNZ 00409220 ;Bucle para las 8 letras
014F:0040925A 8B442410 MOV EAX,[ESP+10] ;Empresa (nº1)
014F:0040925E 50 PUSH EAX
014F:0040925F E83CFFFFFF CALL 004091A0 ;Calcula Número
014F:00409264 83C404 ADD ESP,04
014F:00409267 8BF8 MOV EDI,EAX ;EDI = nº1
014F:00409269 8B44240C MOV EAX,[ESP+0C] ;Nombre (nº2)
014F:0040926D 50 PUSH EAX
014F:0040926E E82DFFFFFF CALL 004091A0 ;Calcula Número
014F:00409273 83C404 ADD ESP,04
014F:00409276 03F8 ADD EDI,EAX ;EDI=nº1 + nº2
014F:00409278 03FE ADD EDI,ESI ;EDI=nº1 + nº2 + ESI
014F:0040927A 47 INC EDI ;EDI=nº1 + nº2 + ESI + 1
014F:0040927B 83FF01 CMP EDI,01 ;Assigna el BitDeAcarreo
014F:0040927E 5F POP EDI
014F:0040927F 1BC0 SBB EAX,EAX ;EAX=EAX-EAX-BitDeAcarreo
014F:00409281 5E POP ESI
014F:00409282 F7D8 NEG EAX ;Pone EAX=1 si Clave OK
014F:00409284 C3 RET
014F:00409285 33C0 XOR EAX,EAX ;Clave incorrecta
014F:00409287 5F POP EDI
014F:00409288 5E POP ESI
014F:00409289 C3 RET
Así pues, nº_Empresa + nº_Nombre + nº_Clave + 1 = 0 determina que la clave sea correcta.
O lo que es lo mismo, que Clave = - nº_Empresa - nº_Nombre - 1
Ahora ya sabemos cómo se calcula la clave, pero para poder hacer el generador de claves, necesitamos saber cómo se calcula el número en función del nombre
y la empresa.
De ello se encarga la rutina que empieza en :4091A0 :
014F:004091A0 56 PUSH ESI
014F:004091A1 57 PUSH EDI
014F:004091A2 33FF XOR EDI,EDI
014F:004091A4 8B74240C MOV ESI,[ESP+0C]
014F:004091A8 56 PUSH ESI
014F:004091A9 FF1548A84400 CALL [KERNEL32!lstrlen]
014F:004091AF 83F804 -- CMP EAX,04
014F:004091B2 7216 (1)| JB 004091CA
014F:004091B4 8BC8 | MOV ECX,EAX
014F:004091B6 C1E902 | SHR ECX,02
014F:004091B9 8D148D00000000 | LEA EDX,[ECX*4+00000000]
014F:004091C0 2BC2 | SUB EAX,EDX
014F:004091C2 033E | ADD EDI,[ESI]
014F:004091C4 83C604 | ADD ESI,04
014F:004091C7 49 | DEC ECX
014F:004091C8 75F8 -- JNZ 004091C2
014F:004091CA 83F802 -- CMP EAX,02
014F:004091CD 721C (2)| JB 004091EB
014F:004091CF 8BD0 | MOV EDX,EAX
014F:004091D1 C1EA01 | SHR EDX,01
014F:004091D4 8D0C5500000000 | LEA ECX,[EDX*2+00000000]
014F:004091DB 2BC1 | SUB EAX,ECX
014F:004091DD 33C9 | XOR ECX,ECX
014F:004091DF 83C602 | ADD ESI,02
014F:004091E2 668B4EFE | MOV CX,[ESI-02]
014F:004091E6 03F9 | ADD EDI,ECX
014F:004091E8 4A | DEC EDX
014F:004091E9 75F2 -- JNZ 004091DD
014F:004091EB 83F801 -- CMP EAX,01
014F:004091EE 720A (3)| JB 004091FA
014F:004091F0 33C9 | XOR ECX,ECX
014F:004091F2 8A0E | MOV CL,[ESI]
014F:004091F4 46 | INC ESI
014F:004091F5 03F9 | ADD EDI,ECX
014F:004091F7 48 | DEC EAX
014F:004091F8 75F6 -- JNZ 004091F0
014F:004091FA 8BC7 MOV EAX,EDI
014F:004091FC 5F POP EDI
014F:004091FD 5E POP ESI
014F:004091FE C3 RET
La rutina acaba devolviendo un valor en EAX. Para sus cálculos, utiliza EDI para ir acumulando
el código ascii de cada carácter de la clave, de la siguiente manera :
1) Si la clave tiene 4 o más caracteres, acumula en bloques de 4 bytes en orden inverso.
2) Si quedan 2 o más caracteres no acumulados, se suman en bloques de 2 bytes en orden inverso.
3) Si queda algún carácter no tratado, también se suma.
Quizás con un ejemplo se entienda mejor, así que veamos cómo actuaría la rutina con el texto "WKT-ECD",
que en hexa es: 57 4B 54 2D 45 43 44
1) EDI=2D544B57 ;los 4 primeros bytes en orden inverso
2) +00004345 ;los 2 siguientes bytes en orden inverso
3) +00000044 ;el último byte
---------
EDI=2D548EE0 ;valor que devuelve la rutina
|