CRACK FOR SIREN MAIL 3.0.0 (32-bit for Windows'95 and NT)
by Greythorne the Technomancer, April 1997
HCU


Courtesy of fravia's page of reverse engineering
I am using Siren Mail 3.0.0, the executable is called SMWIN.EXE 
and has a size of 1,867,264 bytes. 
You'll find it at Siren's home company page, they have
also a  ftp site (no "register me" to get a copy needed)

Siren Mail is a program very similar to Eudora, with a decent amount 
of functionality.

Run the program and you will see SIREN MAIL TRIAL, a TRIAL COUNTER, 
and a REGISTER button.

Try register and you will get a nice screen that allows you to enter a 
registration number, based on a serial number which is also displayed at the 
top of the window.

What nice possibilities we have here!

Originally I wasn't going to crack this program because someone I know 
had a registered copy at work, with a valid registration key, and needed 
the program installed on a home machine.

No problem I said... I copied down the code, zipped up siren mail, and 
for good measure even made a copy of all .ini files in windows 
(pkzipped of course as INI.ZIP) 
- standard practice for me anyway, because i am sneaky like that. 
hehe.

So I unzipped it on the other machine and ran it. To my surprise, the 
program DID NOT ACCEPT the code that was used at work, on EXACTLY THE 
SAME COPY of itself.

Pretty sneaky of them to foil me like that I thought, so it would seem 
that to crack this damn thing I would need to make a key generator 
(ugh) or crack it outright (my favorite option)

Since dead listing approach worked well for me (last week) when I cracked 
WLCHECK and published the results in +ORC tutorial 4.1 (available on the 
web, for instance here but not with Microsoft exchange :-). 
I decided to go that approach. Besides, I have gotten to quite like the 
win32 disassembler - NEAT PROGRAM!

After using W32DASM7 - which was cracked partially by Frog Prints, and 
finished by me (here it is), I opened up the file 
WS.TXT and scanned for TRIAL MODE

Here is the code I landed in.

:0046D7CE-(THE_COMPARE) 837D0801  cmp [ebp+08], 1		
:0046D7D2 0F850E000000            jne 0046D7E6			

:0046D7D8 6A00                    push 00000000
:0046D7DA 6A00                    push 00000000

* StringData Ref from Data Obj ->"Invalid Registration Number. 
				Program "	"will run under trial mode."
                                  |
:0046D7DC 68C09A5700              push 00579AC0
:0046D7E1 E82AB60B00              call 00528E10

notice the compare and jump above...
it looks immedialtely to me like a 'if registered, skip the nasty 
message'and it is.
just change either the compare to ZERO rather than ONE, or
the 0F85 to 0F84 (JNE becomes JE) and now we have cracked 
the registration key screen so that it allows you to enter 
any key (except the RIGHT one however) and exit happily.

Actually, I took it a bit further and decided to make it work for 
any key. I did this because some people i know have registered copies 
for real, and if my cracked version got around, it would matter, 
since even the REAL codes work.

So being the stubborn mule i am, i worked up a fix so that the JNE 
always jumps away. by giving it a 00000001 every time... a 
mov [ebp+08], 1 seems like it would work, but it doesnt matter: 
it takes up too many bytes.

I know a quicker way...
First of all, when a compare of any sort is made, the result is left in 
ax (eax) so we can make eax be what we want.

33 C0	xor eax,eax	(clears eax to zero)
40	inc eax		(adds 1 to it)
90	NOP		(just to fill the extra space)

3 bytes, about as tight as we could write it :)

replacing the 837D0801  with  33C04090 does the trick,
and the JNE goes along on it's merry way.

ANYWAY,
For the sake of getting work done, here is the whole call
courtesy of cut & paste:

Notice that I looked at where all the jumps took me and did a quick 
'find and replace' 0046d752' so that it says GOODBYE.
That helped me alot as you can see how many places it bailed out
of the function. (important to us to see what is going on)

----------------------------------------------------

* Referenced by a CALL at Addresses:
|:0046E46D   , :0046E53F   , :0046E5D9   , :0046E65A   , :0046FCDA   
|
:0046D735 55                      push ebp	"Invalid Registration Number. 
				Program "	"Siren Mail Trial"	"Trial Count:"
                                  |
