SSI Win32 Dongle Protection
Initial workaround for difficult Win32 targets
project3
Dongleling
22 January 1998
by Spyder
Courtesy of Fravia's page of reverse engineering
slightly edited
by Fravia+

Oh my dongle! Just one day after the spectacular essay by Quine here we have another incredibly interesting essay by Spyder... Dongle protection schemes 'as wrappers' seem to be all the rage now, and here you have another very sound approach to 'unwrapping' inn order to undongle... and I know that some friends working on Cubase will be VERY happy to read these recent essays...
Moreover I'm happy to notice that we are (finally) moving from the boring 'how I cracked this specific proggy gna gna gna' (who cares?) to the much more interesting, and important for anybody, 'object oriented' cracking (in this case 'Sentinel Oriented' of course :-)
I like a lot this work by Spider... may be a little note about this passage he wrote:
"...I haven't looked at the exact details of the 
main encryption, but it isn't weak. 
I'm pretty sure it is a rolling encryption...
I believe it would be interesting to have an add-on on this 'rolling encryption': is it a characteristic of Sentinel's schemes? How does it work? How is it implemented? Which tricks are 'rolling' inside it? Unless it is a banal "byte shifting" kind of rolling, which would indeed prove to be unimportant...
So... and now I'll leave you to this tasty reading, prepared for your reversing pleasure by our +contributor Shadow, that gave us a couple of months ago his sound essay about a fundamental tool of the trade: BoundsChecker.
Enjoy!


Related:
+packers
Packers
There is a crack, a crack in everything That's how the light gets in
Rating
( )Beginner (x)Intermediate (x)Advanced ( )Expert

This essay describes a method to work around a rather awkward dongle protection for Win32 programs using Sentinel dongles.
SSI Win32 Dongle Protection
Initial workaround for difficult Win32 targets
Written by Spyder


Introduction


This isn't a complete crack of anything, just a workaround which makes
a seemingly impossible crack possible.

I know little about dongles, or about the companies that make them. 
For this target the company is called "Sentinel", and if you see 
references to Sentinel, or SSI, then we are talking about the same 
thing. If you tried for a dead listing and found megabytes of garbage 
that's also a good (or bad?) sign.

I know little about the actual dongle code - never had to look at it -
setting breakpoints on printer port I/O or something is the *last* way
to start cracking any dongle-protected (aka dongled) program (IMHO).


Tools required

Borland Turbo debug.
Borland Tdump is handy.
A good binary editor
A good disassembler (can you say IDA?).


Target's URL/FTP

There is no specific target.

Essay

Why was this crack going to be so impossible? Well the dongle code is a
wrapper for a semi-protected executable. When the wrapper is applied
it encrypts most of the executable code, in fact it attaches to the end 
of the program and takes over the program entry point.

When the program is run, the dongle code gets control, and if it is happy
with the dongle it will decrypt the executable and pass control to it.
The executable can then call back into the dongle code to make whatever
specific dongle checks it wants, in  order to confirm that the dongle 
is still present at various times during execution.

So even if you crack the initial dongle code you will still need to
understand and patch the main executable. The encryption makes
understanding difficult and patching almost impossible. Fully cracking
the dongle code is unlikely to be an option. These types of dongles do
things like returning a value from a variable string passed to them, the
algorithm and keys to do this are actually sitting inside the dongle - 
there is no easy way of patching the dongle driver code to get the same 
result.

I haven't looked at the exact details of the main encryption, but it
isn't weak. I'm pretty sure it is a rolling encryption where changing
one byte will affect all following bytes which is why patching is so
hard.

I am also pretty sure that the encryption keys come out of the dongle
(they should work this way if the dongle suppliers have any sense) 
which means you are going to need the dongle at least for a couple of 
hours, but, you might also have SOME LUCK. "Cracking without luck it's 
as impossible as cracking without feeling".

If the program has a demo mode, or perhaps some kind of option for network
licensing, then it has to be decrypted without the dongle present, 
so it can run and then decide if it really needs a dongle or a network 
license or whatever in order to run fully.

So, knowing this, how do we work around it?

My approach is to undo what was done when the wrapper was applied,
re-creating something near enough to the original program before it was
wrapped, so that normal reversing techniques can be used.

Lets look at  some interesting bits of a tdump for a sample program:-

