*****************************************************************
         * Title    : PrimaSoft AutoFTP premium v3.4 Registration-HowTo  *
         * Kind     : Serial fishing - Beginner's tutorial               *
         * Date     : 30.08.2002                                         *
         * Updates  : 07.10.2002 - Update from v3.3 to v3.4              *
         * Autor    : FoolFox                                            *
         * Product  : PrimaSoft AutoFTP premium v3.4 (32bits)            *
         * OS       : Windows 95/98/NT/2k                                *
         * URL      : h11p://www.primasoft.com                           *
         ***[Tools:]******************************************************
         *                                                               *
         *  o W32Dasm -  h11p://members.cox.net/w32dasm/                 *
         *               I use version 8.93, registered - no patches     *
         *               Demo version should do the job                  *
         *  o WinHex  -  h11p://www.winhex.com                           *
         *               I use the version 10.4, registered              *
         *               Unregistered version works as well (tested)     *
         *                                                               *
         *****************************************************************

  ***[HowTo]**************************************************************************

  I would recommand to any reader that is not familiar with technics described in this
  document to download the tools shown above and to play with them before atempting to
  reproduce the step indicated in this document. Aside of that, i'm not nativly
  speaking english, so don't expect my writing to be one of the best. I've attempted
  to render this tutorial as clear as i could for a real newbie - as i'm still one
  don't expect to learn advanced techniques here -, so hope i didn't misssed the 
  target. I'm also trying to show you that you always have several ways of reaching
  a solution. Most of people i know would have done it through SoftIce. Even if i
  must admit this is one of the best tool around, i don't like to rely on the tools
  everybody use...maybe i'm just a fool...who know...

  So, first of all, this tutor was at first written for the version 3.3. During the
  writting of the original tutor, and it's translation later in english, the software 
  have evolved. So before being published, this tutorial was already "outdated". As 
  i've seen said on IRC : "with internet, everything that's older than 2 min, is OLD". 
  A clever statement :). Well, i'll try to keep this tutorial updated to follow each
  new outcoming of the software. The work will always be done in regards of the latest
  versions, with some notes including the modification that have be done in regard of
  olders version. 

  Before any try, whatever you are trying to reverse, you'll have to "toy" a little bit
  with the software. Here we are talking of "feeling" the protection just by looking
  at the design. Reversing (or cracking if you look at the scope of this tutorial) is 
  an activity that can take less or more time depending the way you'll exploit the
  product. Experience is the best tool at this game... but a good knowledge of your
  target can significantly downgrade the time needed.

  After having downloaded the product, run the installation. Once installed, run the
  software. First screen that pop-up is a nag-screen, reminding that the installed
  version is a evaluation version, and from there you can register the product, enter
  a registration code, or close the nag-screen to continue with the evaluation version.

  In our case, we'll continue the loading. We could already try to enter a registration
  code, but in the arena of reverse-engineering i'll strongly advise you to not base 
  your findings on any EXCEPTION CASE. There is where a good english is missing, i think.
  An exception case is a "special" case in the process of running the program. The first
  time you run a software, would be an exception in the process of running this software.
  mmm.. Hope is not too obscure the way i told it... well, to try to clarify, your
  software could really be aware of the fact that he is running for the first time. He
  may had to setup some things, and so on. So better run it the first time as a real
  evaluation user, that will of course try the software before buying it. In that case,
  you probably never have any trouble by entering a serial at first try (you could have
  as well tryed a previous version and already decided to buy the further one). The point
  to recall, is that in my mind, you should AVOID special situation. Anyway, let's go 
  further...

  So, we goes through several screens for configure the product. After seeing the main
  screen drawing, we can access to the application menus. Among them, the HELP menu.
  A click on it will reveal a sub entry : Enter Decode Key. A click on this one will
  popup a window titled "Registration Code", with two textbox fields. Those fields
  are respectivly named : "Licensee Name:" and "Registration Code:". The window have
  two buttons, one labeled Ok and the other Cancel. 

  At first glance, no change since version 3.3
   
  It's always important to write down any label you found related to the protection.
  Those will help after on, when we'll try to locate the functions that are in charge
  of the validation of the serial number.

  Here, i usually introduce a further step before atempting anything related to the
  protection, is to open the target in a good Hex Editor (my favorite is WinHex, well
  you can use anyone that respond to your needs...and that allow the edition of a
  binary file) and to search for any URLs located in the software. I then use the
  editor to slightly change any URL i found. I never broke any functionnality like
  that (except maybe for reaching an online help), and it can help to avoid the
  software silently send various information about you, your usual activity, software
  that lay on your HD, on his home server. Even if that in theory wouldn't leed you
  to a court (the way they are fetching data is illegal in most country i know), it's
  never a nice surprise to receive a threatening e-mail for a product you already
  forgotten having reversing a while ago..

  After that, run again the target, and in the registration window enter the
  following informations :


	Licensee Name 	  : UnderCover
	Registration Code : 23452345	(fake)


  For the registration code, we have entered a fake one, but just think about the
  fake code you enter, it should not be any fake (obviously) code, but a code that
  you should be able to trace back in memory. We could have used 23456789 as a
  registration code, but this string is heavily spotted in memory..good luck to
  find the fake serial inside all those lines....

  First thing we'll check out, is that is the target is protected to the point of
  erasing the correct code of the memory at the registration code evaluation time ??

  Here's a basic sample on how a registration scheme could be checked :


	1 - The software wait for user's input.
	2 - Once all input are in, the software compute the correct code.
	3 - The code is correct ? software registered.
	4 - The code is incorrect ? software show "Error" and wait for the
            user validation to return to point one.


  If our target work this way, simply by staying "blocked" at step 4 (we don't
  validate the error message), we could search in memory the fake code we've
  entered. For many actual software (more than you can think), the correct code
  is laying not far away. 

  To protect themself of this memory serial fishing, many software modify the
  previous cycle in the following manner :


	1 - The software wait for user's input.
	2 - Once all input are in, the software compute the correct code.
	3a- The code is correct ? a flag is set on.
	3b- The correct code is erased of the memory.
	3c- Is the flag on ? software registered.
	4 - Is the flag off ? software show "Error" and wait for the
            user validation to return to point one.


  simple, but apparently they are still many programmers to neglect this point.. wich
  is about 3 lines of code. And it may help many authors to not having their baby
  published on indecent serial list of the internet.... serial fishing with WinHex is
  easy, when it have to be combined with a debugger...less easy (not so but is sufficient
  to discourage many people)

  But in our case, as we are seeking that serial, and didn't know yet how the 
  registration part have been coded, we stop after having the fake informations
  entered to launch our memory editor (WinHex). Once WinHex is loaded, validate the
  fake serial. A popup appears :

 
	[information]

	Code Not Accepted ! Please try again
	(Licensee name case sensitive)


  There, we switch on WinHex (using Alt-Tab..), and in the Tools menu, select 
  "Ram editor". A list of working process is shown, there we select "ftpprem" (the
  one we want to toy with), then "Entire memory". Then we launch a search on the
  string "23452345", wich is our fake serial.

  With version 3.3, we find our fake code, and the string "code not accepted". No
  traks of a valid serial (note that when you make a search, you should never
  forget that a data on a windows system can be coded in different way, plain
  text and unicode are the most common ones, your search should cover at least
  the two cases, beyond you can see a plain text part (our fake datas), and the
  message is shown as unicode) :


  Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

  00158EA0   00 00 00 00 79 00 7A 00  06 00 20 00 00 23 10 00   ....y.z... ..#..
  00158EB0   55 6E 64 65 72 43 6F 76  65 72 00 00 00 00 00 00   UnderCover......
  00158EC0   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  ....
  00158FE0   00 00 00 00 00 00 00 00  00 00 00 00 40 00 40 00   ............@.@.
  00158FF0   06 00 20 00 00 23 10 00  32 33 34 35 32 33 34 35   .. ..#..23452345
  00159000   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00   ................
  ....
  001596D0   10 00 00 00 10 00 00 00  13 00 28 00 00 01 0C 00   ..........(.....
  001596E0   00 00 00 00 64 00 65 00  20 00 4E 00 6F 00 74 00   ....d.e. .N.o.t.
  001596F0   20 00 41 00 63 00 63 00  65 00 70 00 74 00 65 00    .A.c.c.e.p.t.e.
  00159700   64 00 21 00 20 00 50 00  6C 00 65 00 61 00 73 00   d.!. .P.l.e.a.s.
  00159710   65 00 20 00 74 00 72 00  79 00 20 00 61 00 67 00   e. .t.r.y. .a.g.
  00159720   61 00 69 00 6E 00 20 00  28 00 4C 00 69 00 63 00   a.i.n. .(.L.i.c.


  In version 3.4, we didn't find this echo, just the one where we've entered our 
  strings. From there there's no way yet to know if the protection scheme have changed.

  We continue our search, without result. Same for the "UnderCover" string. Unicode
  search didn't return anything. So, it look's like WinHex is not enough to grab a
  serial for this product. We'll have a look at the target now using a disassembler/
  debugger (W32Dasm).  

  So, launch W32Dasm, and make it load the FTPPREM.EXE file. If your W32Dasm is just
  showing a huge garbage instead of a clear, desassembled listing, go through the
  menu Disassembler -> Font -> Select and define a font. Save your settings after.

  Without stopping at the apparent complexity of the listing (little note, a minimal
  knowledge of assembly are nearly mandatory to excerce an activity like reverse
  engineering, the better you know your system, the easier it will be for you to
  understand how the stuff work), go the the "Refs" menu, and select "String data
  reference". A window is shown with all strings found within the software. At this
  point, we're looking for the message that is shown during the code validation 
  process.

  And we found some that look like related to our code... :


	"Code Accepted! Thank you for registering "
	"Code Not Accepted! Please try "


  Clicking on the string of the window, W32Dasm bring you right in the offset of the
  code where the string is used :



  :004C8743 90                      nop
  :004C8744 33C9                    xor ecx, ecx
  :004C8746 B201                    mov dl, 01
  :004C8748 A140824C00              mov eax, dword ptr [004C8240]
  :004C874D E8B217F8FF              call 00449F04
  :004C8752 8B15907E4E00            mov edx, dword ptr [004E7E90]
  :004C8758 8902                    mov dword ptr [edx], eax
  :004C875A A1907E4E00              mov eax, dword ptr [004E7E90]
  :004C875F 8B00                    mov eax, dword ptr [eax]
  :004C8761 8B10                    mov edx, dword ptr [eax]
  :004C8763 FF92CC000000            call dword ptr [edx+000000CC]
  :004C8769 48                      dec eax
  :004C876A 753C                    jne 004C87A8
  :004C876C A1907E4E00              mov eax, dword ptr [004E7E90]
  :004C8771 8B00                    mov eax, dword ptr [eax]
  :004C8773 80B8DC02000000          cmp byte ptr [eax+000002DC], 00
  :004C877A 7417                    je 004C8793
  :004C877C 6A00                    push 00000000
  :004C877E 668B0DB8874C00          mov cx, word ptr [004C87B8]
  :004C8785 B202                    mov dl, 02

  * Possible StringData Ref from Code Obj ->"Code Accepted! Thank you for registering "
                                          ->"our software."
                                    |
  :004C8787 B8C4874C00              mov eax, 004C87C4
  :004C878C E80FFAF8FF              call 004581A0
  :004C8791 EB15                    jmp 004C87A8

  * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  |:004C877A(C)
  |
  :004C8793 6A00                    push 00000000
  :004C8795 668B0DB8874C00          mov cx, word ptr [004C87B8]
  :004C879C B202                    mov dl, 02

  * Possible StringData Ref from Code Obj ->"Code Not Accepted! Please try "
                                          ->"again (Licensee Name is case sensitive)."
                                    |
  :004C879E B804884C00              mov eax, 004C8804
  :004C87A3 E8F8F9F8FF              call 004581A0



  In the version 3.3, the code is exactly this one, except that the adress is not 
  the same, making all jump pointing to slightly different adresses.

  We can see that the message "Code not accepted" where called from the line
  004C877A  (* Referenced by a (U)nconditional or (C)onditional Jump). (In version
  3.3, the adress was : 004C80DA). This line is making a byte compare (flag ?), and 
  from the result of the test the user is registered or invited to retry.

  At this point, we could set a Break-Point. 

  A Break-Point is a STOP sign defined inside the debugger. A breakpoint is a point in 
  a program that, when reached, triggers some special behavior useful to the process of 
  debugging; generally, breakpoints are used to either pause program execution, and/or 
  dump the values of some or all of the program variables. Breakpoints may be part of the 
  program itself; or they may be set by the user as part of an interactive session with 
  a debugging tool for scrutinizing the program's execution. Wich is our case... Our idea 
  there is to block the target at a point where the correct code is computed, but not 
  yet erased from memory.

  The conditionnal jump is preceded by some code that look like of some kind of
  operation on a string, we can put a BP (Break-Point) at the adress 004C8743 
  (004C80A3 for version 3.3), run the target, and if we land somewhere where the 
  correct code is not yet computed, we can run the proggy step-by-step until we got 
  what we want.

  Before going further, we'll juste change an option of W32Dasm. Go to the Debug menu,
  select debugger option, and uncheck the "Display program generated exceptions". 
  Having this one enabled result in some W32Dasm pop-up and the application freezed 
  each time the program will generate an exception error....

  In W32Dasm, select the menu Debug -> Load process, and run it without any parameters.
  At this point, you'll see the main windows of W32Dasm reducing it's size about of 1/4,
  the little window is now displayed at the top left of your screen. Two new screens 
  appears beyond,. The left lower screen shows you all informations abour registers and
  their content, the right windows show you the current code being executed and from 
  there you can choose to run the program straight on, step by step, etc... The left
  lower windows is the most interesting, this is where you'll see all data floating 
  around.

  W32Dasm launch the debugger, and stop at the program entry point.  From the main
  window (top left), select the menu Goto -> Goto code location, enter "004C8743". 
  In the same window (where the disassembled listing is shown), while maintaining the 
  [Ctrl] key pressed, mouse-click at the left of the adress :004C8743 (still in the
  same window). A yellow box should be shown at this point. BP is now defined. You 
  should see the adress apears on the left-down windows, on a small listbox labeled 
  Bpts. Click on the Run button of the windows at the lower right to launch the 
  execution of the target.
  
  Application is running. Go to the registration process (Help -> Enter Decode Key),
  enter the fake informations, code is rejected. Get off lamer.

  Oups.

  Again, running too fast is not the way of doing it. We've forgotten some basic rule.

  Clearly, our BP have been neglected. Obviously, the code we've found was not used
  at this point. There can be several explanation for this. It could be a false
  (unused) code injected by the author to fool people like us. Or there is several
  parts of the software that are used to register the product, each part having is
  own registration routine. In our case, the code can be entered either from the Help
  menu..... or from the startup nag-screen.

  At this point, version 3.4 show exactly the same behaviour as version 3.3

  Go back to W32Dasm, and search for the string "Code not accepted". Notice that we
  are not going through the String reference menu, which will only show you the
  FIRST occurence of the string. We want to see all place where this string is used.
  That's why the search should be done through the search menu, and not the string
  ref menu.

  Advice : The string reference menu should be one of the first thing you should look
  at. It will show you all string that are stored in clear in a software. Without running
  or attempt to tamper with the software, you can feel from some string if the target
  contain some anti-cracking code, wich level (just a popup ? destroying the HD ?), if
  some user's name are blacklisted to prevent the use of a published serial... as long
  as you are making something illegal, people in front can do the same. Some does.
  Don't try to crack CDRWin if you are just a newbie. You'll just fuck up your
  CD-Recorder, at least. (No, i didn't try...)

  So, back to our target, in W32Dasm seek for the string "Code Not Accepted". Search
  is launch from the menu Search -> Find text. At first, we step back on our previous 
  code, and then on a second message. This time the listing is quite different. We find
  the final test between a valid code and an invalid one at adress 004D618B (****). For
  version 3.3, the adress was 004D5AC3. But aside that, again the code shown is the
  same for version 3.3 and 3.4.


  :004D6176 48                      dec eax
  :004D6177 0F8581000000            jne 004D61FE
  :004D617D A1907E4E00              mov eax, dword ptr [004E7E90]
  :004D6182 8B00                    mov eax, dword ptr [eax]
  :004D6184 80B8DC02000000          cmp byte ptr [eax+000002DC], 00
  :004D618B 745C                    je 004D61E9				<= ***
  :004D618D 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D6190 8B9044040000            mov edx, dword ptr [eax+00000444]
  :004D6196 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D6199 8B8008040000            mov eax, dword ptr [eax+00000408]
  :004D619F E82CDFF6FF              call 004440D0
  :004D61A4 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D61A7 8B9074040000            mov edx, dword ptr [eax+00000474]
  :004D61AD 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D61B0 8B8008040000            mov eax, dword ptr [eax+00000408]
  :004D61B6 E815DFF6FF              call 004440D0
  :004D61BB 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D61BE 8B907C040000            mov edx, dword ptr [eax+0000047C]
  :004D61C4 8B45FC                  mov eax, dword ptr [ebp-04]
  :004D61C7 8B8008040000            mov eax, dword ptr [eax+00000408]
  :004D61CD E8FEDEF6FF              call 004440D0
  :004D61D2 6A00                    push 00000000
  :004D61D4 668B0D30624D00          mov cx, word ptr [004D6230]
  :004D61DB B202                    mov dl, 02

  * Possible StringData Ref from Code Obj ->"Code Accepted! Thank you for registering "
                                          ->"our software."
                                    |
  :004D61DD B83C624D00              mov eax, 004D623C
  :004D61E2 E8B91FF8FF              call 004581A0
  :004D61E7 EB15                    jmp 004D61FE

  * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  |:004D618B(C)
  |
  :004D61E9 6A00                    push 00000000
  :004D61EB 668B0D30624D00          mov cx, word ptr [004D6230]
  :004D61F2 B202                    mov dl, 02

  * Possible StringData Ref from Code Obj ->"Code Not Accepted! Please try "
                                          ->"again (Licensee Name is case sensitive)."
                                    |
  :004D61F4 B87C624D00              mov eax, 004D627C
  :004D61F9 E8A21FF8FF              call 004581A0



  Well. As there is only two messages like the one we searched, and that our toying
  wasn't using the first function, we are probably taken to the second one to validate
  our serial.

  We need then another BP. Take care, establishing of a correct adress (correct in the
  meaning of returning a result) is often the delicat part of the method. Bad placement
  of a BP could lead to no result at all. Or wasting a lot of time steping in a
  useless code. A this point, no other solution than carefully review the disassembled 
  listing to attempt to guess wtf he's doing. A little bit of "feeling" can help at this
  point. I've heard that you become better and better at this game while time pass....

  Our conditionnal jump at :004D618B follow few line manipulating caracters.


  :004D617D A1907E4E00              mov eax, dword ptr [004E7E90]
  :004D6182 8B00                    mov eax, dword ptr [eax]
  :004D6184 80B8DC02000000          cmp byte ptr [eax+000002DC], 00
  :004D618B 745C                    je 004D61E9				<= ***


  It is PROBABLY (just my opinion) the last stages of the correct code computation. 
  We'll attempt to define the BP on 004D617D (004D5AB5 for v3.3), where the valid code 
  is probably already known, and where there is just the last test done.

  Re-run W32Dasm, load the software, launch the debugger. Define the BP and run
  the baby.

  Once we click on the "Ok" button to validate our code, the debugger stop the
  target and give us the hand back. Great. At least we've stopped this time. We
  are now exactly at the 004D617D adress. (code at this adress have NOT YET been
  executed). If we search for the "23452345" or the "undercover" string (another 
  hint, even if we had entered the name as UnderCover, it is possible that the 
  target operate on this string, either to put it whole uppercase, or lowercase, 
  or anything.. so always make your searches using minus car, like that we don't 
  care of any capitalization (is that an english word ?). It's effective with any 
  kind of application, search engine, etc..), we found something that  where not 
  there before :


    Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

    00D9D9F0   78 FD 42 00 C4 D7 D9 00  00 00 00 00 00 00 00 00   xýB.Ä×Ù.........
    00D9DA00   00 00 00 00 00 00 00 00  B8 52 43 00 C4 D7 D9 00   ........¸RC.Ä×Ù.
    00D9DA10   1A 00 00 00 58 A0 41 00  00 00 00 00 00 00 00 00   ....X A.........
    00D9DA20   2C C4 D6 00 00 00 00 00  78 94 4E 00 68 B1 D9 00   ,ÄÖ.....x”N.h±Ù.
    00D9DA30   D4 25 00 00 32 33 34 35  32 33 34 35 00 00 00 00   Ô%..23452345....
    00D9DA40   78 94 4E 00 68 B1 D9 00  BC 25 00 00 55 6E 64 65   x”N.h±Ù.¼%..Unde
    00D9DA50   72 43 6F 76 65 72 00 00  78 94 4E 00 68 B1 D9 00   rCover..x”N.h±Ù.
    00D9DA60   A4 25 00 00 37 30 36 35  39 32 34 37 18 00 00 00   ¤%..70659247....
    00D9DA70   1F 00 00 00 00 00 00 00  0D 00 00 00 37 30 36 35   ............7065
    00D9DA80   39 32 34 37 34 2D 39 36  38 00 FF FF 78 94 4E 00   92474-968.ÿÿx”N.
    00D9DA90   68 B1 D9 00 70 25 00 00  00 00 00 00 00 00 00 00   h±Ù.p%..........



  mmmmm...  706592474-968 terribly look like as a serial...

  Stop WinHex, W32Dasm, run the target and enter the serial found...


	Licensee Name 	  : UnderCover
	Registration Code : 706592474-968


  following window is shown :

	[Information]

	Code Accepted! Thank you for registering our software


  A clic on the Ok button, and now you are a registered user. The same registration
  code works for both version 3.3 and version 3.4. So basically we can guess that this
  new release was just to fix some bugs....

  Isn't that nice ? :)

  FoolFox

  *[The end....this is the end, my friend...(The Doors)]******************************
  *[EOF]******************************************************************************