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
