-=> How to crack the ** FMS Total Access Memo 2000 ** ActiveX-Control <=-
=========================================================================

This control gives you the opportunity to edit and 
store RTF-formatted texts in MS-Access 97-2000.

Download at: www.fmsinc.com

Since you've downloaded the trial-version you're not able to use this nice control
on your own Access-forms, because of the missing license.
If you don't want to read all this crap just move on to the PATCHWORK-Section of
this little tutorial.

HOW TO CRACK
============

First of all excuse me for my bad English, since I'm not a smart guy.
Well, let's take a look at the nag-screen that appears after you've tried to insert
this ActiveX-control using MS-Access:
"This program is unlicensed software. Please visit www.fmsinc.com for more info"
Uh, this sucks! Note the message text for later use ..
Let's see what an ActiveX-file is all about. It's file-suffix is sometimes .VBX (old style)
or nowadays .OCX, so lets search for this type of file in the programs directory first
(\program files\fms). After this, look at \windows\system, which in this case leads us to the
file FMSTMEMO.OCX. In other cases you could use an installation-reporting tool like 
Norton CleanSweep 2000 to find out which files have been putted where onto your system
during setup. A good approach is to read the instructions delivered with most trial-versions
of any software first. Yes, sometimes reading is necessary.
Now that we've found the file, we use our favorite disassembler like URSofts W32Dasm.
Disassemble the file C:\WINDOWS\SYSTEM\FMSTMEMO.OCX. If the Disassembler isn't able to
open the file then MS-Access is still using it, so close MS-Access!
OK use the Text-search for our nag-message-text: .. unlicensed software ..
You'll see that W32Dasm gave this text the DialogID_00CE / ControlID:FFFF:

In this tutorial W32Dasm-Texts are marked with ">", code-locations of interest 
or entry points are marked with ">>"-Symbols. Remarks are initiated with "///".

>       015 - ControlID:00CF, Control Class:"BUTTON" Control Text:"Ech&o" 
>>  Name: DialogID_00CE, # of Controls=002, Caption:"Total Access Memo 2000", ClassName:""
>>       001 - ControlID:0001, Control Class:"BUTTON" Control Text:"OK" /// OK-Button ///
>>       002 - ControlID:FFFF, Control Class:"STATIC" Control Text: _
>> "This program is unlicensed software. Please visit www.fmsinc.com for more info" 
>   Name: DialogID_07D2, # of Controls=011, Caption:"", ClassName:""
>        001 - ControlID:FFFF, Control Class:"STATIC" Control Text:"A&ppearance:" 
>        002 - ControlID:0843, Control Class:"COMBOBOX" Control Text:"" 

This number is the Assembly representation for our nag-screen-text.
Needless to say that we search from now on for this text-reference e.g. "_00CE" .

So our first search for our new key-word "_00CE" leads us to the following positions:

>  * Reference To: MFC42.Ordinal:08FD, Ord:08FDh
>                                   |
>  :10004327 E8C4CF0000              Call 100112F0
>  
>  * Possible StringData Ref from Data Obj ->"FixedRightMargin"
>                                    |
>  :1000432C 682CA30110              push 1001A32C
>  :10004331 8D9FDC000000            lea ebx, dword ptr [edi+000000DC]
>  :10004337 53                      push ebx
> 
>> * Possible Reference to Dialog: DialogID_00CE /// 1. THIS IS WHERE THE SEARCH STOPs ///
>                                   |
> 
>  * Possible Reference to Dialog: DialogID_07D3, CONTROL_ID:00CE, "Fixed Right &Margin"
>                                   |
>  :10004338 68CE000000              push 000000CE
>  :1000433D 56                      push esi
> 
>  * Reference To: MFC42.Ordinal:08DA, Ord:08DAh
>                                    |
>  :1000433E E8B3CF0000              Call 100112F6
>  :10004343 53                      push ebx
> 
>> * Possible Reference to Dialog: DialogID_00CE /// 2. THIS IS WHERE THE SEARCH STOPs ///
>                                    |
> 
>  * Possible Reference to Dialog: DialogID_07D3, CONTROL_ID:00CE, "Fixed Right &Margin"
>                                    |
>  :10004344 68CE000000              push 000000CE
>  :10004349 56                      push esi
 
Search again and your search stops at the 2nd marked position.
As you see it's ALWAYS a good thing to scroll up in the assembly in order to see what's
happened BEFORE the searched token is being executed.
Well, this piece of code could be our candidate, but as you see there is no jump/call-
reference given before. I'm trying to say, if you follow up the code, there isn't 
a jump to it. So let's assume, that this isn't our bad guy code.
Lets move on .. hit function key [F3], or use the Menu to search again:

>> * Referenced by a CALL at Address:
>> |:1000542B                          <*=- THIS LOOKS INTERESTING .. ///
>> |                                   /// A CALL invokes this CODE .. AHA!! ///
>  :1000EFE0 8B442404                mov eax, dword ptr [esp+04]
>  :1000EFE4 56                      push esi
>  :1000EFE5 50                      push eax
>  :1000EFE6 8BF1                    mov esi, ecx
> 
>> * Possible Reference to Dialog: DialogID_00CE <*=- THIS IS WHERE THE SEARCH STOPs
>                                    |
> 
>  * Possible Reference to Dialog: DialogID_07D3, CONTROL_ID:00CE, "Fixed Right &Margin"
>                                    |
>  :1000EFE8 68CE000000              push 000000CE
> 
>  * Reference To: MFC42.Ordinal:0144, Ord:0144h
>                                    |
>  :1000EFED E85A210000              Call 1001114C
>  :1000EFF2 C706D0660110            mov dword ptr [esi], 100166D0
>  :1000EFF8 8BC6                    mov eax, esi
>  :1000EFFA 5E                      pop esi
>  :1000EFFB C20400                  ret 0004

