1. Making a valid code for your name The usual breakpoint i set when cracking Serial prot's is Hmemcpy, but when tracing
trough the code, i found out that SendDlgItemMessagaA is a much better breakpoint
this time, so let's set a breakpoint on that, and enter a name/code and press the
check button, then you will be at this point (disable the breakpoint now): :00401132 E841020000 CALL USER32!SendDlgItemMessageA
:00401137 A3AF214000 MOV [004021AF],EAX ;eax = length of name
:0040113C 83F800 CMP EAX,00
:0040113F 0F84D5000000 JZ 0040121A
:00401145 83F808 CMP EAX,08 ;the name mustn't be over 8 chars
:00401148 0F8FCC000000 JG 0040121A
:0040114E 8BF0 MOV ESI,EAX
:00401150 6A00 PUSH 00
:00401152 6A00 PUSH 00
:00401154 6A0E PUSH 0E
:00401156 6A04 PUSH 04
:00401158 FF7508 PUSH DWORD PTR [EBP+08]
:0040115B E818020000 CALL USER32!SendDlgItemMessageA
:00401160 83F800 CMP EAX,00 ;eax = length of serial
:00401163 0F84B1000000 JZ 0040121A
:00401169 3BF0 CMP ESI,EAX ;check if length of serial=length of name
:0040116B 0F85A9000000 JNZ 0040121A ;if not jump to bad code
:00401171 6860214000 PUSH 00402160
:00401176 6A08 PUSH 08
:00401178 6A0D PUSH 0D
:0040117A 6A03 PUSH 03
:0040117C FF7508 PUSH DWORD PTR [EBP+08]
:0040117F E8F4010000 CALL USER32!SendDlgItemMessageA
:00401184 6879214000 PUSH 00402179
:00401189 6A10 PUSH 10
:0040118B 6A0D PUSH 0D
:0040118D 6A04 PUSH 04
:0040118F FF7508 PUSH DWORD PTR [EBP+08]
:00401192 E8E1010000 CALL USER32!SendDlgItemMessageA
:00401197 B9FFFFFFFF MOV ECX,FFFFFFFF
:0040119C 41 INC ECX
:0040119D 0FBE8160214000 MOVSX EAX,BYTE PTR [ECX+00402160];eax=value of current char
:004011A4 83F800 CMP EAX,00 ;check if all chars is processed
:004011A7 7432 JZ 004011DB ;jump if all is
:004011A9 BEFFFFFFFF MOV ESI,FFFFFFFF
:004011AE 83F841 CMP EAX,41 ;if eax is lower than 41h (A)
:004011B1 7C67 JL 0040121A ;jump to bad code
:004011B3 83F87A CMP EAX,7A ;if eax is higher than 7A (z)
:004011B6 7762 JA 0040121A ;jump to bad code
:004011B8 83F85A CMP EAX,5A ;if eax is lower than 5A (Z)
:004011BB 7C03 JL 004011C0 ;jump over the SUB EAX,20
:004011BD 83E820 SUB EAX,20 ;makes the name UPPERCASE
:004011C0 46 INC ESI ;ESI+1
:004011C1 0FBE9617204000 MOVSX EDX,BYTE PTR [ESI+00402017];00402017=magic buffer
;edx=current char in magic buffer
:004011C8 3BC2 CMP EAX,EDX ;check if the current char = edx
:004011CA 75F4 JNZ 004011C0 ;loop if not
:004011CC 0FBE863C204000 MOVSX EAX,BYTE PTR [ESI+0040203C];0040204C=serial buffer
;eax=right char in serial for the current char
:004011D3 898194214000 MOV [ECX+00402194],EAX ;save the right serial in 00402194
:004011D9 EBC1 JMP 0040119C ;loop
And the goal for this crackme was to write a keygen, so here is a sample keygen in C..
---DUELIST4.C--------------SOF---
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
int main(){
unsigned char name[500]={0}, temp[500]={0};
unsigned char magicbuffer[35]="A1LSK2DJF4HGP3QWO5EIR6UTYZ8MXN7CBV9"; //the magic buffer
unsigned char buffer[35]="SU7CSJKF09NCSDO9SDF09SDRLVK7809S4NF"; //the serial buffer
unsigned int i=0,length=0,j=0;
tryagain:
length=0;
clrscr();
printf("Keygen for Duelist's Crackme 4 by Klefz [ReFleXZ '99]\n");
printf("Enter your name: "); gets(name);
/* work out length */
while (name[length] != '\0'){ length++; } if(length==0){
printf("\nYou must enter a name!");
getch();
goto tryagain; }
if(length>8){ printf("\nYou have entered a too long name!");
getch();
goto tryagain; }
for(i=0;i<length;i++){ name[i]=toupper(name[i]); } //make the name uppercase
for(i=0;i<length;i++){
for(j=0;j<35;j++){
if(magicbuffer[j]==name[i]){ temp[i]=buffer[j]; goto done;}} //work out the real serial
printf("\nInvalid character, valid chars is a-z A-Z 123456789"); //if an invalid char is entered, show this and end
getch();
return 0;
done:
}
printf("\nYour registration code is: %s\n",temp);
getch();
return 0; }
---DUELIST4.C--------------EOF---
---
/Klefz [ReFleXZ '99] - http://klefz.cjb.net