http://www.extensis.com - Webpage (4.73Mb).
The second target in my mini-war against plugins is Extensis PhotoFrame, a fairly useful if slightly dull program that adds "image frames and border effects to your PhotoShop images" - sic. Like most other plugin authors Extensis is keen to justify your payment, they even wasted their time producing a productivity guide, an instant indication that the product doesn't really have a genuine use. The evaluation version has a 30-day trial facility with serial # register option, initially I was just planning on showing readers how to reverse the time-trial etc and force the program to behave as a registered version.
However that was before I delved in and took a brief look at the serial # algorithm, it is unbelievably stupid and implemented by a programmer who obviously thought he was making life difficult for the cracker, so we'll study that instead as theirs no point cracking something that takes 5 minutes to register. Like all plugins, you'll need something like PhotoShop to actually do anything with them, Extensis will also work with QuarkXPress (another expensive product).
Unlike most other programs Extensis use an external dll (looks like an off-the-shelf product) to do the registration work, the dll exports a whole load of functions which are then called by the plugin. Any decent installation monitor would have found you that file, its frameReg.dll in the SYSTEM directory. This 236k of protectionist squalor looks pretty good inside W32Dasm so grab yourself a quick deadlisting. In fact after cracking this I realised that it may have even been possible to crack the serial # without ever firing SoftICE.
Sift the string references for "You must enter a valid serial number...", then walk back a single conditional jump to this code.
:10002747 PUSH 1002D208 <-- Push the default 1st part
of the code.
:1000274C CALL 10001F50 <-- Call incredibly stupid maths routine.
:10002751 ADD ESP, 10 <-- Correct the stack.
:10002754 TEST AX,AX <-- Test AX = 1 (good), 0 (bad).
:10002757 JZ 10002775 <-- Goodbye_bad_cracker.
The first mistake the protectionist makes is with the serial number input box, which oh-so helpfully tells you the form of the serial #, they are all xxx-###-###-###-######, the first part of our protection then uses lstrlenA to check the code is of length 16h (22 decimal). Moving on we find the first real checking code which uses positions 1, 2 and 3. Just ensure you use BCE as the first 3 letters and you can kiss goodbye to this check. The next check is soon up, this time using positions 5, 6 and 7.
:10001F98 MOVSX AX, BYTE PTR [EDI+4] <-- 5th.
:10001F9D LEA EDX, DWORD PTR [EAX+4*EAX] <-- 5th * 5.
:10001FA0 MOVSX AX, BYTE PTR [EDI+5] <-- 6th.
:10001FA5 LEA EAX, DWORD PTR [EAX+2*EDX] <-- 5th * 10 + 6th.
:10001FA8 MOVSX DX, BYTE PTR [EDI+6] <-- 7th.
:10001FAD LEA ECX, DWORD PTR [EAX+4*EAX] <-- work it out *smile*.
:10001FB0 LEA ECX, DWORD PTR [EDX+2*ECX-14D0h] <-- Final polish.
:10001FB7 CMP AX, WORD PTR [ESP+14] <-- ESP+14 is a default of 64h (100dec).
:10001FBC JL 10001FE4 <-- Jump less and its bad.
:10001FC3 JG 10001FE4 <-- Jump greater and its also bad.
So we can see what the result is and now you've readied your calculators in advance to hack back through the maths. Lazier reversers are perhaps thinking its only 3 numbers, maybe they could guess high/low with SoftICE and quickly find the result, in fact this routine is just plain stupid because the correct result is actually 100 which of course was the ending value, the programmer obviously wanted you to hack back through the maths, there is no need, he gave you the result. In fact you could have coded a very quick program to test all the values anyhow so the protection is fundamentally flawed.
The final real check beneath CALL 10002070 uses positions 12, 13 & 14, theres actually a call before this which manipulates the first 3 default letters and the last 6 digits, producing a result in (E)AX which is then the correct result for the final check. The maths is eminently similar to that which we've seen before except the programmer throws in a SHL (shift left) to make matters more complex, as we saw earlier you could crack the algorithm with brute-force techniques, but is it worth the time when the programmer gave you the answer?.
Tracing through this with a bogus code I quickly found some working serial #'s - BCE-100-222-227-444444, BCE-100-000-500-654321, there are evidently many others all depending on your choice of the last 6 digits. Since writing this tutorial I have actually come to appreciate that PhotoFrame is quite a useful tool although the register now/later option drives me nuts :). In all the protection is probably adequate although I cracked it in under 10 minutes of SoftICE, Extensis may like to consider using the maths to create a real pain in the neck of an algorithm that couldn't be brute-forced in 20 seconds, using defaults is basically a bad idea in any scheme. The dll also needs serious protecting. Your comments are welcome as always.