redirect.htm: Defeating File Integrity Checks Through Redirection

Defeating File Integrity Checks Through Redirection

by Victor Porguen
25 November 1998

Courtesy of reverser's pages of reverse engineering ~ Slightly edited by reverser+

Well, what can I say: read and enjoy! Thanks Victor: viral research applied to reversing has quite a lot to offer... hope you'll send more!
And he did indeed, see: Redirection Revisited -- Achieving Redirection Through API Spoofing, which was published in the +HCU papers on 12 december 1998...
     Defeating File Integrity Checks Through Redirection

                             by

                       Victor Porguen
                     vporguen@yahoo.com
                      25 November, 1998

            Target: WINFAX PRO 9.0 30 day Try-Buy
 ftp://ftp.symantec.com/misc/americas/rps/winfax/WFTRYBUY.EXE

                  Tools: SoftIce, Hexeditor

   Back in the "days of the older ones" we used to create reasonably 
deceptive viruses that used "stealth" techniques to hide code changes 
from CRC and integrity checkers.  Simply put, when the integrity
checking routine opened the file, or made a file read, the viral
code would substitute the correct code in place of the modified
code thus preventing detection regardless of the complexity of the
CRC algorithm.  This same concept can be applied to cracking time
limited programs that go to the trouble of checking the integrity
of the executable from the disk file (as opposed to checking the
code while it is in memory).

   WINFAX 9.0 from Symantec has the common 30-day Try-Buy interface
that we have all grown to know and love.  Cracking the date
limitation while SoftIce is loaded in memory is a rather trivial
exercise.  Nevertheless we must first address the actual "crack"
before we can examine the more interesting aspect of defeating the
file integrity check.  The usual methods of tracing through the
code, setting appropriate breakpoints, and so forth will lead you
to the routine that awaits the "click" on either the "Buy Now" "Try
First" or "Cancel" option   of course, the "Try First" option is
disabled after 30 days.  One of the simplest methods for locating
this area of code is to place a breakpoint on DIALOGBOXPARAMA. 
When SoftIce pops up,  F11 will execute the CALL, click on "Try
First" and SoftIce will pop up once more, and then F12 will break
on the RETurn out of the subroutine, which will be OFFSET 00408BA7.

You will now be sitting smack dab in the middle of the date
checking routine and the necessary crack should be readily
apparent.  Here is the disassembly:
   
014F:00408B75    A3E8864300          MOV  [004386E8] ,EAX     
014F:00408B7A    892D14864300        MOV  [00438614] ,EBP     
014F:00408B80    E84B960100          CALL 004221DO  
014F:00408B85    83C408              ADD  ESP,08    
014F:00408B88    85CO                TEST EAX ,EAX  
014F:00408B8A    751D                JNZ  00408BA9  
014F:00408B8C    6868044300          PUSH 00430468  
014F:00408B91    68A0834300          PUSH 004383AO  
014F:00408B96    E83 5960100         CALL 004221DO  
014F:00408B9B    83C408              ADD  ESP,08    
014F:00408B9E    85CO                TEST EAX, EAX  
014F:00408BAO    7507                JNZ  00408BA9  
014F:00408BA2    E809D5FFFF          CALL 004060BO  
014F:00408BA7    EB05                JMP  00408BAE  
014F:00408BA9    B801000000          MOV  EAX, 00000001  
014F:00408BAE    83F8FF              CMP  EAX,-01   
014F:00408BBI    55                  PUSH EBP  
014F:00408BB2    7514                JNZ  00408BC8  
014F:00408BB4    FF1540D24200        CALL [USER32!PostQuitMessage] 
    

   A two second review of this disassembly reveals the fact that if
