http://www.fortres.com - Webpage.
Greetings once again challenge seekers. I received Fortres 101 as a request in my e-mail a week or so back hence the tutorial. Fortres is a security tool for system administrators that looks as if it could only run effectively under Windows NT, 95 users could probably kick out to DOS or interrupt its loading sequence (disabling msdos.sys probably isn't effective enough). The program is supposed to control employees who might undertake malicious campaigns against their systems (wouldn't just sacking them be a better idea?).
On to the reversing, the first problem came when I ran the setup program, its an InstallShield package with password, normally I wouldn't bother forcing these (this time however I'm not sure if the password can be obtained via e-mail), needless to say this password can be brute-forced pretty easily, the program merely adds up all the letters ASCII values, multiplies them by 2 and adds them to a default (F143ACh), before XOR'ing the result with 51933h to determine whether or not the checksum (F45129h) matches.
Simply work out the desired result from the password by XOR'ing F45129h with 51933h, as shown below.
F 4 5 1 2 9 0 5 1 9 9 3 ----------- XOR F 1 4 8 B A
Elementary brute-forcing gave me 'ffrlhu' in under 3 minutes (just try this with SoftICE and GetWindowTextA - recall that you need to delete a char. to trigger the bpx). The install proceeds merrily on, next up is the "serial # insert box". Again, unless you really want to be in for a long haul study of the InstallShield script don't bother trying to crack at this stage, install as a trial and hope that the protection implemented outside of the install script is easier to track down.
Launching appmgr.exe gives no visible signs of restriction, however a quick look with a grep tool ought to find you F101CFG.dll. Disassemble that with W32Dasm and take a look at those function imports, FGCREG.RetrieveSerialNumber is such an intuitive name I think :), I just can't imagine what it does. Now take a little look at FGCREG.dll (installed in the SYSTEM directory - 40k of protectionist coding). Just feel your way around this dll, try for instance to locate the code that checks whether a good serial # is of length 11h, then take a look for an instruction featuring a hyphen (2D).
A plethora of potential approaches are now available, the first thing we'll do however is remove the time-trial from fortres.exe (actually we would be better served by fixing the dll returns but follow this code anyhow).
:00401028 CALL FGCREG.OKToRun <-- I wonder what this
:0040102D XOR EBX,EBX <-- Clear EBX.
:00401032 CMP EAX,EBX <-- EAX holds OKToRun return.
:00401034 MOV DWORD PTR [EBP+08], EAX <-- Store it for next check.
:00401037 JNZ 0040107D <-- Good_jump_over_time_trial_expiry.
This is really simple, you could just force the JNZ-->JMP and use the compare address space to fix EAX to a suitable value (say 1). However, lets get back to our main dll which exports all of these functions, FGCREG.OKToRun does a fair amount of registry key accessing (reading and closing), I recommend you use the Symbol Loader and trace the function, note that there are 3 possible outcomes.
EAX returned = 0 (XOR EAX,EAX) = time-expired.
EAX returned = 1 (PUSH 1, POP EAX) = good guy, no nag box.
EAX returned = 2 (PUSH 2, POP EAX) = time still available, display nag.
Trace the function through, at 10001123 the program starts doing checks on the date, you ought to assume that a really nice buyer never gets his expiry checked :), here's the first piece of interesting code.
:100010E8 PUSH 10008050 <-- "Value".
:100010ED MOV [EBP-08], 10
:100010F4 PUSH [EBP-0C]
:100010F7 MOV DWORD PTR [EBP-04], EDI <-- Store EDI.
:100010FA CALL ESI <-- RegQueryValueExA.
:100010FC TEST EAX,EAX <-- Check EAX.
:100010FE JNZ 1000117E <-- Jump_and_don't_check_date.
You'll be able to find this "Value" string by searching the registry:
If you delete this value, the call to RegQueryValueExA should fail by setting EAX non-zero (you can verify this if you so desire). The code continues, this time we'll need to add a binary value, "Config" must exist else we'll XOR EAX,EAX and return, create that value now, this is the code that performs another check.
:100011D9 CMP EAX, DWORD PTR [EBP-10] <-- EBP-10 by
default = 7BCh (1980).
:100011DC JZ 100011EA <-- Must jump.
After this code we move on to a final check which is actually the serial # validation routine, its at this code.
:10001210 PUSH EAX <-- I'm pretty sure this is a serial
# of sorts.
:10001211 CALL 10001E03 <-- Validation routine.
:10001217 TEST EAX,EAX <-- Desire EAX non-zero.
:1000121A JNZ 10001228 <-- Good jump and move EAX to 1.
You'll need to trace this validation routine which isn't actually as hard as it looks, you'll need to ensure that positions 6 & 14 are hyphens then just work your way through editing memory and displaying the [EBP-address] pointers as required, remember EAX has to be returned as 1, so avoid any conditional jumps which XOR it. Once you've made these changes in-memory everything should work O.K. Alternatively, you may have noticed that our main .exe files only ever call OKToRun and not any of the other exports, the only other place the other functions are referenced is inside F101CFG.dll. The above code we know is actually RetrieveSerialNumber() so we can do all our patching inside FGCREG.dll.
I have a fair amount of respect for this programs usefulness (even though the protection is sub-standard), I have decided not to include a ready-made crack, take out your HEX editor and follow the scheme yourself then pay the modest registration fee.