Entry RVA                0003D950
Image base               00400000

Object table:
#   Name      VirtSize    RVA     PhysSize  Phys off  Flags
--  --------  --------  --------  --------  --------  --------
01  .text     0001E200  00001000  0001E200  00000400  E0000020 [CERW]
02  .rdata    00000800  00020000  00000800  0001E600  C0000040 [IRW]
03  .data     00013E24  00021000  0000D200  0001EE00  C0000040 [IRW]
04  .PAD000   00000E00  00035000  00000E00  00000000  C0000080 [URW]
05  .SSINod   00007A00  00036000  00007A00  0002C000  E0000040 [IERW]
06  .rsrc     00000800  0003E000  00000800  00033A00  C0000040 [IRW]
07  .idata    00000C00  0003F000  00000C00  00034200  C0000040 [IRW]
08  .reloc    00000200  00040000  00000200  00034E00  42000040 [IDR]
 

SSINod is the added dongle code, PAD000 is where the original program
.reloc segment (which contains import addresses patched up during
program load) was. Image base is where the program gets loaded in a flat
memory model (most addresses are relative to this base). Entry RVA is
the program start address.

The next step is to get the program loaded and decrypted and into Turbo
debug. If the program runs and stays running while it presents an error
message then the best operating way is to fire up TD32 in a dos window 
and attach to the program. One of the wonders of Win32 debugging (dunno 
how it works): just pick File | Attach and select the window, after a 
while TD32 will get control of the program and you can look around. 
You might also be able to start the program with TD32 but getting 
control once it has run and decrypted isn't so easy. 
You may even be able to trust the memory image when the program has 
terminated or maybe look at the stack and find some locations where 
an hardware breakpoint can be set. 
I'm sure it's a lot easier with softice but softice (as far as I know) 
can't do what TD32 is about to.

Anyhow I assume you somehow managed to get control of the program 
using TD32. 

Have a look at the image base + .text RVA and make sure it looks 
like code, to confirm that the program was decrypted, if not then 
maybe you need to borrow a dongle from some friends and start again.

