| SalesAgent 3.0 BUY NOW Cracking (Goth) 
 
    | Well, I assume that you've taken all obligatory precautions
    (backup the registry and such ...), installed our target and restarted
    Win95. 
 PART I - Look what the cat dragged in
 First you'll see how our target behaves. Start your program. You'll get the usual
   'Time Trial' window. We won't bother to 'Try first' head right to 'Buy now'. Fill in
    some stuff and push 'Next' until you reach the 'Select Payment Method' window. Now,
    do you have your credit card info handy? If not, you should reverse our target to
    see which numbers are valid or visit some fancy hacker site and get a credit card
    generator (e.g. CreditMaster) or simply enter:
 
 
 
    Card:    American Express
    No.:     00000000
    Exp.:    01/05
    Name:    Goth
    And push 'Next' until you get to the 'Select Communication Methods" window. For various
    reasons it's necessary to make sure you CAN'T connect to anything, switch off your modem,
    cut your cable or whatever and push 'Next'. Oops, unable to connect and so on. Cancel the
    whole 'Buy now' thing.
 Now, you could observe our target with trial period expired. But you all know what will
    happen, don't you? Yes, the 'Try first' button will vanish and it WON'T come back if you
    set your RTC back. Well, it's a time trial. So at this point you could have the bright
    idea to fire up SoftICE, bpx GetSystemTime, track down the bytes to patch in the EXE/DLL
    and ready you are.
 
 - NO YOU DON'T!
 
 What you'll do at this point is pushing 'Buy now' again. (Sometimes when I get these
    strange attacks of dumbness, I can't believe there's a 'Buy now' button but no way to
    enter any registration code or such and I'll try again... ;-)
 
 
 You see all fields of your 'User Registration' window filled with information you've
    entered before. Close the program and start again. Info is still there. SalesAgent
    stores user info somewhere!
 
 
 
 PART II - The Anatomy of SalesAgent 3.0
 You should now examine our target's files to get a rough overview of what's going on. Well,
    five should be more than enough I took a deep look at RSAGNT32.DLL. Use BRW and/or W32dasm.
    Look at the import and export tables, resources, headers and so on ... Check if they're
    encrypted/compressed. Use your imagination. What file can perform what task? How does the
    scheme work? FEEL it ...
 
 Having felt enough you should come at least to these results:
 
 
 - If your program has more than one EXEs, they all have the same size
 => can't be the real EXEs => some kind of loader
 
 - ********.DL_s are encrypted => the real EXEs will be loaded, decrypted, whatever ...
      RSAGNT32.DLL connects to internet server, contains resources for
      ENTERING REGISTRATION CODE
 
 
 Now, how does our start process look like?
 You start the program which uses RSAGNT32.DLL to check if you're in your trial period and
    then presents the 'Trial' window. If you push 'Try first' the encrypted DL_ is being
    temporary decrypted and started. If you push 'Buy now' the RSAGNT32.DLL is used for
    getting user information, internet connection and REGISTRATION. After registration
    the *.DL_ files should be permanently decrypted.
 
 So how do we get RSAGNT32.DLL to let us register?
 
 
 
 PART III - Faking a mail/fax order
    I've used W32Dasm to disassemble RSAGNT32.DLL. First I examined it's import table to see
    what it is able to and to look for suspicious imports. Huh, you'll find a lot. What should
    make your bells ring is that it's able to modify registry entries but also uses the absolete
    PrivateProfileString (*.INI) stuff. This needs further investigation.
 
 W32dasm finds the first appearance of GetPrivateProfileStringA here:
 
 
 
    ...
    * Reference To: KERNEL32.GetPrivateProfileStringA, Ord:0112h
      
                                       |
    :100015EE   8B35A8010210 mov esi, dword ptr [100201A8]
      
    * Possible StringData Ref from Data Obj ->"rsagent.ini"
      
                                       |
    ...
    Oops, it tries to read from a file called RSAGENT.INI And where are these *.INI thingies
    usually kept? Right, we'll find it in our 'Windows' directory:
 
 
    
    | [ReleaseSoft] firstName=Goth
 lastName=Nosferatu
 company=!
 street1=!
 street2=!
 city=!
 state=
 zip=12345
 country=United States
 geoType=110
 phoneNum=!
 faxNum=!
 email=!
 personalCode=
 toneDial=1
 callWait=0
 needAccess=0
 accessCode=9
 intlPrefix=
 callWaitStr=
 mailStat-975135=0
 ATTN=AT
 MTONEDIAL=T
 PULSEDIAL=P
 DIALTHIS=D
 WORDRESULT=V1
 HANGUP=H0
 ADDINIT=E0
 ESCAPE=+++
 OKAY=OK
 NOCARRIER=NO CARRIER
 CONNECTED=CONNECT
 NODIALTONE=NO DIALTONE
 BUSY=BUSY
 
 |  It wasn't there right after the installation. So it must have been created while we tried
    to register the target in PART I. Examine it. Look for something that could help us to
    register. Well, till 'email=!' (Yes, I'm a lazy bastard. I entered all these '!')
    nothing of importance. But wait, 'personalCode='!
 
 Where have we seen this before? If you did as I told you in PART II you would know where.
    Use BRW. Look at dialog 2011! What is this dialog's title? 'Complete Mail / Fax Payment'!
    Hm, Mail?, Fax? can't remember any Mail / Fax order opportunity during 'Buy now' procedure.
    Take a look at dialog 2001. Our old friend from PART I 'Select Communication Method' but
    this dialog allows ordering by phone and mail/fax. So it should be possible to get to
    dialog 2011 without completing the internet/modem connection!
 
 All entries are pretty self explainary but what's about this 'mailStat-975135=0' entry?
    Let's change it to 1, restart NU and try 'Buy now' procedure again. Anything changed? Of
    course! We are finally at dialog 2011. There we have a 'Personal Code' and what we
    haven't is an 'Unlocking Code'. But not for long ...
 
 
 
 PART IV - RSAGNT32.DLL's builtin KeyGenerator
 We know that our 'Unlocking Code' will be recieved by dialog 2011. So you should
    bpx GetDlgItemTextA in SoftICE. Enter a dummy unlock code (e.g. gothtog) and after
    pressing F12 SoftICE will popup here:
 
 
 
    :10005612    mov edi, 10032E20              <= our unlocking code
    :10005617    or ecx, FFFFFFFF
    :1000561A    xor eax, eax
    :1000561C    repnz
    :1000561D    scasb
    :1000561E    not ecx
    :10005620    dec ecx
    :10005621    cmp ecx, 0000000A              <= is it 10 chars long?
    :10005624    je 10005665                    <= Yes! => Go for validation check!
    :10005626    lea edx, dword ptr [esp+10]    No! => ...
      
    * Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is not valid for
    this program."
                   
                                                         |
    :1000562A    push 10023890
    :1000562F    push edx
    :10005630    call 10014590
    Step over the next instructions, toogle zero flag at 10005624 and step on till you reach:
 
 
    :100056A8    push ecx
    :100056A9    push edx
    :100056AA    push eax
    :100056AB    call 1000B980                  <= calculate the real code
    :100056B0    add esp, 0000000C
    :100056B3    lea ecx, dword ptr [esp+000000D8]
    :100056BA    push 10032E20                  <= our code
    :100056BF    push ecx                       <= real code
    :100056C0    call 1001F5C0                  <= compare
    :100056C5    add esp, 00000008
    :100056C8    test eax, eax                  <= if compare fails (eax!=0)
    :100056CA    jne 1000597C                   <= we'll get 'Sorry, that...'
     ...         ...
    At 100056BA we dump ecx and get a perfect 10 chars long unlock code like: 'RQXKNKQJPP'
    (This code is only valid if your personal code was '1234567890' and the program was
     Dreamweaver! BTW, you the unlock codes changes if you modify your 'personalCode' entry
     and your 'mailStat-975135' in RSAGENT.INI!) Leave SoftICE (F5). Enter the unlock code
     and we get a 'Enter your serial' window. (Weird!) Here we enter our unlock code again and
     it's done!
 
 
 PART V - Summary and Additions
 We won't have to deal with any encryption routines since SalesAgent 3.0 can be defeated
     in less than 2 min:
 
 
 - change 'personalCode=' to 'personalCode=1234567890' and 'mailStat-975135=0' to
      'mailStat-975135=1' in RSAGENT.INI (if there's no RSAGENT.INI create one!)
 
 - start the 'Buy now' procedure and
 
 -  enter 'RQXKNKQJPP' as unlock code (only if your cracking Dreamweaver)
 
 |  
 
 
 SalesAgent 3.0 TRY FIRST Cracking (Victor Porguen)
 
 
    | Back in the 'old days' 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). 
 Programs protected by SalesAgent's can have the common x-day Try-Buy interface that we
    have all grown to know and love. An example of this could be WinFAX Pro 9.0 from Symantec,
    which is the example program for this essay. 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:
 
 
 
      :00408B75 A3E8864300            MOV      [004386E8],EAX 
      :00408B7A 892D14864300          MOV      [00438614],EBP 
      :00408B80 E84B960100            CALL     004221DO 
      :00408B85 83C408                ADD      ESP,08 
      :00408B88 85CO                  TEST     EAX,EAX 
      :00408B8A 751D                  JNZ      00408BA9 
      :00408B8C 6868044300            PUSH     00430468 
      :00408B91 68A0834300            PUSH     004383AO 
      :00408B96 E835960100            CALL     004221DO 
      :00408B9B 83C408                ADD      ESP,08 
      :00408B9E 85CO                  TEST     EAX,EAX 
      :00408BAO 7507                  JNZ      00408BA9 
      :00408BA2 E809D5FFFF            CALL     004060BO 
      :00408BA7 EB05                  JMP      00408BAE 
      :00408BA9 B801000000            MOV      EAX,00000001 
      :00408BAE 83F8FF                CMP      EAX,-01 
      :00408BBI 55                    PUSH     EBP 
      :00408BB2 7514                  JNZ      00408BC8 
      :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 program 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 really 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:
 
 
 
      :00421B72 55                    PUSH     EBP 
      :00421B73 51                    PUSH     ECX 
      :00421B74 53                    PUSH     EBX 
      :00421B75 52                    PUSH     EDX 
      :00421B76 50                    PUSH     EAX 
      :00421B77 FF1568D04200          CALL     [KERNEL32!CreateFileA] 
      :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:
 
 
      :004221DO BOO1                  MOV      AL,01 
      :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
 
 3) Open the file (whether the name was changed or not) and JMP back to the correct code.
 
 
 
      :004221D3 5B                    POP      EBX 
      :004221D4 53                    PUSH     EBX 
      :004221D5 8A03                  MOV      AL,[EBX] 
      :004221D7 43                    INC      EBX 
      :004221D8 OACO                  OR       AL,AL 
      :004221DA 75F9                  JNZ      004221D5 
      :004221DC 83EBOD                SUB      EBX,OD 
      :004221DF 813B4641584D          CMP      DWORD PTR [EBX],4D584146 
      :004221E5 7515                  JNZ      004221FC 
      :004221E7 817B044E473332        CMP      DWORD PTR [EBX+04],3233474E 
      :004221EE 750C                  JNZ      004221FC 
      :004221FO 817B082E455845        CMP      DWORD PTR [EBX+08],4558452E 
      :004221F7 7503                  JNZ      004221FC 
      :004221F9 C60321                MOV      BYTE PTR [EBX],21 
      :004221FC FF1568D04200          CALL     [KERNEL32!CreateFileA] 
      :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:
 
 
 
      :00421B72 55                    PUSH      EBP 
      :00421B73 51                    PUSH      ECX 
      :00421B74 53                    PUSH      EBX 
      :00421B75 52                    PUSH      EDX 
      :00421B76 50                    PUSH      EAX 
      :00421B77 E957060000            JMP       004221D3 
      :00421B7C 90                    NOP 
      :00421B7D 8BF8                  MOV       EDI,EAX 
    That's it. The program is now completely cracked. 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 http://www.releasesoft.com,
    who apparently authored the 'integrity checking system' that Symantec used on WinFax.
    Apparently, the protection system is quite widespread. Pity, really.
 |  
 
 
 
 |