Cracking "KeyText v 1.24" Date: July 24, 1999 Author : +ViPeR+ [E]bola [V]irus [C]rew Program Name : KeyText v 1.24 Location : http://www.mjmsoft.com/ Method: Calculate and Compare char by char. <> ------------------------------------------------------------------------------- For demostration purpose and to save you the time of repeatedly tracing the code, please enter the following information in the registration box. Name: evc_viper Code: 4346V39IPERR 'Ctrl-D' into Soft-Ice. Set breakpoint at 'hmemcpy' in Soft-Ice. 'Ctrl-D' out of Soft-Ice. and click 'ok' button and you are back to Soft-Ice. I assume that you have already 'F11' and 'F12' back to the process of KeyText. (If not, read some other tutorials about how to do it). 'F10' until you are at 00406ABE. : :00406ABE E8BD5B0000 call 0040C680 :00406AC3 85C0 test eax, eax :00406AC5 7433 je 00406AFA ; jump if eax=0 If you jump at the above call, you are a bad cracker. Hence, let's trace in the 'call 0040C680'. >>> The First Part <<< 'F10' until you reach at : : 015F:0040C6BA 8A87E8D14200 MOV AL,[EDI+0042D1E8] 015F:0040C6C0 50 PUSH EAX 015F:0040C6C1 E88A010000 CALL 0040C850 015F:0040C6C6 83C404 ADD ESP,04 015F:0040C6C9 03F0 ADD ESI,EAX ; ESI has hex value ; of 'r', the last ; char of our user name 015F:0040C6CB 47 INC EDI 015F:0040C6CC 83FF05 CMP EDI,05 015F:0040C6CF 7CE9 JL 0040C6BA The above code get the hex sum of 'revc_v' which is 285h. 015F:0040C6D1 8BC6 MOV EAX,ESI 015F:0040C6D3 B944000000 MOV ECX,00000044 015F:0040C6D8 99 CDQ 015F:0040C6D9 F7F9 IDIV ECX EAX(=285h) is divided by ECX(=44h). The result is put in EAX and EDX, respectively. so, 285h/44h = 9h ..... 21h and EAX=00000009, EDX=00000021. 015F:0040C6DB B867666666 MOV EAX,66666667 015F:0040C6E0 8B1D0CD24200 MOV EBX,[0042D20C] 015F:0040C6E6 8BCA MOV ECX,EDX 015F:0040C6E8 83C10A ADD ECX,0A ECX = 21h + Ah = 2Bh. 015F:0040C6EB F7E9 IMUL ECX EAX=66666667*ECX = 113333334Dh. They are store in EAX and EDX respectively of the following form: EAX=3333334D, EDX=00000011. 015F:0040C6ED C1FA02 SAR EDX,02 After this instruction, EDX=00000004. 015F:0040C6F0 8BC2 MOV EAX,EDX 015F:0040C6F2 C1E81F SHR EAX,1F ; <-- Set EAX=00000000 015F:0040C6F5 8D540230 LEA EDX,[EAX+EDX+30] ; EDX=00000034=4(dec) 015F:0040C6F9 8BC3 MOV EAX,EBX 015F:0040C6FB 25FF000000 AND EAX,000000FF ; <-- get the 1st fake char 015F:0040C700 3BD0 CMP EDX,EAX ; <-- Compare them 015F:0040C702 0F8534010000 JNZ 0040C83C (NO JUMP)4 015F:0040C708 8BC1 MOV EAX,ECX 015F:0040C70A B90A000000 MOV ECX,0000000A EAX=2B and ECX=0000000A. EAX / ECX = 4(=EAX).....3(=EDX). 015F:0040C70F 99 CDQ 015F:0040C710 F7F9 IDIV ECX 015F:0040C712 33C0 XOR EAX,EAX 015F:0040C714 8AC7 MOV AL,BH 015F:0040C716 83C230 ADD EDX,30 EDX = 3h + 30h = 33h. 015F:0040C719 3BD0 CMP EDX,EAX ; <-- compare the second char 015F:0040C71B 0F851B010000 JNZ 0040C83C (NO JUMP)3 The following code snippet calculates and compares the 3rd and 4th registration code. It is very similar to the above code. 015F:0040C721 8BC6 MOV EAX,ESI ; <-- EAX= 285h 015F:0040C723 B957000000 MOV ECX,00000057 015F:0040C728 99 CDQ 015F:0040C729 F7F9 IDIV ECX 015F:0040C72B B867666666 MOV EAX,66666667 015F:0040C730 8BCA MOV ECX,EDX 015F:0040C732 83C10A ADD ECX,0A 015F:0040C735 F7E9 IMUL ECX 015F:0040C737 C1FA02 SAR EDX,02 015F:0040C73A 8BC2 MOV EAX,EDX 015F:0040C73C C1E81F SHR EAX,1F 015F:0040C73F 8D540230 LEA EDX,[EAX+EDX+30] 015F:0040C743 33C0 XOR EAX,EAX 015F:0040C745 A00ED24200 MOV AL,[0042D20E] 015F:0040C74A 3BD0 CMP EDX,EAX ; <-- compare the 3rd chars. 015F:0040C74C 0F85EA000000 JNZ 0040C83C (NO JUMP)4 015F:0040C752 8BC1 MOV EAX,ECX 015F:0040C754 B90A000000 MOV ECX,0000000A 015F:0040C759 99 CDQ 015F:0040C75A F7F9 IDIV ECX 015F:0040C75C 33C0 XOR EAX,EAX 015F:0040C75E A00FD24200 MOV AL,[0042D20F] ; <--- Notice this 015F:0040C763 83C230 ADD EDX,30 015F:0040C766 3BD0 CMP EDX,EAX ; <-- compare the 4th char 015F:0040C768 0F85CE000000 JNZ 0040C83C (NO JUMP)6 015F:0040C76E 8BC6 MOV EAX,ESI 015F:0040C770 B94D000000 MOV ECX,0000004D 015F:0040C775 99 CDQ 015F:0040C776 F7F9 IDIV ECX 015F:0040C778 B867666666 MOV EAX,66666667 015F:0040C77D 8BCA MOV ECX,EDX 015F:0040C77F 83C10A ADD ECX,0A 015F:0040C782 F7E9 IMUL ECX 015F:0040C784 C1FA02 SAR EDX,02 015F:0040C787 8BC2 MOV EAX,EDX 015F:0040C789 C1E81F SHR EAX,1F 015F:0040C78C 8D540230 LEA EDX,[EAX+EDX+30] 015F:0040C790 33C0 XOR EAX,EAX 015F:0040C792 A011D24200 MOV AL,[0042D211] ; <--- Notice this If you are careful, you can see that the compare routine skip the 5th char. and calculate and compare the 6th and 7th char. 015F:0040C797 3BD0 CMP EDX,EAX ; <-- compare the 6th char 015F:0040C799 0F859D000000 JNZ 0040C83C (NO JUMP)3 015F:0040C79F 8BC1 MOV EAX,ECX 015F:0040C7A1 B90A000000 MOV ECX,0000000A 015F:0040C7A6 99 CDQ 015F:0040C7A7 F7F9 IDIV ECX 015F:0040C7A9 33C0 XOR EAX,EAX 015F:0040C7AB A012D24200 MOV AL,[0042D212] 015F:0040C7B0 83C230 ADD EDX,30 015F:0040C7B3 3BD0 CMP EDX,EAX ; <-- compare the 7th char 015F:0040C7B5 0F8581000000 JNZ 0040C83C (NO JUMP)9 015F:0040C7BB 33C9 XOR ECX,ECX 015F:0040C7BD 33C0 XOR EAX,EAX Hence, if the user name is 'evc_viper', the first part of your registration code is '4346V39'. You can replace the 'V' with any character you like because the program ignore the 5th character. But it will be used to calculate the second part of your registration code. >>> The Second Part <<< 015F:0040C7BF 84DB TEST BL,BL 015F:0040C7C1 7419 JZ 0040C7DC (NO JUMP) 015F:0040C7C3 85C9 TEST ECX,ECX 015F:0040C7C5 740A JZ 0040C7D1 015F:0040C7C7 33D2 XOR EDX,EDX 015F:0040C7C9 8A910BD24200 MOV DL,[ECX+0042D20B] 015F:0040C7CF 03C2 ADD EAX,EDX 015F:0040C7D1 8A910DD24200 MOV DL,[ECX+0042D20D] 015F:0040C7D7 41 INC ECX 015F:0040C7D8 84D2 TEST DL,DL 015F:0040C7DA 75E7 JNZ 0040C7C3 015F:0040C7DC 99 CDQ 015F:0040C7DD BEF0000000 MOV ESI,000000F0 015F:0040C7E2 8A890BD24200 MOV CL,[ECX+0042D20B] 015F:0040C7E8 F7FE IDIV ESI What the above code segment does is to sum the hex values of your registration code except the last char. Let's put the sum in a variable called 'SumRegCode'. SumRegCode / ESI. In this case, it is 2c3h/F0h = 02h.....E3h and the result is put into EAX and EDX where, in our example, EAX=02h and EDX=E3h. 015F:0040C7EA 80F949 CMP CL,49 ; <-- 49="I" 015F:0040C7ED 884C240C MOV [ESP+0C],CL 015F:0040C7F1 8BC2 MOV EAX,EDX ; EAX=E3h 015F:0040C7F3 7306 JAE 0040C7FB 015F:0040C7FB 80F94F CMP CL,4F ; <-- 4f ="O" 015F:0040C7FE 7606 JBE 0040C806 015F:0040C800 FEC9 DEC CL 015F:0040C802 884C240C MOV [ESP+0C],CL 015F:0040C806 99 CDQ 015F:0040C807 BE18000000 MOV ESI,00000018 015F:0040C80C 8B4C240C MOV ECX,[ESP+0C] 015F:0040C810 F7FE IDIV ESI E3h/18h = 09h.....0Bh where EAX=09h and EDX=0Bh. 015F:0040C812 81E1FF000000 AND ECX,000000FF 015F:0040C818 83E942 SUB ECX,42 015F:0040C81B 3BCA CMP ECX,EDX ; Note: EDX=0Bh The above CMP instruction is important. If ECX==EDX, you are registered. Otherwise, still not registered. From the code, the value in ECX will be substracted by 42h and then this value will be compared with the value in EDX which is OBh in our case. Simple calculation follows: ECX-42h=0Bh, hence, ECX is equal to 42h + 0Bh = 4Dh which is the hex code for the letter "M". 015F:0040C81D 751D JNZ 0040C83C 015F:0040C83C 5F POP EDI 015F:0040C83D 5E POP ESI 015F:0040C83E 33C0 XOR EAX,EAX 015F:0040C840 5B POP EBX 015F:0040C841 59 POP ECX 015F:0040C842 C3 RET Enter the following information: Name: evc_viper Code: 4346V39IPERM to see the "Thank you" message box. Final Note: Follow the above explaination, I think it should be easy to write a key generator for this nice program. Also, try to use different name and code to figure out the last letter of your code. It is fun. Ob Duh Do I really have to remind you all that by buying and NOT stealing the software you use will ensure that these software houses will continue to produce even *better* software for us to use and more importantly, to continue offering even more challenges to breaking their often weak protection systems. +ViPeR+ [E]bola [V]irus [C]rew July 24 1999