:0046E4E3 68589C5700              push 00579C58
:0046E4E8 8B4DE8                  mov ecx, [ebp-18]
:0046E4EB 83C15C                  add ecx, 0000005C
:0046E4EE E85C220B00              call 0052074F
:0046E4F3 A12CB35800              mov eax, [0058B32C]
:0046E4F8 50                      push eax

We have to backtrack a bit more than in the first try to find 
our comparison, but here it is:

:0046E475 83F801                  cmp eax, 1		AM I REGISTERED?
:0046E478 0F8552000000            jne 0046E4D0	IF NOT, JUMP DISPLAY 
						TRIAL NOTICE ON NAGSCREEN

* StringData Ref from Data Obj ->"Siren Mail"	"Registration Key:"
                                  |
:0046E491 682C9C5700              push 00579C2C

Crack it as we did above.

0F85 -> 0F84     or     00000001 -> 00000000
or even 33C040 like I showed you for a more stylistic
and better crack.

Coupled with the previous crack of the registration screen above, 
we have cracked our naggers, but something bothers me about
a two-part crack that removes visible signs of a protection scheme.
----------------------------------------------------------------------------

Again, to make life easier on you, here is the full call from
beginning to end:

* Referenced by a CALL at Addresses:0046E60B   , :0046F3CB   
|
:0046E45F 55                      push ebp
:0046E460 8BEC                    mov ebp, esp
:0046E462 83EC18                  sub esp, 00000018
:0046E465 53                      push ebx
:0046E466 56                      push esi
:0046E467 57                      push edi
:0046E468 894DE8                  mov [ebp-18], ecx
:0046E46B 6A00                    push 00000000
:0046E46D E8C3F2FFFF              call 0046D735	
:0046E472 83C404                  add esp, 00000004
	
:0046E475 83F801                  cmp eax, 1		AM I REGISTERED?
:0046E478 0F8552000000            jne 0046E4D0	IF NOT, DISPLAY 
						TRIAL NOTICE ON NAGSCREEN

* StringData Ref from Data Obj ->"Siren Mail"	"Registration Key:"
                                  |
:0046E491 682C9C5700              push 00579C2C
:0046E496 8B4DE8                  mov ecx, [ebp-18]
:0046E499 83C15C                  add ecx, 0000005C
:0046E49C E8AE220B00              call 0052074F
:0046E4A1 A11CB35800              mov eax, [0058B31C]
:0046E4A6 50                      push eax

* StringData Ref from Data Obj ->"%ld"
                                  |
:0046E4A7 68409C5700              push 00579C40
:0046E4AC 8D45EC                  lea eax, [ebp-14]
:0046E4AF 50                      push eax

* Reference To: USER32.wsprintfA, Ord:0249h
                                  |
:0046E4B0 FF15D40F5900            Call dword ptr [00590FD4]
:0046E4B6 83C40C                  add esp, 0000000C
:0046E4B9 8D45EC                  lea eax, [ebp-14]
:0046E4BC 50                      push eax
:0046E4BD 8B4DE8                  mov ecx, [ebp-18]

* Reference to Dialog: DialogID_0098 
                                  |
:0046E4C0 81C198000000            add ecx, 00000098
:0046E4C6 E884220B00              call 0052074F
:0046E4CB E94D000000              jmp 0046E51D

* Referenced by a  Jump at Address:0046E478(C)
|

* StringData Ref from Data Obj ->"Siren Mail Trial"	"Trial Count:"
                                  |
:0046E4E3 68589C5700              push 00579C58
:0046E4E8 8B4DE8                  mov ecx, [ebp-18]
:0046E4EB 83C15C                  add ecx, 0000005C
:0046E4EE E85C220B00              call 0052074F
:0046E4F3 A12CB35800              mov eax, [0058B32C]
:0046E4F8 50                      push eax

* StringData Ref from Data Obj ->"%d"
                                  |
:0046E4F9 68689C5700              push 00579C68
:0046E4FE 8D45EC                  lea eax, [ebp-14]
:0046E501 50                      push eax

* Reference To: USER32.wsprintfA, Ord:0249h
                                  |
:0046E502 FF15D40F5900            Call dword ptr [00590FD4]
:0046E508 83C40C                  add esp, 0000000C
:0046E50B 8D45EC                  lea eax, [ebp-14]
:0046E50E 50                      push eax
:0046E50F 8B4DE8                  mov ecx, [ebp-18]