Now open up a dump window, go to (Ctrl-G) the image base address and
start marking a block by holding shift and dragging the mouse from the
required hex byte (block marking in TD32 is a bit strange and shift
cursor keys don't always work). Now go to the end of the .text segment
(which should extend the marked block). Select Block | write (Ctrl-B, W)
and TD32 will kindly dump the executable header and whole decrypted
.text segment to a file for you. 
TD32 seems to write such blocks at about 1-2kB per second, which is 
pretty slow, so you might take a coffee/cocktail break. 
(Sorry if I am being too specific about "driving TD32" but the first 
time I did this I didn't realise TD32 could dump memory blocks to
disk and I spent hours writing memory dump 'panes' to the log file 
and then I wrote a whole own-made program to turn the dumps back into 
binary, so I want to make sure that my readers will know this trick 
- a little knowledge sometimes goes a long way).

Now one more thing before we are done with TD32. Take a look at the
PAD000 segment. It will be mostly zeros and you will see a block of 
32 bit addresses.
These are the import entries which were patched up at load time in 
the .reloc segment and part of the dongle code copies them here, 
where the main executable expects them to be. 
The order and number of entries is not the same as in the .reloc 
segment so you can't do a simple copy of it, nor fiddle with RVAs 
to get them in the right place. 

Set an hardware memory write breakpoint on any of these locations 
and then restart the program from TD32 (Ctrl-F2).

TD32 should break in the middle of the dongle code which is copying
across these entries. Take a look at the code and -if it is like the
stuff I have seen- you will find a table of pairs (couples) of 32 bit 
addresses pointed to by ebx. 
These are pairs of relative (to image load) addresses inside .reloc, 
with the required relative address in .PAD000 for the same
import. Mark this table and dump to disk as before.

Now we are done with TD32 and -probably- with the dongle.

Putting it back together.

Now we have to insert the decrypted dump back into the executable, which
is really just binary editing of a sort, but rather tricky. 
Take another look at the tdump object table and understand what it 
means...

Entry RVA                0003D950
Image base               00400000

Object table:
#   Name      VirtSize    RVA     PhysSize  Phys off  Flags
--  --------  --------  --------  --------  --------  --------
01  .text     0001E200  00001000  0001E200  00000400  E0000020 [CERW]
02  .rdata    00000800  00020000  00000800  0001E600  C0000040 [IRW]
03  .data     00013E24  00021000  0000D200  0001EE00  C0000040 [IRW]
04  .PAD000   00000E00  00035000  00000E00  00000000  C0000080 [URW]
05  .SSINod   00007A00  00036000  00007A00  0002C000  E0000040 [IERW]
06  .rsrc     00000800  0003E000  00000800  00033A00  C0000040 [IRW]
07  .idata    00000C00  0003F000  00000C00  00034200  C0000040 [IRW]
08  .reloc    00000200  00040000  00000200  00034E00  42000040 [IDR]


The .text segment RVA is 1000 which means that in memory this is 
started at the image base + 1000 = 401000. 
The Phys off is where .text lives in the executable file. 
That means the decrypted dump has c00 bytes between 400 and 1000, 
which need to be cut. 
The executable file header is not encrypted, and in my experience 
it is always identical in the memory image. 
With you favorite editor, hack out the c00 bytes and paste
the dumped image on top of the executable.

Fixing the imports. We have this dump of pairs of addresses to move import addresses between .reloc and .PAD000 segments at start up. We should have plenty of space for code in the .SSINod segment as once the program is really cracked it shouldn't ever have to call inside there. I turned the binary dump into hex, then manually edited it into db assembler statements for any old assembler that can create a binary output file. Add A1h in front of the first address for a mov eax,[????] and A3h in front of the next for a mov [????],eax. Remember to add the Image load address to all addresses as they are also relative. Double check that you are loading from .reloc and storing into .PAD000. I just dumped this binary fragment into the executable at the start of the .SSINod segment. You might then want to patch up the Entry RVA in the executable header to point at this code (or patch a jump in later).
Where are we now? At this stage you should have an executable that has no encryption and will start running a lump of code that moves import addresses to where the original program expects them. The entry point probably points at this code but don't run it as the import patch is currently followed by dongle garbage. The executable should be exactly the same size as the original - if not I'm afraid you messed up the editing somewhere. Now you have something you can start cracking, fine for dead listing, but you will have to find the original program entry point and patch inside it a jump at the end of the import patching code before you can try to run it. If you are using IDA it may well discover the program entry point as a standard runtime library startup function although IDA seems not to automatically recognize the compiler in these reconstructed executables (select a signature manually). The other alternative is to debug another program built with the same tools to find what the entry point code looks like. You could even search for likely looking code, startup code will anyway probably call GetVersion pretty quickly. Once you have found and patched inside the original program entry point, the workaround is done. You have now an executable with the same function as the original before it was wrapped. The chances are that this program will still call into the dongle code but as the authors expected the dongle wrapper to make examination difficult and patching impossible they are unlikely to have done anything too sophisticated, and if they have, that suit us well: even more challenges!


Final Notes

Well I hope you found this interesting and perhaps useful. I haven't
seen this particular sentinel dongle encrypt anything more than the 
.text segment, indeed, it doesn't always encrypt the whole 
text segment.

The same recovery technique could be used for other encryption based
schemes but things get tricky where more than the .text segment is
encrypted. You would have to break and capture an image before the
program runs enough to 'smudge' its own data segments, the .reloc 
segment is particularly painful as the OS 'corrupts' that during 
loading (however, this kind of stuff is equally difficult for 
the protectors).

After having written this essay I read Quine's excellent HASP essay,  
published yesterday by Fravia+, where Quine shows how to dump 
large areas of memory with SOFTICE, among other marvels. 
The HASP protection sounds quite similar to my Sentinel one.
I suspect the Sentinel rolling encryption is more robust. I have also
seen Win32 HASP protected targets with no encryption (possibly because
they also had network licensing options).

Spyder


Ob Duh

I wont even bother explaining you that you should BUY this target program if you intend to use it for a longer period than the allowed one. Should you want to STEAL this software instead, you don't need to crack its protection scheme at all: you'll find it on most Warez sites, complete and already regged, farewell.

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

dongles
Back to dongleling

redhomepage redlinks redanonymity +ORC redstudents' essays redacademy database
redtools redJavascript wars redcocktails redantismut CGI-scripts redsearch_forms redmail_Fravia
redIs reverse engineering legal?