Cracking "Save disabled" protections

by Zero
("Dead listing" approach and "live" approach
a couple of lessons that the protectionists should head :-)

(14 July 1997, slightly edited by Fravia+)


Courtesy of Fravia's page of reverse engineering

Well, this project is finally on its way!... here you'll find not one but *TWO* essays by Zero, master of the "save disabled" protections.

I like what Zero writes:

By the way, although I am a beginner in software reverse engineering 
and practically learned everything from +ORC and his students' essays,
I never actually did any of the cracks they wrote about. At the beginning,
I have tried the famous pooldemo crack, but got bored after five minutes.
Cracking just looses it's fine taste if you already know all the answers.
So, IMHO the best way to use these essays is to understand the described
method and try it on other programs having a similar protection.
But if he's a "beginner" as he says, then I would like to find many other "beginners" working with this quality and with this kind of deep and clear methodical approach!

Cracking "Save disabled" protections


 It's getting very popular among software writers nowadays, to distribute crippled
versions of their program, where some important functions, (save, export
etc.) are not working. Usually, these demos try to suggest that the critical 
code is really missing from the program, so you have to get a full version
from the author to enjoy those functions, and cracking the demo would make 
no snese. 
As +ORC kindly pointed out for us, we should never believe blindly the 
statements of the programmers (nor of anybody else, for that matter). 
For example, if we disassemble a "save disabled" program and see that it 
calls the commdlg.getsavefilename routine, we can suspect some cheating.
 As you can guess, a number of these demos can be turned into full
versions quite easily. In this essay, I want to show you, how to crack
these demos if the protection is implemented through a master "demo 
version" flag.

Cracking Vector NTI demo

VNTI 4.0 demo for win95 from Informax, Inc. can be found at
ftp.informaxinc.com/pub/informax/vnti4/D40dw95.zip
The main exe file of this target is DI40DEMO.EXE (3 596 288 bytes)

 This is a really outstanding program for those who are in the DNA hacking
business, but probably useless for most of you. Never mind, the aim of this
essay is to show you how to crack *not* to give you some good program
for free. By the way, although I am a beginner in this cracking business
and practically learned everything from +ORC and his students' essays,
I never actually did any of the cracks they wrote about. At the beginning,
I have tried the famous pooldemo crack, but got bored after five minutes.
Cracking just looses it's fine taste if you already know all the answers.
So, IMHO the best way to use these essays is to understand the described
method and try it on an other program having similar protection.

 OK let's go back to our target. After installation and running, we see
that several functions - most notably exporting and importing sequences - 
are not allowed, but we get the nice message "This Function Deactivated
in Demonstration Version". Well, this message will be our hook.
 Let's try the dead listing approach first. (I suppose you have read the
relevant +ORC tutorials.) In the disassembled list of DI40DEMO.EXE we
search for the text "This Function Deactivated". It turns up at several
positions, the first one is listed here:

:00427D64 837D1003                cmp [ebp+10], 00000003
:00427D68 0F8507000000            jne 00427D75 "This Function Deactivated"
                                        ->"in Demonstration Version"
                                  |
:00427D86 68202E6D00              push 006D2E20
:00427D8B E86A471C00              call 005EC4FA <-send the message
:00427D90 83C40C                  add esp, 0000000C
:00427D93 33C0                    xor eax, eax
:00427D95 E9B4040000              jmp 0042824E <-leave

* Referenced by a Jump at Address :00427D7C(C)
|
:00427D9A 837D1001                cmp [ebp+10], 01 <-real work starts
:00427D9E 0F8535000000            jne 00427DD9
:00427DA4 837D0C01                cmp [ebp+0C], 00000001

 Well, what do we see here? Just four instructions before the demo message
is sent, there is a flag check, and if it's zero we are free to go on.
Very suggestive, but let's check first the other occurences of the demo
message. As we find out, exactly this type of flag check occurs before
each demo message is sent.
 It's time to see, where this flag is being set at the first place. We
search for the string "mov dword ptr [006DD2AC]" and find that it has only
three occurances, all in one part of the code.

* Referenced by a Jump at Address :00512A2B(C)
|
:00512A38 6898A66F00              push 006FA698
:00512A3D E8286C0D00              call 005E966A	<-checking subroutine
:00512A42 83C404                  add esp, 00000004
:00512A45 8945D0                  mov [ebp-30], eax "Bad or missing User Data file"
                                  |
:00512A79 680CFD6D00              push 006DFD0C
:00512A7E E8779A0D00              call 005EC4FA 
Cracking Dnasis ver 2.5 Demo

Dnasis 2.5 for windows from Hitachi Software can be found at
www.hitsoft.com:80/gs/dnasis/dnadmo25.zip
The main exe file of this target is DNASIS.EXE (3 019 264 bytes).

 After installation, we run DNASIS.EXE, open a sample file (pbr322.dna)
and observe that a couple of functions (Save As, Print, Copy etc.) are
not working, but send a message window with the text "This function is
not supported in demo version."
 Well, how should we attack this protection? Let's think a bit about, what
