***************************************************************** * Title : PrimaSoft AutoFTP premium v3.5 Registration-HowTo * * Kind : Serial fishing - Beginner's tutorial * * Date : 30.08.2002 * * Updates : 07.10.2002 - Update from v3.3 to v3.4 * * : 08.01.2003 - Update from v3.4 to v3.5 * * Autor : FoolFox * * Product : PrimaSoft AutoFTP premium v3.5 (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) * * o OllyDebug - h11p://home.t-online.de/home/Ollydbg/ * * I use the version 1.08b * * * ***************************************************************** ***[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 respectively 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, except a little popup in version 3.5 to recall the user the presence of the help file in case of trouble. 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. Same result with version 3.5 as for 3.4. 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 " Those strings are found from version 3.3 up to the 3.5. Clicking on the string of the window, W32Dasm bring you right in the offset of the code where the string is used : :004C8C47 90 nop :004C8C48 33C9 xor ecx, ecx :004C8C4A B201 mov dl, 01 :004C8C4C A144874C00 mov eax, dword ptr [004C8744] :004C8C51 E8AE12F8FF call 00449F04 :004C8C56 8B15948E4E00 mov edx, dword ptr [004E8E94] :004C8C5C 8902 mov dword ptr [edx], eax :004C8C5E A1948E4E00 mov eax, dword ptr [004E8E94] :004C8C63 8B00 mov eax, dword ptr [eax] :004C8C65 8B10 mov edx, dword ptr [eax] :004C8C67 FF92CC000000 call dword ptr [edx+000000CC] :004C8C6D 48 dec eax :004C8C6E 753C jne 004C8CAC :004C8C70 A1948E4E00 mov eax, dword ptr [004E8E94] :004C8C75 8B00 mov eax, dword ptr [eax] :004C8C77 80B8DC02000000 cmp byte ptr [eax+000002DC], 00 :004C8C7E 7417 je 004C8C97 :004C8C80 6A00 push 00000000 :004C8C82 668B0DBC8C4C00 mov cx, word ptr [004C8CBC] :004C8C89 B202 mov dl, 02 * Possible StringData Ref from Code Obj ->"Code Accepted! Thank you for registering " ->"our software." | :004C8C8B B8C88C4C00 mov eax, 004C8CC8 :004C8C90 E80BF5F8FF call 004581A0 :004C8C95 EB15 jmp 004C8CAC * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004C8C7E(C) | :004C8C97 6A00 push 00000000 :004C8C99 668B0DBC8C4C00 mov cx, word ptr [004C8CBC] :004C8CA0 B202 mov dl, 02 * Possible StringData Ref from Code Obj ->"Code Not Accepted! Please try " ->"again (Licensee Name is case sensitive)." | :004C8CA2 B8088D4C00 mov eax, 004C8D08 :004C8CA7 E8F4F4F8FF call 004581A0 In the version 3.3 and 3.4, 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 004C8C7E (* Referenced by a (U)nconditional or (C)onditional Jump). (In version 3.3, the adress was : 004C80DA, in version 3.4 the adresse was : 004C877A). 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 004C8C47 (004C80A3 for version 3.3, 004C8743 for the version 3.4), 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 "004C8C47" (value for the v3.5 version). In the same window (where the disassembled listing is shown), while maintaining the [Ctrl] key pressed, mouse-click at the left of the adress :004C8C47 (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. For version 3.5, runing the program will bring the following warning : EXCEPTION WARNING The thread tried to read from or to write to a virtual adress for wich it does not have the appropriate access. [ Ok ] Then the application crash. No more debugging possible. For version 3.3 and 3.4, the manipulation had the following result. I'll come back later on the 3.5 version, please read on if you hadn't read the previous version of this tutorial, otherwise you can jump ahead the next three paragraphs : 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, but we could have done as well. (Thanks crUsAdEr for pointing me this :)). Clicking on a string in the W32Dasm List of String Data Items will lead you to the first occurence. CLicking again will bring you to the next one. We do it through the search menu this time, but that's not mandatory. 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 004D672B (****). For version 3.3, the adress was 004D5AC3, for version 3.4 the adress was 004D618B. But aside that, again the code shown is the same for version 3.3, 3.4 and 3.5. :004D6716 48 dec eax :004D6717 0F8581000000 jne 004D679E :004D671D A1948E4E00 mov eax, dword ptr [004E8E94] :004D6722 8B00 mov eax, dword ptr [eax] :004D6724 80B8DC02000000 cmp byte ptr [eax+000002DC], 00 :004D672B 745C je 004D6789 <== (****) :004D672D 8B45FC mov eax, dword ptr [ebp-04] :004D6730 8B9044040000 mov edx, dword ptr [eax+00000444] :004D6736 8B45FC mov eax, dword ptr [ebp-04] :004D6739 8B8008040000 mov eax, dword ptr [eax+00000408] :004D673F E88CD9F6FF call 004440D0 :004D6744 8B45FC mov eax, dword ptr [ebp-04] :004D6747 8B9074040000 mov edx, dword ptr [eax+00000474] :004D674D 8B45FC mov eax, dword ptr [ebp-04] :004D6750 8B8008040000 mov eax, dword ptr [eax+00000408] :004D6756 E875D9F6FF call 004440D0 :004D675B 8B45FC mov eax, dword ptr [ebp-04] :004D675E 8B907C040000 mov edx, dword ptr [eax+0000047C] :004D6764 8B45FC mov eax, dword ptr [ebp-04] :004D6767 8B8008040000 mov eax, dword ptr [eax+00000408] :004D676D E85ED9F6FF call 004440D0 :004D6772 6A00 push 00000000 :004D6774 668B0DD0674D00 mov cx, word ptr [004D67D0] :004D677B B202 mov dl, 02 * Possible StringData Ref from Code Obj ->"Code Accepted! Thank you for registering " ->"our software." | :004D677D B8DC674D00 mov eax, 004D67DC :004D6782 E8191AF8FF call 004581A0 :004D6787 EB15 jmp 004D679E * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:004D672B(C) | :004D6789 6A00 push 00000000 :004D678B 668B0DD0674D00 mov cx, word ptr [004D67D0] :004D6792 B202 mov dl, 02 * Possible StringData Ref from Code Obj ->"Code Not Accepted! Please try " ->"again (Licensee Name is case sensitive)." | :004D6794 B81C684D00 mov eax, 004D681C :004D6799 E8021AF8FF 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 :004D672B follow few line manipulating caracters. :004D671D A1948E4E00 mov eax, dword ptr [004E8E94] :004D6722 8B00 mov eax, dword ptr [eax] :004D6724 80B8DC02000000 cmp byte ptr [eax+000002DC], 00 It is PROBABLY (just my opinion) the last stages of the correct code computation. We'll attempt to define the BP on 004D671D (004D5AB5 for v3.3, 004D617D for v3.4), 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. With version 3.5, we land again on the Exception Warning. Previous version worked as follow (we'll be back on 3.5 version just after having extracted the right serial for version 3.3 and version 3.4) : 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.... Now, back to the 3.5 version. Clearly they have made some changes. Anti-debuggers tricks added ? let's see first some basic workaround : We had made all the process of getting the serial for all version studied by going through the registration screen from the menu when we where inside the application. But we can also get this registration screen from the startup, by clicking the Register button. Let's see if going from the startup change something. Load the ftpprem.exe in W32Dasm, from the Debug menu make a Load Process, set the breakpoint at 004C8C70 (as previously found at the first stage), run the debugging session, on the startup screen click on the [Enter Registration Code] button. The screen appears WITHOUT the exception raised. Good. From there, as we've done for versions 3.3 and 3.4, we enter our fake informations and click on the [ Ok ] button: Licensee Name : UnderCover Registration Code : 23452345 We got the warning "Code not accepted". Launching WinHex and making a search on "undercover" or "23452345" give as result : Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F 00D6A9F0 00 00 00 00 B8 52 43 00 B0 A7 D6 00 1A 00 00 00 ....¸RC.°§Ö..... 00D6AA00 58 A0 41 00 00 00 00 00 00 00 00 00 30 9B D6 00 X A.........0›Ö. 00D6AA10 00 00 00 00 26 00 00 00 00 00 00 00 17 00 00 00 ....&........... 00D6AA20 45 6E 74 65 72 20 52 65 67 69 73 74 72 61 74 69 Enter Registrati 00D6AA30 6F 6E 20 43 6F 64 65 00 1A 00 00 00 00 00 00 00 on Code......... 00D6AA40 0A 00 00 00 55 6E 64 65 72 43 6F 76 65 72 00 00 ....UnderCover.. 00D6AA50 50 AA D6 00 50 AA D6 00 18 00 00 00 37 30 36 35 PªÖ.PªÖ.....7065 00D6AA60 39 32 34 37 18 00 00 00 1F 00 00 00 00 00 00 00 9247............ 00D6AA70 0D 00 00 00 37 30 36 35 39 32 34 37 34 2D 39 36 ....706592474-96 00D6AA80 38 00 FF FF 00 00 01 00 00 00 00 00 00 00 00 00 8.ÿÿ............ 00D6AA90 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ We land on the good result !!! See ? As our usual way to retrieve the serial didn't give any result, we achieve to get it using another path. And the second path was as easy as they where in previous version. If the modification of the version 3.5 where done in the aim of protecting the software from that kind of piracy, then we can say that the job have been done only at 50%. The two roads to the serials where apparents since the 3.3 release. Only one was used to get a serial. Funny, this is exactly the one that seem protected by now. Or we've reach a bug that only affect one function. Strange thing, here, is that the serial generation routine didn't change at all. We could have blindly issued the 3.3 serial and it would have worked. If they have released this version for anti-cracking purpose, then I think they have missed a point somewhere. As the release state that the new version was a maintenance release correcting some memory leaks, we may have a side-effect of the correction. Otherwise, we can expect some hardened anti-cracking stuff in version 3.6. The point here to recall, is that if you don't succeed using one way, you may succeed using another, as easy way. Always search the weakest point. But what could have been done in case the second road was as well protected ? Using ExeScope, let's have a look at our PE header, precisly the Section Flag of the code section. We currently got : adress value meaning 0000021C 60000020 Section Flag (Readable, Executable, Code) This could be a kind of protection. It's often used to confuse W32Dasm. Usual value to overcome this situation is such as E0000020 or E0000060. But this is probably not our problem, as this protection lead W32Dasm to disassemble nothing. That was not our case, as we could get the death listing, so we'll have to look at somewhere else. Done for confirmation, lead to the same Exception Warning as before. We probably face a protection that raise an exception and check if something handle the exception (such as a debugger). To be able to handle that, we need a debugger that will pass the exception to the program. So, we'll drop W32Dasm for now and turn our attention at OllyDebug. OllyDebug is in my mind far more powerfull than W32Dasm for some tasks, where W32Dasm gain in easy handling and clarity. Launch OllyDebug, from the menu File -> Open, select the ftpprem.exe file. The OllyDebug main windows is divided in 4 parts. On top left, the disassembled listing, on top right you got the contents of the registers, down left you got a dump of the memory and down right you got the stack. Once there, we'll do it the same way we've done previously : 1 - Search for the string "Code Accepted! Thank you for registering ". To do this, on the disassembled listing windows, right-click and select "Search for..." in the drop-down menu, then select "All referenced text strings". A new window open, and we find our strings there. Text strings referenced in Ftpprem:CODE, item 7664 Address=004C8C8B Disassembly=MOV EAX,Ftpprem.004C8CC8 Text string=ASCII "Code Accepted! Thank you for registering our software." Text strings referenced in Ftpprem:CODE, item 8505 Address=004D677D Disassembly=MOV EAX,Ftpprem.004D67DC Text string=ASCII "Code Accepted! Thank you for registering our software." 2 - Move to the code part in order to find where to place our BP. To do this, select the second reference (something taken from our past experience) and double-click on it. We are back on our disassembled listing. 004D6717 |. 0F85 81000000 JNZ Ftpprem.004D679E 004D671D |. A1 948E4E00 MOV EAX,DWORD PTR DS:[4E8E94] 004D6722 |. 8B00 MOV EAX,DWORD PTR DS:[EAX] 004D6724 |. 80B8 DC020000 >CMP BYTE PTR DS:[EAX+2DC],0 .... .... 004D677D |. B8 DC674D00 MOV EAX,Ftpprem.004D67DC ; |ASCII "Code Accepted! Thank you for registering our software." 004D6782 |. E8 191AF8FF CALL Ftpprem.004581A0 ; \Ftpprem.004581A0 004D6787 |. EB 15 JMP SHORT Ftpprem.004D679E 3 - Set the Break-Point and Run the proggy. Select the following line in the disassembled window : 004D671D |. A1 948E4E00 MOV EAX,DWORD PTR DS:[4E8E94] Right-click on it, and from the drop-down menu select Breakpoint, then Toggle. As there where no BP at this adress, now one is set. From the debug menu, select run. Wait for the first screen to pop-up, click on the close button to go in the application. 4 - Waiting to reach our break-point. This was straight forward for version 3.3 and 3.4, we've seen that this will not be the case for version 3.5. Effectivly, our debugger stop at the following adress: 77E814BA 66:8338 00 CMP WORD PTR DS:[EAX],0 There is an access violation on reading of the memory. But with OllyDebug, we can pass the exception back to the program. We do that by using the keys [Shift]+[F9]. [F9] is the shortkey for run. Once done, we land a second time on the same part of code, press [Shift]+[F9] again. Then we land on a third exception : 77F1D473 FF15 B4C3F377 CALL DWORD PTR DS:[<&ntdll.RtlRaiseExcep> Bypassing this one, will lead us to our application running. From there, enter some flase data, wait for the prog to reach our break-point, and check the memory with WinHex. FoolFox *[The end....this is the end, my friend...(The Doors)]****************************** *[EOF]******************************************************************************