***************************************************************** * 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]******************************************************************************