Crackme 1.0 by Pusillus ----------------------- This crackme was a nice piece, XOR encryption.. that's fun :) well first of all BPX GetDlgItemTextA and then start the crackme and enter a junk serial, press the 'Check' button, and you should be in softice at the GetDlgItemTextA call, press F12 to get out of that call and you should land here: :004010AB CALL USER32!GetDlgItemTextA :004010B0 CALL 004010C9 :004010B5 JMP 004010C0 :004010B7 MOV EAX,00000000 :004010BC LEAVE :004010BD RET 0010 Press F8 to trace into the CALL 004010C9 (where the routine is) and we lands here: :004010C9 PUSH ESI :004010CA PUSH EDI :004010CB PUSH ECX :004010CC XOR ESI,ESI :004010CE XOR EDI,EDI :004010D0 MOV ECX,00000008 ; counter = 8 :004010D5 MOV ESI,00403044 ; esi = our junk serial :004010DA XOR BYTE PTR [ESI],32 ; takes each char of the junk serial and XOR's the value with 32h :004010DD INC ESI ; esi + 1 :004010DE LOOP 004011DA ; loop until counter = 0 :004010E0 MOV ESI,00403044 ; esi = our junk serial XOR'ed :004010E5 MOV ECX,00000004 ; counter = 4 :004010EA MOV AL,[ESI] ; al = value of first char in our junk serial :004010EC MOV BL,[ESI+01] ; bl = value of second char :004010EF XOR AL,BL ; AL = AL XOR BL :004010F1 MOV [EDI+0040304C],AL ; string = char(al) :004010F7 ADD ESI,02 ; esi + 2 :004010FA INC EDI :004010FB LOOP 004011EA ; loop until counter = 0 :004010FD MOV ESI,0040304C ; ESI = string :00401102 MOV AL,[ESI] ; al = value of first char in string :00401104 MOV BL,[ESI+01] ; bl = value of second char :00401107 XOR AL,BL ; al = al xor bl :00401109 MOV BL,[ESI+02] ; bl = value of third char :0040110C MOV CL,[ESI+03] ; cl = value of fourth char :0040110F XOR BL,CL ; bl = bl xor cl :00401111 XOR AL,BL ; al = al xor bl :00401113 MOV ECX,00000008 ; counter = 8 :00401118 MOV ESI,00403044 ; esi = our junk serial :0040111D XOR [ESI],AL ; char = char xor al :0040111F INC ESI :00401120 LOOP 0040121D ; loop until counter = 0 :00401122 MOV ECX,00000008 ; counter = 8 :00401127 MOV ESI,00403044 ; our fully xor'ed junk serial :0040112C MOV EDI,00403008 ; and this is how it should look like do a 'd 404008' and you'll see that it should be 71h, 18h, 59h, 1Bh, 79h, 42h, 45h, 4Ch :00401131 MOV AL,[ESI] ; al = value of junk serial char :00401133 CMP AL,[EDI] ; compare it with the right :00401135 JNZ 00401154 ; jump if not zero :00401137 INC ESI ; else loop :00401138 INC EDI :00401139 LOOP 00401231 ; loop until counter = 0 :0040113B PUSH 40 :0040113D PUSH 00403035 :00401142 PUSH 00403010 :00401147 PUSH DWORD PTR [00403054] :0040114D CALL USER32!MessageBoxA ; good cracker box! :00401152 JMP 0040116B :00401154 PUSH 30 ; bad cracker comes here :00401156 PUSH 00403035 :0040115B PUSH 00403022 :00401160 PUSH DWORD PTR [00403054] :00401166 CALL USER32!MessageBoxA ; show the bad cracker box :0040116B POP EDI :0040116C POP ESI :0040116D POP ECX :0040116E RET so lets calculate :), but hey! we code an program to do it for us (it's easier ;) here is a sample PASCAL program to calculate the right serial.. var string1,string2:string; x0r,i,cnt:byte; begin string1:=chr($71)+chr($18)+chr($59)+chr($1B)+chr($79)+chr($42)+chr($45)+chr($4C); { string1=the right serial xor'ed (from the 'd 404008' } string2:='1234'; x0r:=0; cnt:=1; for i:=1 to 8 do string1[i]:=chr(ord(string1[i]) xor $32); { XOR each char with 32h } for i:=1 to 4 do begin string2[i]:=chr(ord(string1[cnt]) xor ord(string1[cnt+1])); { string2[i] = value of string1[cnt] xor value of string1[cnt+1] } cnt:=cnt+2; end; string2[1]:=chr(ord(string2[1]) xor ord(string2[2])); { string2[1] = value of string2[1] xor value of string2[2] } string2[2]:=chr(ord(string2[3]) xor ord(string2[4])); { string2[2] = value of string2[3] xor value of string2[4] } x0r:=ord(string2[1]) xor ord(string2[2]); { x0r = value of string2[1] xor value of string2[2] } for i:=1 to 8 do string1[i]:=chr(ord(string1[i]) xor x0r); { XOR each char of STRING1 with the value of x0r } writeln(string1); { print the serial out on the screen } end. and it will show Z3r0Ring which is the right serial :) --- /Klefz