Crack Tutorial by Vizion, 09/97 [TARGET...........]: SmilerShell/95 v1.4 (url : www.windows95.com) [TOOLZ............]: W32Dasm v8.9, SoftIce 3.01 [PROTECTION.......]: registration key [REMARK(s)........]: problably cracked already by some other people [PRECRACK NOTES...]: I assume that you have some knowledge about ASM and are able to use W32Dasm and SoftIce [#1 THe KEY.......]: Hi again! Today we take a look at SmilerShell/95. When we load the program, we can see that a registration key is all we need to register this target. First of all create a "dead-listing" with W32Dasm. Why we do that? Well we want to know what .dll calls are made. So goto the next section in W32Dasm, +++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++ Number of Imported Modules = 6 (decimal) Import Module 001: KERNEL32.dll Import Module 002: USER32.dll <--- interesting Import Module 003: GDI32.dll Import Module 004: comdlg32.dll Import Module 005: ADVAPI32.dll Import Module 006: SHELL32.dll So jump to the details about USER32.dll Import Module 002: USER32.dll ... Addr:00030F0C hint(00E8) Name: GetDesktopWindow Addr:00030BF4 hint(00C1) Name: EnumWindows Addr:00030BE8 hint(015C) Name: IsWindow Addr:00030BD6 hint(0135) Name: GetWindowTextA <--- interesting Addr:00030BC4 hint(008A) Name: DialogBoxParamA Addr:00030BB8 hint(0159) Name: IsIconic ... Addr:00030AFE hint(01A3) Name: PostMessageA Addr:00030AEE hint(0207) Name: SetWindowPos Addr:00030AD8 hint(01C4) Name: SendDlgItemMessageA Addr:00030AC6 hint(00ED) Name: GetDlgItemTextA <--- interesting Addr:00030AB8 hint(0188) Name: MessageBoxA Addr:00030E1C hint(0115) Name: GetParent ... Ok, we got to choices to set a breakpoint on. Let's start with GetWindowTextA. Start SoftIce (SI) and enter it (Ctrl-D). Set a breakpoint on GetWindowTextA type : BPX GetWindowTextA and exit SI (Ctrl-D again), run SmilerShell/95 (SS) and enter any key (I used : 12121212). Bingo! You should be right back in SI, press F11 to get out of the function and disable the breakpoint type : BD 0 Now you'll see that GetWindowTextA was called from within GetDlgItemTextA. Now press F10 twice to get into the SS-code, if you should have set a breakpoint on GetDlgItemTextA, you would have saved two F10'n (try it). Either way, you should get at the following code, * Reference To: USER32.GetDlgItemTextA, Ord:00EDh | :00401CCA FF15B4064300 Call dword ptr [004306B4] :00401CD0 85C0 test eax, eax <--- has user entered a key? :00401CD2 0F841F020000 je 00401EF7 <--- jump if no key * Possible Reference to String Resource ID=00001: "&Hide!" | :00401CD8 C785ACFEFFFF01000000 mov dword ptr [ebp+FFFFFEAC], 00000001 :00401CE2 0FBE85B0FEFFFF movsx eax, byte ptr [ebp+FFFFFEB0] :00401CE9 50 push eax :00401CEA E88E9B0100 call 0041B87D <--- upcase first char of key :00401CEF 83C404 add esp, 00000004 :00401CF2 8885B0FEFFFF mov byte ptr [ebp+FFFFFEB0], al * Possible Reference to String Resource ID=00001: "&Hide!" | :00401CF8 C785A8FEFFFF01000000 mov dword ptr [ebp+FFFFFEA8], 00000001 :00401D02 E906000000 jmp 00401D0D <--- jump to 00401D0D * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401D93(U) | :00401D07 FF85A8FEFFFF inc dword ptr [ebp+FFFFFEA8] * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401D02(U) | :00401D0D 8B85A8FEFFFF mov eax, dword ptr [ebp+FFFFFEA8] :00401D13 0FBE8405B0FEFFFF movsx eax, byte ptr [ebp+eax-00000150] :00401D1B 85C0 test eax, eax :00401D1D 0F8475000000 je 00401D98 :00401D23 833D64E3420001 cmp dword ptr [0042E364], 00000001 :00401D2A 0F8E24000000 jle 00401D54 <--- jump to 00401D54 ... * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00401D2A(C) | :00401D54 8B85A8FEFFFF mov eax, dword ptr [ebp+FFFFFEA8] :00401D5A 0FBE8405B0FEFFFF movsx eax, byte ptr [ebp+eax-00000150] ... * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401D1D(C), :00401D8E(U) | :00401D98 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401D9F 0F8422000000 je 00401DC7 :00401DA5 8D85B0FEFFFF lea eax, dword ptr [ebp+FFFFFEB0] :00401DAB 50 push eax :00401DAC E87F9A0100 call 0041B830 :00401DB1 83C404 add esp, 00000004 :00401DB4 83F80B cmp eax, 0000000B <--- is lenght of entered key = 11 :00401DB7 0F840A000000 je 00401DC7 :00401DBD C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401D9F(C), :00401DB7(C) | :00401DC7 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401DCE 0F841A000000 je 00401DEE :00401DD4 0FBE85B7FEFFFF movsx eax, byte ptr [ebp+FFFFFEB7] <--- get 8th char :00401DDB 83F833 cmp eax, 00000033 <--- equal to '3' :00401DDE 0F840A000000 je 00401DEE :00401DE4 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401DCE(C), :00401DDE(C) | :00401DEE 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401DF5 0F841A000000 je 00401E15 :00401DFB 0FBE85B4FEFFFF movsx eax, byte ptr [ebp+FFFFFEB4] <--- get 5th char :00401E02 83F830 cmp eax, 00000030 <--- equal to '0' :00401E05 0F840A000000 je 00401E15 :00401E0B C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401DF5(C), :00401E05(C) | :00401E15 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401E1C 0F841A000000 je 00401E3C :00401E22 0FBE85B3FEFFFF movsx eax, byte ptr [ebp+FFFFFEB3] <--- get 4th char :00401E29 83F834 cmp eax, 00000034 <--- equal to '4' :00401E2C 0F840A000000 je 00401E3C :00401E32 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401E1C(C), :00401E2C(C) | :00401E3C 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401E43 0F841A000000 je 00401E63 :00401E49 0FBE85B1FEFFFF movsx eax, byte ptr [ebp+FFFFFEB1] <--- get 2nd char :00401E50 83F832 cmp eax, 00000032 <--- equal to '2' :00401E53 0F840A000000 je 00401E63 :00401E59 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401E43(C), :00401E53(C) | :00401E63 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401E6A 0F841A000000 je 00401E8A :00401E70 0FBE85B6FEFFFF movsx eax, byte ptr [ebp+FFFFFEB6] <--- get 7th char :00401E77 83F830 cmp eax, 00000030 <--- equal to '0' :00401E7A 0F840A000000 je 00401E8A :00401E80 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401E6A(C), :00401E7A(C) | :00401E8A 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401E91 0F841A000000 je 00401EB1 :00401E97 0FBE85B0FEFFFF movsx eax, byte ptr [ebp+FFFFFEB0] <--- get 1st char :00401E9E 83F843 cmp eax, 00000043 <--- equal to 'C' :00401EA1 0F840A000000 je 00401EB1 :00401EA7 C785ACFEFFFF00000000 mov dword ptr [ebp+FFFFFEAC], 00000000 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:00401E91(C), :00401EA1(C) | :00401EB1 83BDACFEFFFF00 cmp dword ptr [ebp+FFFFFEAC], 00000000 :00401EB8 0F8419000000 je 00401ED7 :00401EBE 8D85B0FEFFFF lea eax, dword ptr [ebp+FFFFFEB0] :00401EC4 50 push eax :00401EC5 6860434200 push 00424360 :00401ECA E871880100 call 0041A740 :00401ECF 83C408 add esp, 00000008 :00401ED2 E920000000 jmp 00401EF7 ... So from this code we know that the key needs the next format : C2x40x03xxx, and the value for x can be anything from 0-9. Voila, another target has just been cracked. Now let's go on and create a little key generator for it, so that you can show the whole world how good you are ;). [#2 KEY GEN.......]: I will use Borland Pascal 7.0 for this little example, why? Well I think pascal is quite readable, and that's important i think :). Ofcourse you can do this in ASM or C or any programming language you like. Ok, here follows the code for the keygenerator, ----------------------------------------------------------------------------------- program SmilerShell; var key : string; begin writeln('SmilerShell/95 v1.4 - Key Generator by Vizion [VC97]'); randomize; key[0] := #11; <--- set lenght of string at 11 key[1] := char(67); <--- fill string with needed and some random values key[2] := char(50); key[3] := char(random(9) + 48); key[4] := char(52); key[5] := char(48); key[6] := char(random(9) + 48); key[7] := char(48); key[8] := char(51); key[9] := char(random(9) + 48); key[10] := char(random(9) + 48); key[11] := char(random(9) + 48); write('Registration key : ', key) end. ----------------------------------------------------------------------------------- I think you should be able to understand most of the code. So that's all. Easy! [GREETZ...........]: All people on #cracking4newbies and #cracking, members of Mexelite`97/c4n Fravia for his (awesome) home page, Razzi, +ORC, and many others for there great tutorials So that's all folks, hope you enjoyed it and learned something, Vizion.