Spamkiller v2.76
[Reversing essay]

Subject: Cracking
Target: Spamkiller v2.76
Author: BlackB
URL: http://www.spamkiller.com
Date: 2000-02-28
Tools used: SoftICE
Difficulty (scale 1-5): 2

Before starting!
This essay is for knowledge purposes only!!
Software developers spend much time in making their programs. They live from the money we give them!
Please buy good software!!
I. Introduction
Hi cracker! Back for more? Good....coz here is another reversing essay! This time I'll show you how to reverse Spamkiller. This time we won't try to patch it, no, we'll fish for a serial. And what serial? A hardcoded one!! That means: the hardcoded serial works with all usernames and companies you fill in!! So no need to make a keygen :-)
II. About the protection
Has some anti-sice (easy to remove). Further we won't bother about other protections like the trial as we're looking for a serial.
III. Cracking it

When I first got my hands on Spamkiller I tried to patch it. However, I never succeeded in doing it and I became quite frustrated. I didn't try to find a serial as I thought it would be too hard. But as I had nothing to loose I gave it a try......god it was dead easy and I even found a hardcoded serial! :-)

Okay, how to start? First: you can't enter a serial when you installed the program. You have to enter it when installing. So run the setup file until you have the choice between "yes, i've bought the program"/"no, but install the trial". Of course we select the first option ;-) There are 3 textboxes to fill in: username, company, serial. Fill in your name, company and a bogus serial. Fire up SoftICE (ctrl-d....do I still have to mention this??) We'll set a breakpoint on hmemcpy as there are no other breakpoints useable. Leave SoftICE and click "Next". SoftICE pops up. Now press F12 (=execute until 'ret') twelve times! Then you'll reach the real Spamkiller install code. You see this now:

Start partial code

0137:0113EBB6  MOV     EAX,[EBP-08]
0137:0113EBB9  LEA     EDX,[EBP-04]
0137:0113EBBC  CALL    010F7F24
0137:0113EBC1  MOV     EDX,[EBP-04]
0137:0113EBC4  LEA     EAX,[EDI+08]
0137:0113EBC7  CALL    010F3AB8
0137:0113EBCC  LEA     EDX,[EBP-10]
0137:0113EBCF  MOV     EAX,[EBX+00000308]
0137:0113EBD5  CALL    0112A05C
0137:0113EBDA  MOV     EAX,[EBP-10]
0137:0113EBDD  LEA     EDX,[EBP-0C]
0137:0113EBE0  CALL    010F7F24
0137:0113EBE5  MOV     EDX,[EBP-0C]
0137:0113EBE8  LEA     EAX,[EDI+0C]
0137:0113EBEB  CALL    010F3AB8
0137:0113EBF0  LEA     EDX,[EBP-18]
0137:0113EBF3  MOV     EAX,[EBX+00000310]
0137:0113EBF9  CALL    0112A05C
0137:0113EBFE  MOV     EAX,[EBP-18]
0137:0113EC01  LEA     EDX,[EBP-14]
0137:0113EC04  CALL    010F7F24
0137:0113EC09  MOV     EDX,[EBP-14]
0137:0113EC0C  MOV     EAX,EDI
0137:0113EC0E  CALL    0113DFFC <- Calculate the serial
0137:0113EC13  CMP     DWORD PTR [EDI+08],00
0137:0113EC17  JZ      0113EC89
0137:0113EC19  MOV     EDX,[EDI+10]
0137:0113EC1C  MOV     EAX,[EDI]
0137:0113EC1E  CALL    0113DDA0 <- Calculate hardcoded serial
0137:0113EC23  TEST    AL,AL    <- Test if good serial

End partial code
Okay, the comments are pretty clear :) Now, we are not interested in the serial for our username, but interested in the hardcoded one. Therefore trace into the "0137:0113EC1E CALL 0113DDA0". You should see this

Start partial code