* Reference to Dialog: DialogID_0098 
                                  |
:0046E512 81C198000000            add ecx, 00000098
:0046E518 E832220B00              call 0052074F

* Referenced by a  Jump at Address:0046E4CB(U)
|
:0046E51D 6A00                    push 00000000
:0046E51F 8B4DE8                  mov ecx, [ebp-18]
:0046E522 E83B190B00              call 0051FE62
:0046E527 E900000000              jmp 0046E52C

* Referenced by a  Jump at Address:0046E527(U)
|
:0046E52C 5F                      pop edi
:0046E52D 5E                      pop esi
:0046E52E 5B                      pop ebx
:0046E52F C9                      leave
:0046E530 C3                      ret
-----------------------------------------------

Now, what we have done is two important cosmetic 
changes to the program, which now
1) allows you to enter any registration code you like, and
2) does not display a TRIAL VERSION notice  on the main screen

What if there are hidden parts to this we don't know of?
There may be, there may not. Regardless, we have to make 2 
changes in the software to effect an 'after the fact' crack. 
In other words, we have only found the results of the 
crack and removed them. If there are other results that we 
haven't found, then there would be a problem, and the crack 
would not be complete.

To make sure, I figured that the MAKE IT REGISTERED code was 
somewhere nearby, go figure: we originally looked in the ENTER 
YOUR REG CODE call, and found a way to disable the nagscreen 
that came with it... but if we could do that, why not look at 
that piece of code a little further... if we can enter a code 
there, we SHOULD BE ABLE to make it register there.

Looking at the call again from the top... this time seeking 
some basic compares or suspicious values being set:

* Referenced by a CALL at Addresses:0046E46D, :0046E53F, 
				:0046E5D9, :0046E65A, :0046FCDA   
|
:0046D735 55                      push ebp			
:0046D736 8BEC                    mov ebp, esp
:0046D738 83EC04                  sub esp, 00000004
:0046D73B 53                      push ebx
:0046D73C 56                      push esi
:0046D73D 57                      push edi

:0046D73E 833D1CB3580000          cmp dword ptr [0058B31C], 0	
:0046D745 0F8507000000            jne  0046D752	
:0046D74B 33C0                    xor eax, eax				
:0046D74D E99B000000              jmp 0046D7ED-(GOODBYE)					

The compare 0 looks interesting, notice the xor which resets eax 
to zero? Changing the JNE to a JE (0F 85 becomes 0F 84) results in 
something we had accomplished before... it ALSO allows acceptance 
of any value on the screen where we typed in a sample registration 
code.

That didnt do us any good. See, but that isn't a 00000001 is it? 
and our codes have been checking for a value of 1 which is what the 
registered flag should be (have you been following? :)

Go on down just a little farther and you will hit a MUCH NICER 
fellow... 

:0046D770 39051CB35800            cmp [0058B31C], eax	
:0046D776 0F850F000000            jne 0046D78B		
:0046D77C B801000000              mov eax, 00000001		
:0046D781 E967000000              jmp 0046D7ED-(GOODBYE)	
:0046D786 E962000000              jmp 0046D7ED-(GOODBYE)

whereas before you had compares to 00000001, this one MAKES eax
= to 1. This, my dear friends, is the main registered-version 
flag setter! Want to test for yourself? go for it :)

Changing the JNE from 0F85  to 0F84 cracks it completely!
(In my copy i still do the 33C040  changes on top of this since
they allow even good codes to work - just my style I guess ;)
So then here is the complete crack for this program:
*******************************************************
Crack for Siren Mail 3.0 by Greythorne The Technomancer
(April 1997)
find this data: 051CB358000F850F
change it to: 051CB358000F840F
*******************************************************

Enterprising crackers may want to make a fix for the compare
using XOR's instead for a better crack - I did ;)

33C0 33C0 33C0	 (this clears EAX 3 times in order to fill 
		  the 6-byte space where the compare was)

Another thing:
the crack location with the compare, compares the REAL ECHO at the 
point of breaking... in other words, i ran sirenmail (unregistered) 
and breakpointed on MESSAGEBOXA in order to break into the program 
at any old point because it seems to be a 1 to 1 exact comparison 
between this program and wdasm's output...
the location :0046D770 in W32DASM7 is EXACTLY  0137:0046D770 inside 
softice... even if it wasnt, you could enter a 00 in the hex editor 
at the crack location compare and softice would trap it there anyway 
(GPF, but it works nonetheless)

