http://www.scootersoftware.com - Webpage (~850k).
Firstly, thanks go to tnwo for suggesting this program. Beyond Compare uses a 2 stage proprietary algorithm which might appear banal but is a little trickier to understand than some. In this tutorial I'm not going to quote many code snippets, instead I'll make reference to the pertinent calls and addresses. The program requests a user name and organization, both are used in the scheme. To gain an entry point you'll need to bpx hmemcpy / (bmsg under NT) and F12 through the standard stack patterns (11 presses), you can then trace your way with F10.
:00478193 CALL 00471F50 <-- Great protection routine.
:00478198 TEST AL,AL <-- As per usual flag AL.
:0047819A JNZ 004781A3
You must trace 00471F50. The first part of the protection uses a hard-coded in prefix (Beyond Compare 1), to this will be added your name and organization (all of these are uppercased). The resulting string using my name as an example is as follows (note the spacing or lack of it).
BEYOND COMPARE 1CRACKZMEXELITE
The first stage of the algorithm starts at address 0047034E (beneath CALL 00470308) and performs a 3 pass manipulation which is actually simpler than it first looks. Each character from the above string is passed through this loop, the loop acts as a filter, the resulting bytes are stored for use in the 2nd stage. The 2nd stage (address 0046327C) takes the resulting bytes and passes them through a 2nd algorithm which generates a value in ESI. The lower value of SI provides an index into an array of dwords which is 1k in size i.e. (00-FF = 256 * 4).
We'll now construct this key generator step-by-step. Evidently we might not need to implement some of the inefficient fiddling that occurs, in both algorithms the 'BEYOND COMPARE 1' string will always produce a constant set of results although when we implement the key generator it might be easier not to use this fact. The first algorithms handling of 20h chars. is tricky to get right, because I'm a lazy coder I elected just to ignore them and patch the memory with 00 which of course I'll check for in algorithm 2, the program itself actually shifts the entire string when it finds a space.
Algorithm 2 uses a dword lookup table which in theory is 1k in size, however in reality the higher end of the table is never reached. Obviously we will need to implement this table (0047C840-0047CC3C), I recommend you use SoftDump to do this.
sdump95 beycomp.hex 1024
We firstly define a file dump name and the length in bytes of our data. SoftDump responds with a mapping address (in my case this is 82D48000). We enter SoftICE and bpx for address 00463290 (our table will be in memory at this point).
m 0047C840 l 1024 82D48000
Next we map memory address 0047C840 + 1k to our SoftDump mapping address, you can of course verify with SoftICE that the table is indeed mapped correctly, after exiting SoftICE we press Enter in SoftDump's window and the file is dumped to disk (view it with Hiew). If you take a closer look at the dump you'll realise that this table is in fact recursive, the same block of 64 bytes is repeated, you should also truncate the file at offset 400h (1024 dec). I really procrastinated on how to implement this table, loading it entirely into memory was one option but I couldn't be sure about clobbering parts of the program DATA. In the end I used an inefficient but more stable solution.
I figured that only 64 bytes needed to be accessible, each index greater than 16 decimal could be divided by 16 leaving a remainder that would give exactly the same table index. Attached you'll find my complete source code, its fairly substantial and might appear confusing at first, primarily because I wrote it quickly and without too much thought for clarity :-). I should like to add that this product is well-written and probably genuinely useful so if you have $30 and plan on keeping it, I'm sure the author would be grateful.