0137:0113DDA0  PUSH    EBP
0137:0113DDA1  MOV     EBP,ESP
0137:0113DDA3  MOV     ECX,00000004
0137:0113DDA8  PUSH    00
0137:0113DDAA  PUSH    00
0137:0113DDAC  DEC     ECX
0137:0113DDAD  JNZ     0113DDA8
0137:0113DDAF  PUSH    ECX
0137:0113DDB0  PUSH    EBX
0137:0113DDB1  PUSH    ESI
0137:0113DDB2  PUSH    EDI
0137:0113DDB3  MOV     [EBP-04],EDX
0137:0113DDB6  MOV     EAX,[EBP-04]
0137:0113DDB9  CALL    010F3E98
0137:0113DDBE  XOR     EAX,EAX
0137:0113DDC0  PUSH    EBP
0137:0113DDC1  PUSH    0113DFDC
0137:0113DDC6  PUSH    DWORD PTR FS:[EAX]
0137:0113DDC9  MOV     FS:[EAX],ESP
0137:0113DDCC  MOV     BYTE PTR [EBP-05],00
0137:0113DDD0  XOR     EAX,EAX
0137:0113DDD2  MOV     [01142BB4],EAX
0137:0113DDD8  MOV     [01142BB8],EAX
0137:0113DDDE  MOV     EBX,00000007
0137:0113DDE3  MOV     ESI,01140BD8
0137:0113DDE8  LEA     EDX,[EBP-10]
0137:0113DDEB  MOV     EAX,[ESI]
0137:0113DDED  CALL    0113CC78 <- Here is our hardcoded serial created!!
0137:0113DDF2  MOV     EDX,[EBP-10]
0137:0113DDF5  MOV     EAX,[EBP-04]
0137:0113DDF8  CALL    010F3DF4
0137:0113DDFD  JZ      0113DFAC
0137:0113DE03  ADD     ESI,04
0137:0113DE06  DEC     EBX      

End partial code

Voilà.....step over the call (=F10). The hardcoded serial is located in the EDX register. Type "d edx" to get it in the data window. I knew it was in the edx register as it was one of the registers that got another color in SoftICE after the execution of the call. That means that this value was changed in the call.
Ah, before I forget, you have to remove all "-" in the serial. Maybe that was used to trick us crackers :)

Last thing left is the anti-softice check which is very annoying as you can't have SoftICE active while running Spamkiller. (it gives a "division by zero" error). Fortunately it's very easy to remove: disassemble the Spamkiller.exe, goto the String References and search for "\\sice". Double click on it and you should see this:

Start partial code

* Referenced by a CALL at Address:
|:004D10AA   
|
:004AC1B0 55                      push ebp
:004AC1B1 8BEC                    mov ebp, esp
:004AC1B3 6A00                    push 00000000
:004AC1B5 33C0                    xor eax, eax
:004AC1B7 55                      push ebp
:004AC1B8 6832C24A00              push 004AC232
:004AC1BD 64FF30                  push dword ptr fs:[eax]
:004AC1C0 648920                  mov dword ptr fs:[eax], esp
:004AC1C3 A190094E00              mov eax, dword ptr [004E0990]
:004AC1C8 803800                  cmp byte ptr [eax], 00
:004AC1CB 740F                    je 004AC1DC
:004AC1CD 8D45FC                  lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"\\.\NTICE"
                                  |
:004AC1D0 BA44C24A00              mov edx, 004AC244
:004AC1D5 E8A27BF5FF              call 00403D7C
:004AC1DA EB0D                    jmp 004AC1E9

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004AC1CB(C)
|
:004AC1DC 8D45FC                  lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"\\.\SICE"
                                  |
:004AC1DF BA58C24A00              mov edx, 004AC258
:004AC1E4 E8937BF5FF              call 00403D7C

End partial code
To prevent Spamkiller checking for SoftICE, just put a 'ret' instruction in the very beginning of the call. That makes:

Before patching: 004AC1B0 55 push ebp
After patching: 004AC1B0 C3 ret

That's it my dear reader!
IV. In the end

Goodbye fellow cracker. Hope you learned something.
I didn't mention the serial in this essay because I want my site to be neutral. In that way I prevent problems with software authors and that way I keep away "i want a serial"-people.
Thx and greets goto:
Lazarus (you also have a nice site :-] )
Nitrus (for givin' me some advice on c++)
Magic Mike (for helping me when I was a real newbie)
R!sc (for helping me with many other things)
....and all other crackers on #cracking4newbies and EVC.

Greets

BlackB

Endnote:
Essay written by The Blackbird © 1999-2000
This essay can be freely distributed/ published/ printed etc... as long as no modifications are made.