http://www.pegasusimaging.com - FTP : jpgwiz.exe (1.88Mb)
Well this tutorial was born by my recent need for a JPG compressor for this webpage, however our enjoyment of this very good soft. is soon to be marred by the authors crude insistence of watermarking any compressed JPG's with the Pegasus Imaging Corporation's logo. The protection is a serial # affair and I'll describe the algorithm with a key generator below, finding the good code in the clear is easy enough, finding the real-routine a little trickier, yet not much.
Now here's what I really wanted to investigate. Anyone can figure that unless you register this software its nigh on useless, no-one is going to want to watermark their JPG's with someone elses logo, thus I reckoned these guys actually wouldn't mind someone breaking the protection because they would somehow be able to take a registered users JPG and decode the user name from it. Preliminary inspection of the registered version's output shows the header is clearly marked.
Lets firstly reverse the registration scheme. I bpx'd for hmemcpy and used around 10 F12's, through the usual stack pattern, this is the top-level code which you've probably seen so much:-
:004C0F96 MOV EAX, DWORD PTR [EBP-10] <-- Code Entered.
:004C0F99 LEA EDX, DWORD PTR [EBP-0C]
:004C0F9C CALL 00408344 <-- Protection Scheme.
:004C0FA1 MOV EDX, DWORD PTR [EBP-0C] <-- Code Entered.
:004C0FA4 MOV EAX, DWORD PTR [EBP-08] <-- Good Code.
:004C0FA7 CALL 00404014 <-- Compare.
:004C0FAC JNZ 004C114D
To find the algorithm do a simple memory search at 004C0F96 and bpr on copies of your user name (there are 3) but 1 may well have a rather intriguing suffix attached (PegasusJWIZBC111). F5 no more than twice and you'll be at the start of the generation routine (004C0E59). Lets take some notes as we calmly step through the scheme. The routine isn't a particularly bad one, with a table of words, an inner loop and some neat increments, at 004C0EB0 EBX holds the Registration #. Here the summary.
:004C0E59 MOVZX EAX, BYTE PTR [EAX+EDX-1] <-- Get
individual name chars.
:004C0E6D INC [EBP-0C] <-- Increment DWORD Var 1.
:004C0E75 MOV EDX, 005345FC <-- Table of WORD's.
:004C0E9D INC [EBP-10] <-- Increment DWORD Var 2.
:004C0EAB DEC [EBP-14] <-- Holds length.
I always find that its a good idea to use the same registers as the protection when you write a key generator, you'll find my ASM source code at the end of this tutorial (its fairly untidy) but does demonstrate some useful ideas, of note is the fact that I didn't actually want to type in the table used by the program (very tedious DB lists), instead I used IceDump to dump the area to disk and the key generator merely opens the file.
Next I used JPEG Wizard to compress the same example JPG file (my site logo in fact) with firstly my real name and then with 'CrackZ', sadly my hope that there would be a conspiracy of some sort was dashed, there were no differences between the files which is kind of surprising considering the possibility to encrypt trivially such information.