Tutorial Crack! =-=-=-=-=-=-=-= Program: Hardwood Solitaire Cracker: JosephCo Level: Intermediate Tools: SoftICE, W32Dasm, a Hex Editor. Ok Gang, here's the long awaited Crack Tutorial for Hardwood Solitaire. Some of you with more experience, may see some flaws in the logic process here. If you do please let me know. The hard part was trying to figure out how to enter my data. While deadlisting it I found references to "Wrong Serial" and "You must input a valid Serial Number" (or to that effect), but alas I couldn't find where to enter the Registration Data. My first instinct was to start hitting control keys. I tried ctrl+a, ctrl+b and so on and so forth...finally when I hit ctrl+k the reg screen popped up. WOW!!!!! (BTW for some lame programmers, you should make it Control D, that might stop some newbie Crackers until they change winice.dat.) Now onto the main course ------------------------ Let me start by saying that first I tried to crack this program using SoftICE. I tried 'BPX hmemcpy then followed my dummy serial. This got me totally lost. I then tried to just patch it so it would accept any user and serial. This wasn't hard to do!! However when I restarted the program it still said that I was not registered!? Damn I missed something. I tried and tried to get it to break when it read my serial from where ever it was stored, but to no avail. By this time I was almost at wits end. I looked at the program again using w32dasm. This time I REALLY looked at it. By following the code I figured something out! Take a look at line 00417484 and tell me what you see. Exactly!!!, its the last test before you are sent to the "CONGRATS YOUR REGISTERED" screen. Hmm at this point I was thinking to myself that if it's set = 0, then that's bad. So, I searched for where it was set in the program. I looked at the line before it and it was CALL 004176f0. I went into that call a little ways. When you do this, look around at the routine. You might find a few interesting things. *side note* ( I don't like to follow calls too far; I just look at them to see if I notice anything neat). When I looked at this call I found 3 jumps to the same address....hmmm (maybe that is a bad place) so I also looked there. Inside that routine I saw where it did a xor eax, eax and then returned to the place where the call was made from. And as you remember the next line is test eax, eax. If xor eax, eax makes eax equal to zero, then that's bad. I knew I didn't want this to happen, so I thought I was in the right routine. To test this theory I hexed an int 3 into the middle of the routine just before the 3 jumps to 0041779b, this was line 00417715. In case you didn't know it, int 3 was set aside for debugging purposes. The op code for int 3 is just CC. Since it is just one byte I usually try to replace another single byte op code with it. If you cant find one and have to put it inside a full instruction remember to nop (90) the remaining bytes in that instruction OK like I said hexed CC into the spot where the push eax (50)was (in the hex editor, you have to search for 11 bytes total: 8d4424208bcc8964240c50) and then ran the program like normal. Since we put an int 3 inside the program we have to make sure that sice pops when it hits it.... I entered sice and did bpint 3. I've been told that if u have the I3here function turned on inside sice then it will pop for you, however I don't. Therefore I did the bpint 3. Just remember to enter sice (before you hit ctrl+k - to get to the reg screen) and make sure it will break on int 3 Now hit ctrl+k and enter the data you want (I used josephCo [C4N '97] for my name and 7777777 for my serial )and press enter. sice pops on the int3 that u hexed into the program....at this point you have to change it back to the original instruction (push eax) to prevent corruption of the data. To do this hit A then the return key. You just entered assemble mode in sice. Now type PUSH EAX then hit the enter key. Now hit the ESC key to get out of assemble mode. The currently highlighted instruction is where the int3 used to be, but now it's replaced by PUSH EAX We want to single step through the code. We do this by hitting f10. What I was looking for when I did this is to see which jmp cleared eax. I also tested all the registers before each jump to see if I could find my serial. The first conditional jump was a test eax, eax. This was just testing to see if eax was 0. I didn't do anything here. The next test was cmp edi, eax. At this point I did D edi and D eax. I noticed that when I did this the starting address was different for both edi and eax. I then did ? eax and ? edi this resulted in the values in eax and edi being printed on the screen. The first number is the hex value of the 2nd number and the 3rd is what it looks like in ascii. I noticed that one of the values was 7777777 !!!!!!!! This was the serial I entered! So I looked at the other one and saw that the serial should have been 137347 !!!!!! I didn't test anything else. I just let the program finish it's check and return with the messagebox saying that I had entered the wrong serial. This time I entered 137347 and hit enter. When sice popped I stepped through again to see what would happen. This time edi and eax were equal. I let the routine keep checking and then a box popped saying thank you for upgrading!!! I had cracked it!!!! The only thing left to do was to change my CC back to a 50 in hex editor. I hope this has helped you understand and maybe shed a little light on the many different ways of finding a serial. I really don't believe a novice can do this from scratch. I have a hard time myself, but with lots of patience and practice (not to mention learning asm) you can eventually do this too. Well thank you for reading this Tutorial, and if you have any questions feel free to stop by #cracking4newbies. We are located on EFNET on IRC. Thanks again and good luck PS. I've added a few comments below to help you out too. ......................................................................................................................................................... THIS IS JUST PART OF THE PROGRAM THAT HAS THE FINAL CHECK FOR THE SERIAL NUMBER :00417459 E851DC0100 call 004350AF :0041745E 83F801 cmp eax, 00000001 :00417461 0F8540010000 jne 004175A7 :00417467 8B54246C mov edx, [esp + 6C] :0041746B 8D442468 lea eax, [esp + 68] :0041746F 52 push edx :00417470 51 push ecx :00417471 8BCC mov ecx, esp :00417473 89642410 mov [esp + 10], esp :00417477 50 push eax :00417478 E8E0C30100 call 0043385D :0041747D 8BCE mov ecx, esi :0041747F E86C020000 call 004176F0 (I followed this call in w32dasm} :00417484 85C0 test eax, eax (this is the test to see if eax = 0 or not) :00417486 0F84D3000000 je 0041755F (if eax is 0 then goto "sorry wrong serial" routine :0041748C 6A00 push 00000000 2:0041748E 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"Thank you for upgrading Hardwood " ->"Solitaire II!!!!" | :00417490 68F41F4500 push 00451FF4 :00417495 E8F8640200 call 0043D992 ......................................................................................................................................................... THIS IS THE START OF THE CALL :004176F0 6AFF push FFFFFFFF :004176F2 6898264400 push 00442698 :004176F7 64A100000000 mov eax, fs:[00000000] :004176FD 50 push eax :004176FE 64892500000000 mov fs:[00000000], esp :00417705 51 push ecx :00417706 56 push esi :00417707 57 push edi :00417708 8BF1 mov esi, ecx :0041770A 51 push ecx :0041770B 8D442420 lea eax, [esp + 20] :0041770F 8BCC mov ecx, esp :00417711 8964240C mov [esp + 0C], esp :00417715 50 push eax ( this is the line I changed to int3(CC)) :00417716 C744241C00000000 mov [esp + 1C], 00000000 :0041771E E83AC10100 call 0043385D :00417723 8BCE mov ecx, esi :00417725 E816FAFFFF call 00417140 :0041772A 85C0 test eax, eax (was anything entered in the serial field?) :0041772C 756D jne 0041779B JUMP :0041772E 8B4C241C mov ecx, [esp + 1C] :00417732 51 push ecx :00417733 8BCE mov ecx, esi :00417735 E806FFFFFF call 00417640 :0041773A 8BF8 mov edi, eax :0041773C 8B442420 mov eax, [esp + 20] :00417740 3BF8 cmp edi, eax (edi=proper serial eax=dummy serial) :00417742 7557 jne 0041779B JUMP: eax gets set to 0 :00417744 8B54241C mov edx, [esp + 1C] :00417748 837AF803 cmp [edx+F8], 00000003 :0041774C 7E4D jle 0041779B JUMP :0041774E 8D8E17060000 lea ecx, [esi+00000617] :00417754 6A0A push 0000000A :00417756 51 push ecx :00417757 50 push eax :00417758 E823820100 call 0042F980 :0041775D 83C40C add esp, 0000000C :00417760 81C63A060000 add esi, 0000063A :00417766 6A0A push 0000000A :00417768 56 push esi :00417769 57 push edi :0041776A E811820100 call 0042F980 :0041776F 83C40C add esp, 0000000C :00417772 8D4C241C lea ecx, [esp + 1C] :00417776 C7442414FFFFFFFF mov [esp + 14], FFFFFFFF :0041777E E815C20100 call 00433998 :00417783 B801000000 mov eax, 00000001 :00417788 8B4C240C mov ecx, [esp + 0C] :0041778C 64890D00000000 mov fs:[00000000], ecx :00417793 5F pop edi :00417794 5E pop esi :00417795 83C410 add esp, 00000010 :00417798 C20800 ret 0008 ......................................................................................................................................................... THIS ROUTINE CLEARS EAX :0041779B 8D4C241C lea ecx, [esp + 1C] :0041779F C7442414FFFFFFFF mov [esp + 14], FFFFFFFF :004177A7 E8ECC10100 call 00433998 :004177AC 8B4C240C mov ecx, [esp + 0C] :004177B0 5F pop edi :004177B1 33C0 xor eax, eax ( this line makes eax=0, which we DON'T :004177B3 64890D00000000 mov fs:[00000000], ecx want to happen) :004177BA 5E pop esi :004177BB 83C410 add esp, 00000010 :004177BE C20800 ret 0008