http://www.digfrontiers.com - Webpage.
Before I start, in order to follow this tutorial your going to need a decent image/photo editing program and an RGB image (the PhotoShop samples will do for that - I'm using guitar.psd). You might get away with using Paint Shop Pro as a cheaper alternative but I'm using Adobe for obvious reasons. I decided I'd wage a small mini-war against plug-in authors because these products are pretty much a rip-off.
The basic idea behind the plug-in scam is simple, these products always target Adobe PhotoShop users, who have already paid say £450 (UK) approx ($700) and therefore might have lots of money to waste on frilly add-ons. Instant price tripling. HVS ColorGIF doesn't look a bad program and I'm sure it has its uses, but I for one am unable to believe this is a product deserving of hard earned cash.
Enough background and to the reversing, the plug-in is pretty small and has a 30-day trial facility and a friendly registration option which I'll discuss briefly. We could crack the register scheme which is a serial number/unlock code affair, but forget doing it, it'll probably take too long to crack the maths. Instead we'll be a little more methodical. Firstly we'll trigger the time-out, then crack the registered status option.
Triggering the time-out changes the title text too "Expired Export Plugin - Call .....", you'll easily locate that reference inside W32Dasm (the file is hvscgu.8bf), sadly the text of the nag box that appears whenever you try to do anything is also nearby in the StringRef list.
:100142F6 MOV EAX, DWORD PTR [EBX+00000614] <-- Offset of flag.
:10014301 JZ 10014314 <-- Jump registered user.
:10014303 DEC EAX <-- Decrement.
:10014304 JZ 1001430D <-- Jump still on evaluation.
:1001434E MOV EAX, DWORD PTR [EBX+00000614] <-- Check it again.
:10014357 JZ 100143D4 <-- Good_jump.
You can either try bpxing for this code or patching in an INT 3, I did the
latter because of offset differences between the plug-in and W32Dasm. Sure
enough nasty-times up user has EAX = 2 when we'd really like 0, however the
checking isn't stupid because shortly afterwards the flag is checked again.
We'll patch these 2 snippets appropriately. Now the title bar says
Registered User and the Register button has disappeared.
Now we move to Apply something, its nasty message box time, so our initial string fishing was merely aesthetic, sadly the nag box text is in the clear and easy to locate (address 1001017F), its referenced by 4 conditional jumps, the first being 1000FF2C.
:1000FF1E MOV EAX, DWORD PTR [100179DC] <-- Address.
:1000FF23 MOV ECX, DWORD PTR [EAX+00000614] <-- Recognise this.
:1000FF29 CMP ECX, 00000003 <-- Query ECX = 3.
:1000FF2C JZ 1001017F <-- Bad jump.
:1000FF32 CMP ECX, 00000002 <-- Query ECX = 2.
:1000FF35 JZ 1001017F <-- Killing 2 birds.....
These first 2 conditional jumps go to our bad message box and the 614 pointer is a pretty shocking give away, we can easily kill this code by ensuring ECX is never 3 or 2 (its value doesn't matter), so lets just XOR it and forget about the 2 bad jumps. Regrettably for the program author we've got virtually an identical check at the other 2 bad conditional jumps (address 10010096) - patch them in similar fashion.
The fun however isn't yet over, and its a good idea to scan the disassembly for any more instances of this [register+00000614] flag. Just the 614 value (with the 0's) is a sufficiently narrow criterion. First instance is this code.
:10003B0A CALL 10006230 <-- Interesting function call.
:10003B0F MOV DWORD PTR [ESI+00000614], EAX <-- Move EAX to the flag.
I won't comment the function, needless to say there is a call to MSVCRT.time
and a lot of EAX flag setting. We can see that EAX good guy is at address
10006315 (MOV EAX, 1), however we'll check that 10006230 and the sub-functions
which determine EAX's value aren't called elsewhere. CALL's 10014F40, 10015110,
10014FD0 and 10006390 are of real interest and 3 of them are called
elsewhere. In fact we won't need to patch anything here because these
functions only set the 614 flag as I've dubbed it, not restrict the actual
functionality (thats done higher in the tree). 10006230 is only called once
so we'll just patch the DWORD PTR to 1 instead (thats trickier but fortunately
theres some free compiler generated space at the end and you can get
away with BYTE PTR).
Sadly there is another 614 flag reference which controls palette saving at address 10010BF7 and another at 100125E6. Fix them in a similar fashion as those discussed previously. As an aide to distribution you might like to also fix the Register option so that any serial # can be accepted (a small matter of a few bytes), this might not be necessary but safeguards against checks for registry presence of a "SerialNumber".
This completes the crack, however I'll just commend the author on a fairly good serial # scheme (tedious maths to reverse me thinks) and a commendable attempt to implement a lot of checks. The main weaknesses of this scheme are the ease of disassembly and the reliance on the same flag / maybe separate local variables though? because of the register swapping, MSVC has certain ways of doing things.