Now, bpx on 0137:0046d76d (the compare as seen below)
:0046D76D 8B45FC                mov eax, [ebp-04]
:0046D770 39051CB35800          cmp [0058B31C], eax  

Let's make a key generator!


looking back at the code of the compare we just looked at,
we see the mathematical part of the protection routine 
(important code is explained)

:0046D752 A118B35800     mov eax, [0058B318]	;get the program's serial number
:0046D757 8945FC         mov [ebp-04], eax	;(store serial number)
:0046D75A B90B000000     mov ecx, 0000000B	;ecx becomes B (11 in deximal)
:0046D75F 8B45FC         mov eax, [ebp-04]	;(get serial number)
:0046D762 99             cdq	               ;(doesn't seem to do anything)

:0046D763 F7F9           idiv ecx		;divide eax (serial num) by ecx (11)
:0046D765 05AB909600     add eax, 009690AB	;add this number to eax

:0046D76A 8945FC        mov [ebp-04], eax    ;(store new code)
:0046D76D 8B45FC        mov eax, [ebp-04]	;(get new code)

:0046D770 39051CB35800  cmp [0058B31C], eax	;compare new code to your typed one

NOW WE KNOW WHAT THE MATH OF THE PROTECTION IS
simply: serial number / B(hex) + 9690AB(hex)
that's it! The key generator is therefore:
************************************************************
#include 
int main()  /* compiled with borland c/c++ 4.5 */
{
        unsigned long code;
        printf("Keymaker for SIREN MAIL 3.0.0 / 32-bit\n");
        printf("By Greythorne the Technomancer - April 1997\n\n");
        printf("Enter your serial number (do not include dashes): ");
        scanf("%U",&code);
        printf("Creating key for %lu\n",code);
        code = code / 0x0B;
        code = code + 0x9690AB;
        printf("Your code is %lu\n",code);
}
*************************************************************
For the softice guys out there: it is easy enough to breakpoint
on the start of the code, step through each step one by one and
check eax at each point (and the data locations) so it is simple
to determine what values do what for us.
I hope this work shows the possibilities one can grasp with the 
dead listing methode, and then some :)


After all this, is there something else I could do to crack this better?
I get to show you how to make this program become its own key generator!!!

To do this we must look at two places in particular;
The code generator itself, and the registration screen that displays the
registration code.

HERE IS THE CODE GENERATION ROUTINE AGAIN:

:0046D752 A118B35800     mov eax, [0058B318]    ;get the program's serial number
:0046D757 8945FC         mov [ebp-04], eax      ;(store serial number)
:0046D75A B90B000000     mov ecx, 0000000B      ;ecx becomes B (11 in deximal)
:0046D75F 8B45FC         mov eax, [ebp-04]      ;(get serial number)
:0046D762 99             cdq                    ;(doesn't seem to do anything)

:0046D763 F7F9           idiv ecx               ;divide eax (serial num) by ecx (11)
:0046D765 05AB909600     add eax, 009690AB      ;add this number to eax

:0046D76A 8945FC        mov [ebp-04], eax    ;(store new code)
:0046D76D 8B45FC        mov eax, [ebp-04]    ;(get new code)

:0046D770 39051CB35800  cmp [0058B31C], eax     ;compare new code to your typed one 
    The real code is in eax, and the one you typed in is at [0058b31c]
(note that compares erase eax so the code is lost after this line is 
executed)

:0046D776 0F850F000000  jne 0046d78B	; jumps away if eax not zero
:0046D77C b801000000  mov eax, 1		;registers the program

...AND HERE AGAIN IS THE IMPORTANT DATA FROM THE REG SCREEN:

* StringData Ref from Data Obj ->"Registration Key:"
                                  |
:0046E491 682C9C5700          push 00579C2C
:0046E496 8B4DE8              mov ecx, [ebp-18]
:0046E499 83C15C              add ecx, 0000005C
:0046E49C E8AE220B00          call 0052074F
:0046E4A1 A11CB35800          mov eax, [0058B31C] 
Thank you for tuning in!
+gthorne'97

+gthorne 1997. All rights reversed.

You are deep inside fravia's page of reverse engineering, choose your way out:

homepage links red anonymity +ORC students' essays
academy database tools cocktails search_forms mail_fravia