the program executes the instruction at 00408BA9 there will be no
expiration of the program.  Further, if the program does NOT
execute the CALL at 00408BA2 the "nag" screen will never display. 
From these two facts flow the obvious conclusion that if the CALL
at 00408B80 returns EAX as anything but zero, then the program will
be cracked.  Setting the system date forward to expire the program
and setting a breakpoint on 00408B8A and "forcing the jump" through
manual clearing of the zero flag while under SoftIce confirms that
this is indeed the crack.  When I first attacked this target I
thought to myself "Hmm, that was rather disappointing ... only five
minutes to crack the program."  However, when I made the actual
byte change in the diskfile FAXMNG32.EXE, it produced page faults. 
I immediately assumed I had mistyped the patch (which was nothing
more than making the conditional jump unconditional).  However,
under SoftIce the patch was exactly as it should be -- and there
was no theoretical reason that this patch should create page faults
unintentionally, therefore the page faults must be on purpose (and
I couldn't have been more pleased).  The first step, of course, was
to set a debug register breakpoint for memory reads on the one-byte
patch to see if the integrity routine was checking memory.  It
wasn't, so the only other possibility was that it was checking the
file from the disk.  Setting a breakpoint on CREATEFILEA and
reviewing the names of the files that were to be opened confirmed
that the program was indeed checking itself on disk   and not just
once, it was running a thread in the background that was constantly
checking the integrity of the file.  How nice.  Simply renaming the
file and keeping a copy of the original file intact was not the
solution since the program was bright enough to actually open and
check the file under the name that it was executing as well as the
correct name of FAXMNG32.EXE.  

   It is at this point that we address the issue for which this
essay is named:  Defeating File Integrity Checks Through
Redirection.  The first step in the process is determining the
location of the CALL that is opening FAXMNG32.EXE for checking. 
Setting a breakpoint on CREATEFILEA as detailed above finds the
call in jiffy-quick time.  Here is the disassembly of the call that
repeatedly opens FAXMNG32.EXE and which we will "cut out" below:  

014F:00421B72    55             PUSH EBP  
014F:00421B73    51             PUSH ECX  
014F:00421B74    53             PUSH EBX  
014F;00421B75    52             PUSH EDX  
014F:00421B76    50             PUSH EAX  
014F:00421B77    FF1568D04200   CALL [KERNEL32!CreateFileA]   
014F:00421B7D    8BF8           MOV  EDI, EAX  

   The next step is to find an area of code that is suitable to
hold our "stealth" routine that will substitute an "unhacked" copy
of the file for the cracked copy.  If we look back to where we know
we must insert the crack we see the CALL 004221D0 at offset
00408B80, which we know is the key to defeating the date check.  If
this code routine is not called elsewhere in the program, we can
use that code area to house our routine and have that CALL return
EAX as nonzero (which is the CRACK!).  Setting a breakpoint on
004221D0 confirms that the routine is only used to check the date,
thus we now have room to work.  First, we apply the crack so that
the CALL at offset 00408B80 always returns EAX as non-zero. 
Putting the value of one in AL and RETurning will do nicely.  Thus
we now have the following short crack code at offset 004221D0:

014F:004221DO    BOO1      MOV  AL,01     
014F:004221D2    C3        RET  

   Now we must create the routine, right after the short crack
code, that will check the name of the file that is to be opened
and, if it is the target file FAXMNG32.EXE, change the name to be
opened to a file that is identical but unhacked ("virgin").  If it
is not the target file, simply open whatever file is named and
chain back to the correct code.  If it is the target file, open the
"virgin" file that is identical to the original unhacked
FAXMNG32.EXE, and then chain back to the correct code.  For the
"virgin" file I chose to name it !AXMNG32.EXE because of the
simplicity of changing one letter in the name.  Here is a
disassembly of the code that 1) Scans the address on the stack for
zero, indicating the end of the filepath name; 2) Checks the name
of the file, and if it is the target file, replace the first letter
of the name with an "!", which is the name of the virgin file; and
3) Open the file (whether the name was changed or not) and jmp back
to the correct code.

014F:004221D3    5B             POP  EBX  
014F:004221D4    53             PUSH EBX            
014F:004221D5    8A03           MOV  AL, [EBX] 
014F:004221D7    43             INC  EBX       
014F:004221D8    OACO           OR   AL,AL     
014F:004221DA    75F9           JNZ  004221D5  
014F:004221DC    83EBOD         SUB  EBX,OD    
014F:004221DF    813B4641584D   CMP  DWORD PTR [EBX] ,4D584146    
014F:004221E5    7515           JNZ  004221FC  
014F:004221E7    817B044E473332 CMP  DWORD PTR [EBX+04],3233474E  
014F:004221EE    750C           JNZ  004221FC  
014F:004221FO    817B082E455845 CMP  DWORD PTR [EBX+08],4558452E  
014F:004221F7    7503           JNZ  004221FC  
014F;004221F9    C60321         MOV  BYTE PTR [EBX] ,21  
014F:004221FC    FF1568D04200   CALL [KERNEL32!CreateFileA]   
014F:00422202    E976F9FFFF     JMP  00421B7D

   The final step is to write the "cut out" code, which is simply
nothing more than replacing the CALL CREATEFILEA with a jmp to our
stealth routine.  Here is the disassembly of the code that is
listed above after the six byte "cut- out" patch:

014F:00421B72    55             PUSH EBP
014F:00421B73    51             PUSH ECX  
014F:00421B74    53             PUSH EBX  
014F;00421B75    52             PUSH EDX  
014F:00421B76    50             PUSH EAX  
014F:00421B77    E957060000     JMP  004221D3  
014F:00421B7C    90             NOP       
014F:00421B7D    8BF8           MOV  EDI, EAX  

   That's it.  The program is now completely cracked (you might
want to tweak FAXMNTKY.DLL to allow for "Live Update" off of the
menu and to remove the nag from the "ABOUT"   but it's not really
necessary) The background thread that continually checks the file
integrity is redirected to a virgin copy of the executable each
time it is called   which of course allows it to pass any CRC,
checksum, or similar algorithm.  

   As a final note, I will point the reader to www.releasesoft.com,
who apparently authored the "integrity checking system" that
Symantec used on WinFax.  Apparently, the protection system is
quite widespread.  Pity, really.

You are deep inside reverser's pages of reverse engineering, choose your way out:
redhomepage red links red anonymity +ORC redenemy stalking redacademy database
redantismut redtools redcocktails redsearch_forms redmail_reverser
redIs reverse engineering illegal?