As you see this piece of code is invoked by a call, also a good sign is, that this
code section is very small. We know that a error message is coded with little expense..
So we go to the address 1000542B. Just search for :1000542B backward, or do whatever
to reach this code-position. Scroll up and you should see this:

>> * Reference To: ADVAPI32.RegCloseKey, Ord:015Bh  /// A VERY GOOD SIGN IS THE REGISTRY ///
>                                    |              /// ACCESS OF THE PROGRAM!!
>  :100053E6 8B3500400110            mov esi, dword ptr [10014000]
>  :100053EC 50                      push eax
>  :100053ED FFD6                    call esi
>  :100053EF 8B4C2410                mov ecx, dword ptr [esp+10]
>  :100053F3 51                      push ecx
>  :100053F4 FFD6                    call esi
>  :100053F6 3BDF                    cmp ebx, edi
>> :100053F8 742C                    je 10005426   /// BAD GUYS GOTO 10005426 ///--|
>  :100053FA 8D542420                lea edx, dword ptr [esp+20]                   |
>  :100053FE 52                      push edx                                      |
>  :100053FF 8D442444                lea eax, dword ptr [esp+44]                   |
>  :10005403 50                      push eax                                      |
>                                                                                  |
>  * Reference To: MSVCRT._stricmp, Ord:01C1h  /// STRING COMPARE !!! ///          |
>                                    |         /// IS THE GIVEN SERIAL A VALID ONE?|
>  :10005404 FF1540470110            Call dword ptr [10014740]                     |
>  :1000540A 83C408                  add esp, 00000008                             |
>  :1000540D F7D8                    neg eax                                       |
>  :1000540F 1BC0                    sbb eax, eax                                  |
>  :10005411 40                      inc eax                                       |
>  :10005412 8944241C                mov dword ptr [esp+1C], eax                   |
>> :10005416 740E                    je 10005426   /// BAD GUYS GOTO 10005426 ///--|
>  :10005418 830D0CA4011002          or dword ptr [1001A40C], 00000002             |
>                                                                                  |
>  * Possible Reference to Dialog: DialogID_0001                                   | 
>                                    |                                             |
>                                                                                  |
>  * Possible Reference to String Resource ID=00001: "FMS Total Access Memo 2000 Control"
>                                    |                                             |
>  :1000541F B801000000              mov eax, 00000001 /// EAX=1, SAYS USER IS LICENSED ///
>  :10005424 EB34                    jmp 1000545A      /// EVERYTHING IS OK, GOON  |
>                                                                                  |
>  * Referenced by a (U)nconditional or (C)onditional Jump at Addresses:           |
>  |:100053F8(C), :10005416(C)  /// YES! SOME MORE JMP-REFs ///                    |
>  |                                                                               |
>  :10005426 57                      push edi  <------------------------------------
>  :10005427 8D4C2464                lea ecx, dword ptr [esp+64]
>> :1000542B E8B09B0000              call 1000EFE0            /// THIS IS WHERE WE LAND ///
>  :10005430 8D4C2460                lea ecx, dword ptr [esp+60]
>
>  * Possible Reference to String Resource ID=00004: "Editor"

First take a look at my remarks. Yes, we've reached our goal! It's very often a good sign
when the program reads the registry and even better if the program compares two values.
Sometimes you won't find both in the same code-section like you do here, so keep on searching!
This code reads the registry, compares the given string with the right one and then
decides to fire the nag-screen or not. We're through!

All we have to do is to patch the two JE (jump-if-even) with NOP (no-operation) -opcodes
at address 100053F8 and 10005416. To do so, please read the PATCHWORK-section below.
You could create a keymaker, too. This would be more elegant, especially for those lamers 
who aren't interested in real cracking, these people need a serialcode!
In this case you would have to create a .reg file, because they're even not able to edit
the registry by their own..

You find better cracking-tutorials at www.crackstore.com especially those from +ORC, which
teached me a lot. Me for one is +ORC one of the best crackers, or better reengineers, I know.

PATCHWORK
=========

File: C:\WINDOWS\SYSTEM\FMSTMEMO.OCX

 ////////////////////////////////////////////////////////////////
 // Digital Signature (Windows-file-property, version)         //
 // Just to check out, that you've got the right version       //
 // of the file so that your Patchwork will take effect.       //
 //                                                            //
 //   Name of           FMS, Inc.                              //
 //   Signature:                                               //
 //                                                            //
 //   Date of                                                  //
 //   Signature:        Tuesday, 18th April 2000 08:34:48pm    //
 ////////////////////////////////////////////////////////////////

Three steps to victory:
- load the File "c:\windows\system\fmstmemo.ocx" into your favorite Hex-Editor.
- goto File-Offset (hex) 53F8 change the two Bytes 74 2C to 90 90 (Nop Nop).
- goto File-Offset 5416 change the two Bytes 74 0E to 90 90 (Nop Nop).

Instead of NOPs you could use the opcodes for push edi (57) 
and after that (5F) pop edi, which will take the same effect, too.
I mention this, because some programs check their main files for NOPs and then
kick you out of the program.

That's all folks!

+SIG of RANGER