Minimum Installation Files (505k) available on request.
Firstly I'll thank the person who sent me this program for examination. EyeSys so far as I can work out is a tool for use by opticians, in fact without some specialist hardware I have a feeling the software is pretty useless. As you might expect for a specialist application a dongle has been used. This program is dated 1994 (that's pre SoftICE v3.x/W32Dasm and probably IDA) so modern day tools shouldn't have too many problems. However the program is 16-bit and as you'll see implements a basic anti-debugging trick.
I won't give you any prize for bpx'ing the MessageBox, working it back and seeing that a function export from kechk.dll is responsible for the dongle check. You can just brute-force ww.exe and make the program work using W32Dasm (all the word pointers offset from the base are 0 = good). Instead we'll try SoftICE, a bpio -h 378 rw will hit but no amount of F12 work will get you back to the application caller. Remember that the challenge here is too patch kechk.dll not the application.
Being a 16-bit application also gives us Loader headaches, if we are too bpx a specific piece of code whilst in protected mode the value of the code segment (CS) is important, under 32-bit programs aside from exceptional circumstances we can assume a constant CS. Consider this code from ww.exe.
:0010.3206 PUSH BX <-- You can't bpx here easily.
:0010.3213 CALL KECHK.KECHECK <-- Dongle dll export.
The trick evidently is too use the temporary INT 3 patch technique, we'll then
re-assemble the push bx in at debug time. We reach this code then try and trace
KECHECK, problems, "SoftICE break due to embedded INT 3", repeat ad infinitum.
You can't trace it :), of course we can get around it easily, consider this
basic anti-debug trick from the days when crackers used Turbo Debugger/SoftICE
for Windows 3.1 (this was what I thought I had here).
start:
MOV CX, 0200h <-- CX used for loop.
MOV SI, 0100h <-- SI counter.
LODSB <-- Load Byte.
INT 3 <-- Stop any active debugger.
CBW
ADD BX,AX
LOOP start <-- and frustrate cracker by looping.
As you should already know, all debuggers insert an INT 3 (opcode CC) into
the program code to act as a trigger, at this code any debugger running will
fire upon every execution of the loop, 2 loops like this and your going to get
annoyed pretty quickly. Of course SoftICE provides the facility to turn this
trigger mechanism off with the I3HERE setting. As soon as you trace inside the
CALL to KECHECK turn off all INT 3's with I3HERE OFF. However this won't be
good enough.
:0001.01BC MOV BH,00 <-- Flag.
:0001.01BE MOV CX,0002 <-- Number of words to copy from p-mode to r-mode stack.
:0001.01C1 LES DI, [BP-22]
:0001.01C4 MOV AX,0301 <-- R-mode procedure with far return frame.
:0001.01C7 PUSH WORD PTR [BP-10]
:0001.01CA PUSH WORD PTR [BP-12]
:0001.01CD INT 31 <-- Execute this in SoftICE and its game over.
We'll kill this INT 31 with NOP's, not an elegant technique but effective. You
should be able to see that our objective is to have KECHECK set all of our
desired pointers to 0. The simplest way to see where bad moves occur is via a
watch window. Consider this code.
:0010.32A1 CALL KECHK.KECHECK <-- Check Dongle Key.
:0010.32A6 MOV [BP-0A], AX <-- AX's value is important.
:0010.32AC MOV AX, ES:[BX] <-- As is [BP-04].
:0010.32AF MOV [BP-10],AX <-- Store.
After these adjustments word pointers at BP-06/08 & 0A will be checked for 0,
any of them being 0 will result in a good jump. Following the jump you should
see another 3 checks, this time using AX's value and word pointers BP-0C/0E
(again 0's are desirable). We'll now patch ww.exe with an INT 3 immediately
before the final call too KECHECK (remember to NOP the INT 31 inside kechk.dll).
It suffices that the NOPping of the INT 31 gets us through the 1st set of
3 checks with BP-06=0, however both BP-0C/0E are FFFF which we don't want, lets
trace KECHECK and 'watch' these pointers.
You'll soon see that this specific CALL doesn't seem to be responsible for setting these values (they are FF before you start), we'll have to get in earlier. As you may have guessed, the first call to KECHECK sets BP-0C and the 2nd BP-0E, the code is very similar and uses the value of AX which is actually ES:[BX]. There is however a small problem, before we even call KECHECK ES:[BX] is FFFF, so we are looking for an instruction to alter this. I had a brief look through all the sub_functions called by KECHECK and I couldn't find anything to perform the required magic. This means we'll have to settle for patching ww.exe after all, there probably wasn't any real advantage in being able to do kechk.dll anyhow.
All 3 MOV AX,ES:[BX] (addresses 0010.321E, 0010.3265 & 0010.32AC).
Replaced with 66 33 C0 (XOR AX,AX).
Making these changes allows us to launch the program which on my system then bitches that I haven't a framegrabber and my patients database is more than 30 days old, this is evidently unrelated to the dongle.
Return to Main Index,
Dongles.