is happening between the selection of a menu item and the appearance of
the demo message. Obviously, there is a point in the line of the events,
where the information about which menu item has been selected, will be 
converted to an address, where there is code which responds to the actual
selection, and the execution of the code will continue on this address.
 Why is this important for us? Because, the decision whether to send the
demo message or execute the function will, probably, be made very close
to this conversion point. Why? Because, before this point the program is
not aware of which menu item was chosen, so it cannot decide to send the
demo message. After the main switch point, when the program starts
to work on the menu item specific code, it is unreasonable to execute tons
of useless code, just to decide, later, that a demo message was appropriate.
 Keeping this reasoning in mind, we can suppose that the decision about
the demo message is either wired into the process which produce the menu
item specific address or situated at the very beginning of the menu item
specific code. (Note, that this does not mean, we have a conditional
decision on our hand! It may very well mean that we'll just find a jmp to
senddemomessage routine at this place).
 Well, the aim is clear now! We have to find the main switch point and
snoop around it! We have to break in the line of events between the menu
item selection and the demo message appearence. The demo message is sent
in a new window, so we can try to break in at the user!createwindow
procedure.
 OK, first load Softice, load DNASIS.EXE then start the program and load a
sample file. Open the file menu, press ctrl-D and we are in Softice, now.
Set a breakpoint on the createwindow function:

:bpx createwindow

 The breakpoint is set, so go back to DNASIS and select the Save As menu
item. As the program wants to present the demo message we pop up in Softice
at the very first instruction of the user!createwindow procedure. At this
point the program has already decided to send the warning message so it has
actually passed the code we are looking for. Let's examine the stack.

:stack
NDVGM(53) at 3767:5EAC [?]
NDVGM(53) at 3767:570C [?]
NDVGM(53) at 3767:52EE [?]
NDVGM(53) at 3767:4D78 [?]
NDVGM(53) at 3767:4C7C [?]
NDVGM(53) at 3767:4C18 [?]
DNASIS(09) at 23AF:3F80 [?]  USER!CREATEWINDOW at 17B7:07F1 [?]

 It shows us through which calls we arrived to the createwindow procedure.
(Forget about my comments on the right, for a moment!) We could now set
breakpoints at this addresses and run the program to find out at which
point the Save As specific code starts, but it would take far too much 
time.
 It's better if we follow the above described procedure when we select 
other menu items, too. In that way, we can compare the stack results of the
different menu selections - working ones and disabled ones - and we'll 
probably find what we want. 
So do the bpx createwindow + our stack "magic" when you choose another menu 
item which gives the demo message (say "Print") and yet another menu item 
which does not send the demo message, yet creates 
a new window as well (say "New"). For Print we get the following stack result:

NDVGM(53) at 3767:5EAC [?]
NDVGM(53) at 3767:570C [?]
NDVGM(53) at 3767:52EE [?]
NDVGM(53) at 3767:4D78 [?]
NDVGM(53) at 3767:4C7C [?]
NDVGM(53) at 3767:4C18 [?]
DNASIS(09) at 23AF:3F80 [?]  USER!CREATEWINDOW at 17B7:07F1 [?]

But we get this one for "New":

NDVGM(53) at 3767:570C [?]
NDVGM(53) at 3767:52EE [?]
NDVGM(53) at 3767:4D78 [?]
NDVGM(53) at 3767:4C7C [?]
NDVGM(53) at 3767:4C18 [?]
DNASIS(09) at 23AF:3F80 [?]  USER!CREATEWINDOW at 17B7:07F1 [?]

 Comparing the three stack results, we can pinpoint where the menu item
specific code is executed (see my comments on the right, now). We can see
that the last common point from the beginning, in the three different
execution pathway, is the call at DNASIS(09):3F80 (the selectors in your
listings are different from mine so I'll use the DNASIS(module number)
description from now on). Here the program calls the main switch routine,
which pass the execution to the menu item specific codes.
 We can observe another thing, too. There is a small difference between
the execution path of the Print and the Save As functions, which otherwise
produce the same demo message result. Therefore, the decision about the
demo message is not wired in the menu item specific address decoding
process, since it generates two different addresses for Save As and
Print. If it were the other way, the same address (the address of the
"senddemomessage" routine) would be generated for the two different menu
items. This means that the decision of sending the demo message is
generated inside the menu item specific codes. With this knowledge, we set a
breakpoint at DNASIS(09):3F80. (Remove all other breakpoints and mind your
own selector)

:bpx 23af:3f80

 Running DNASIS we have a conferm that the process of every menu item 
selection goes through this point. Let's step inside the call with F8 
and we find ourself in the menu item selection decoding subroutine 
(at DNASIS(02):064B).
We step through the code with F10 until we come to this part:

246F:082C  7714                JA      0842
246F:082E  2D6500              SUB     AX,0065
246F:0831  8BD8                MOV     BX,AX
246F:0833  83FB0A              CMP     BX,0A
246F:0836  7603                JBE     083B
246F:0838  E93F0B              JMP     137A
246F:083B  03DB                ADD     BX,BX
246F:083D  2EFFA75D14          JMP     CS:[BX+145D] 


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

homepage links red anonymity +ORC students' essays tools cocktails
search_forms corporate mailFraVia
Is reverse engineering legal?