LESSON 9 (2) - How to Wincrack, Hands on Nagscreens galore: The Paint Shop Pro crack (part A) Merry Xmas. We'll learn, beginning with this lesson, how to eliminate the "nagscreens", i.e. the protection and or annoying schemes that many commercial and shareware windows programs use in order to annoy us and push lusers to buy them. In order to understand (simple) nag screen deprotection we'll crack following different approaches Paint Shop Pro, the de facto standard used to day for graphic manipulation. It's a good choice, I believe, because - it's a very widespread application: you'll surely have some copies of it on your CD-ROMs, and you'll find many copies on the Web (albeit not cracked ones until now: the only cracks I am aware of are patches that simulate the user clicking on the OK button of the nagscreen, thus closing it, but not eliminating it). - this application has many older versions: I want to teach you here also a "general" approach strategy that you should often follow when (and if) you'll start higher cracking: the *very* important study of the "embryology" of the software you want to crack. The long history trail of the "ancient" copies of your target will help you a lot to understand its evolution and the parallel evolution of its protection scheme ("Historia lux veritatis... magistra vitae", hope you did not forget your Cicero :=) The case of the nagscreen evolution of PSP is particularly evident: 1) static nagscreen ;1993, Ver. 2.0, PSP.EXE = 525.520 bytes 2) daycount added ;1994, Ver. 3.0, 861.856 bytes 3) delayed OK focus ;1995, Ver. 3.2-32, 1.042.944 bytes 4) ported to Win95 ;1996, Ver. 4.1, 1.151.488 bytes In the meantime many functions have been added to the program whose size has broken all limits. Let's begin our crack with the oldest copy of Paint Shop Pro i could find: I want to stress that knowledge of history is very important (there should be a faculty of "software history" in all great universities, there will be of course one in my +HCU). I'll use the old SHAREWARE version 2.01, whose file PSP.EXE has a length of 525520 bytes and is dated 15 november 1993. Just to make a comparison, version 3.0 has a PSP.EXE file of 861856 bytes, and is dated 4 march 1995, version 3.12-32 (Win31) has a PSP.EXE length of 1.042.944 bytes, and is dated 27 december 1995 and version 4.1 for windows 95 has a PSP.EXE with much too many bytes which is dated 1 september 1996: a classical example of overbloated programming language involution. Version after version JASC incorporated added the "counter" that reminds you how many days you have been using this program, telling you to register it after 30 days. This nagscreen is by far and large not particularly annoying, JASC has been pretty correct (compared with other nagscreens used by less interesting but more preposterous software). Nevertheless we do not like nagscreens all the same, coz we want to enjoy all programs, commercial or not, without paying any money at all and without silly nagscreens or reminders of any sort (all sort of goods should be free in my opinion, not only software: I think I am a sort of "aristocratic communist": I believe that private property is a theft -of course- and that everybody should have -at least- a sail Yacht, good books, a lot of caviar and good Wodka-Martinis in crystal glasses without paying anything at all: all this should be completely free in order to allow each one to concentrate on interesting activities like wind watching, poetry, micro-ethology, study of the colours, cracking, ancient rhetoric et cetera). Anyway, in this old PSP, version 2.01, there was in the nagscreen no day counter yet ("you are on day xx of your 30 days..."), a "static" nagscreen, the whole program is still very "basic", nobody would have said, looking at this midget, that Jasc could have evolved this embryo of a program, in three years, in the de- facto standard graphic manipulation program that we know to day (december 1996). Let's crack: We fire our Winice (I will not explain any more why you should use Winice: buy (or codebar) a "real" copy of it or else find all three cracked copies, DOS, WIN31 and WIN95, on the Web. Then learn how to use it well: this tool is the alpha and omega of cracking... I am using for this lesson a Windows 3.1 computer with my Winice for Windows 3.1, version 1.3, cracked by the ubiquitous Marquis de Soiree). We begin now, Winice lurks already behind Windows, Microsoft abomination has already been started, a cool breeze blows outside, I fire PSP 2.1. We'll use in this lesson a couple of different approaches to code pinpointing: you'll remember that we could have done our three steps basic approach, as usual (always working, but at times slower or more inaccurate than other approaches): 1)task 2)hwnd 3)bmsg relevant_window wm_gettext sequence of commands, as follows 1) :task TaskName SS:SP StTop StBot StLow TaskDB hQueue Events PROGMAN 1727:200A 0936 2070 1426 066F 07F7 0000 PSP * 1D27:D826 9654 D9BE D132 11EF 11D7 0000 2) :hwnd psp Window Handle hQueue QOwner Class Name Window Procedure 0EB4(0) 11D7 PSP #32769 04A7:9E6B 25B8(1) 11D7 PSP Histogram 1197:07E8 2090(1) 11D7 PSP #32770 1D07:120E 20F0(2) 11D7 PSP Static 1D07:38A6 2138(2) 11D7 PSP Static 1D07:38A6 2180(2) 11D7 PSP Static 1D07:38A6 21D8(2) 11D7 PSP Static 1D07:38A6 2230(2) 11D7 PSP Static 1D07:38A6 2298(2) 11D7 PSP Static 1D07:38A6 22F0(2) 11D7 PSP Button 1D07:2876 2344(2) 11D7 PSP Button 1D07:2876 2398(2) 11D7 PSP Static 1D07:38A6 23F0(2) 11D7 PSP Static 1D07:38A6 2448(2) 11D7 PSP Static 1D07:38A6 24A0(2) 11D7 PSP Static 1D07:38A6 ... (and more handles, the segment numbers may obviously differ from yours) Since the two "buttons" are the OK and CANCEL buttons inside the nag screen, we can immediately pinpoint the code with a 3) :bmsg 22F0 wm_gettext command, which would fire back winice as soon as we click the OK button. You'll please also notice from the hwnd list above that the window #32770 has 6 small "text" windows inside and two buttons, that the window procedure for the main nag window is at 1D07:120E, the procedures for text are at 1D07:38A6 and the procedures for the buttons are at 1D07:2876. We'll come back on this approach later. It's the typical pinpointing used for password protection schemes, as we have seen in the password lessons, but this approach is NOT the best one for nagscreens. Let's follow now another approach: let's find the nagstrings in the parts of PSP that contains DATA (as opposed to CODE), the :heap command will help us: it's the standard command to understand the STRUCTURE in memory of your deployed applications, you'll use it a lot for nagscreen cracking and for time limits deprotections. :heap psp ; we know from :task that the name is "PSP" Han./Sel Address Length Owner Type Seg/Rsrc 1C37 00027980 00000040 PSP Alloc 0876 000279C0 00000020 PSP Resource IconGrp 1FFE 806EC760 000010A0 PSP Code 03 1BA6 LH 806B2000 0000E9E0 PSP Data 90 2016 807CC340 00003C60 PSP Code 01 200E 80774780 00002940 PSP Code 02 ... (many more handles) As you can see doing your listing, there is only one data block, E9E0 bytes long, at 806B2000. Have a look at the code blocks, though, many of them, as you'll see, have a little "D" after the type CODE, as you'll use often and often this :heap command to crack protection schemes in the future, you may as well learn right now that these are (most of the time) uninteresting for cracking purposes. If we now pinpoint this code with a bpr RW on part of the text that the nagscreen displays, we'll land in the middle of the routine that copies this text in various memory locations, each time PSP runs: :bpr 30:806B2150 30:806B2170 RW Let's start PSP once more and we'll land here inside winice: 011F:00007A1B D1E9 SHR CX,1 011F:00007A1D F366A5 REPZ MOVSD ;this writes in 806B1250 011F:00007A20 8BC8 MOV CX,AX 011F:00007A22 83E103 AND CX,+03 011F:00007A25 F3A4 REPZ MOVSB Hope that my readers DO remember that REPZ is repeat string manipulation until cx=0 and that MOVSD moves strings by doublewords, from ds:si to es:di, updating si and di. We are here in the piece of the main windows KERNEL module, responsible for setting up this part of PSP. Now things start getting interesting: if you make a search for the string 'freeware' (contained in the nagscreen of PSP) before loading psp you'll get as location only the echoes of your own search string: :s 30:0 lffffffff 'freeware' Pattern found at 0030:007DBA58 0030:008E107F 0030:008E1867 0030:008E601A If you search the same string after the KERNEL's has finished copying around PSP code (as we saw above) you'll fetch quite a lot of locations: :s 30:0 lffffffff 'freeware' Pattern found at 0030:0066242D 0030:007DBA58 ;echo 0030:007DBFCA 0030:008E107F ;echo 0030:008E12A8 0030:008E1867 ;echo 0030:008E601A ;echo 0030:009EDF4D 0030:806A4F4D The last one is the more interesting one, being above 80000000. But, hey, how comes that the 'freeware' text occurrence at 30:806B2170 (the one we breakpointed into) has not been found? It's an interesting point, and you could now obviously bpr RW all the relevant locations to trace backward to the "culprit" code section of PSP, the one setting up the nagscreen that we want to eliminate. But we'll now leave even this second approach and follow a third and better one for nagscreen deprotection: the "stack_crack" technique (I want to show you the MANY possibilities that we have for cracking these programs. As everybody (should) know, every time a child window (or a pop- up window) is created, the function that must be invoked is HWND CreateWindow, which is called by virtually all windows programs. This function specifies the window's class, title and style, and may also determine the window's initial screen location and size. This function returns the handle to the newly created window. It's a general purpose API function with this structure: HWND CreateWindow(LPCSTR lpszClassName, LPCSTR lpszWindowName, DWORD dwStyle, int iX, int iY, int iWidth, int iHeight, HWND hPArent, HMENU hMenu, HINSTANCE hINst, void FAR *lpvData) And, for those of you that do not know nothing, lpszClassNAme points to a character string naming the window's class and lpszWindowName points to a character string identifying the window by name, which is pretty useful for us little crackers... you should study a little this kind of stuff, just to make an example, do you know that EDIT Class control style ES_PASSWORD displays all typed characters as asterisk symbols? (Whereby setting EM_SETPASSWORDCHAR to zero will print the password echo on the display, but this is stuff for another lesson :=) Let's work with the breakpoint on the CreateWindow function we have seen above, obviously, now that you know all the parameters, you could as well change the position of the nagscreen (iX, iY, iWidth...) instead of removing it. :bpx CreateWindow And now let's fire PSP, look at the screen! We pop in winice 5 times before the relevant moment (i.e. just before the nagscreen). Therefore we change our breakpoint, setting the occurrence "6" for the counter: :bpx USER!CREATEWINDOW C=06 Now we fire PSP once more and this time we look at the stack as soon as we pop inside Winice, because we know that the last CreateWindow has created the nagscreen and we want to know where is the "culprit" section of PSP code: :stack PSP(05) at 1EF7:00AF [?] through 1EF7:00AF PSP(05) at 1EF7:1094 [?] through 1EF7:1076 PSP(01) at 1F3F:0598 [?] through 1F3F:0000 PSP(8A) at 1F0F:0024 [?] through 1F0F:0000 USER(19) at 073F:099B [?] through USER!DIALOGBOX USER(19) at 073F:0A31 [?] through 073F:09A3 USER(19) at 073F:07FC [?] through 073F:0737 PSP(01) at 1F3F:0BC0 [?] through 1F3F:0BC0 PSP(02) at 1F2F:0DF7 [?] through 1F2F:0000 => USER!CREATEWINDOW at 06B7:0F1B [?] through 1EBF:0052 That's nice music for us! Let's have a deep look at these pretty data: See! The last CreateWindow occurrence is called by Segment 02 of the PSP code (you remember the :heap PSP command listing, we made for the first approach, if not do it now: the heap listing will show you the complete structure in memory of your target)... and yes, let's have a look at segment 2, the locations around DF7: here the relevant section of code: 1F2F:00000DEB 90 NOP 1F2F:00000DEC 687A70 PUSH 707A 1F2F:00000DEF FF36068F PUSH WORD PTR [8F06] 1F2F:00000DF3 FF36FC70 PUSH WORD PTR [70FC] 1F2F:00000DF7 9A5200BF1E CALL 1EBF:0052 ;call the bazaar Following this last call, we land in the USER(19) code section of windows USER module, which sets up a child window (in this case the nag screen) and then waits for user's mouse clicks. 073F:0000083E 56 PUSH SI 073F:0000083F 6A01 PUSH 01 073F:00000841 9AF20BE706 CALL 06E7:0BF2 ;makes the nagframe 073F:00000846 56 PUSH SI 073F:00000847 9A0444A704 CALL 04A7:4404 ;writes the nagtext 073F:0000084C 3936E200 CMP [00E2],SI But USER should obviously not be cracked (well, you could, but not here... see the lesson about windows "guts": KERNEL, USER and GDI and the possibilities you get cracking them directly), but here our culprit protection scheme must of course dwell inside the PSP code... therefore let's now have another look at the task list we found breakpointing on CreateWindow. All the three user(19) codes are USER module's routines, let's see... where should we cut mustard with our crack? Obviously BEFORE the call to USER(19), also either in PSP(8A), or in PSP(01) or in PSP(05). Three possibilities: 1) Study a disassembled listing. A nice disassembly listing can be very helpful for our cracks (through good old WCB or through WDASM, cracked copies of all these nice disassemblers are on the Web). Useless an d tedious in this case. 2) Have a direct look. There are in this case only three sections of code, just have a look at them and find in which one triggers the protection. Useless an d tedious in this case. 3) -Always better- use a little zen. Relax, sip a Martini-Wodka (be careful: only Moskowskaja will do, do not exceed the correct amount of Schweppes' indian tonic) and look once more at the :heap PSP listing. See? Segment 8A of PSP code is only A0 bytes long, therefore pretty unlikely to yield a protection scheme. That leaves segments 05 and 01. Segment 05 does not have enough "run" to hyde a protection scheme (yes, this is zen): as you can recall from our stack listing, the two occurrence of segment 05 have only a zero run (AF-AF) or a very short one (76-94). See? Out of the three sections we started with remains only one: code section 01, which is 3C60 bytes long, has sufficient "run" (0-598) and will therefore -for sure- hide inside the protection scheme. Well, 3C60 bytes is quite a long piece of code to examine (even if we started with more than half a million bytes in the first place)... but we do not need to look much around, the protection will be not far away from our call (for reasons I'll not delve inside here... remember lesson C3 ?). We'll have a look at fifty bytes, and having to sieve less than 100 bytes do not seem to me to represent an unreasonable amount of work in order to eliminate a nagscreen, nicht wahr? Let's have a look at the code in segment 1, examining -say- 50 bytes around the locations at segment PSP(01), all info we found using Winice's :heap command: ... PSP(01) at 1F3F:0598 [?] through 1F97:0000 ... Here the code -through Winice- with my comments: 1F3F:0000056D 0BC0 OR AX,AX ;conditional 1F3F:0000056F 740D JZ 057E ;jump, if not 1F3F:00000571 9AA802BF10 CALL 10BF:02A8 ;this chooses 1F3F:00000576 50 PUSH AX ;the hWnd which 1F3F:00000577 6A04 PUSH 04 ;04=activates 1F3F:00000579 9A3E10E706 CALL USER!SHOWWINDOW ;herein 1F3F:0000057E A1FC70 MOV AX, [70FC] ;now load AX 1F3F:00000581 A30C6F MOV [6F0C],AX ;save a copy 1F3F:00000584 C706FC700000 MOV WORD PTR [70FC],0000 ;clean 1F3F:0000058A 682711 PUSH 1127 ;and load the other 1F3F:0000058D 686601 PUSH 0166 ;parameters for the 1F3F:00000590 686B0A PUSH 0A6B ;call, which are 1F3F:00000593 FF36068F PUSH WORD PTR [70FC] ;all pushed 1F3F:00000597 50 PUSH AX ;on the stack for 1F3F:00000598 9A00005F11 CALL 115F:0000 ;this final call 1F3F:0000059D 83C40A ADD SP,+0A ;Now it's 1F3F:000005A0 0BC0 OR AX,AX ;finished Well, what do we have here? We have the whole nagscreen procedure at a glance: The call to USER!SHOWWINDOW is a BOOL ShowWindow (HWND hWnd, int iVisFlag) function, which determines the specified window's visibility state. hWnd is the handle of the window and iVisFlag determines how the window is shown. This function returns true if the window is already visible, false if the window was hidden. iVisFlag can be one of the SW_ constants, number 4 is activate and display. The program fetches at the previous call the AX parameter and then calls the routine that prepares the nagscreen. OK, we found it (was pretty easy, as you saw). Now, how do we crack this? There are one hundred thousand ways (an elegant one would be changing the iVisFlag option). I would suggest something rock solid: putting a JNZ 059D at line 1F3F:0000056D, replacing the JZ 057E on a "two for two" bytes basis, a clean crack. And loo! It works flawlessly: we fly over the nagscreen. Here is the crack with good old symdeb... you may use symdeb but you may obviously use more "modern" hexeditors, like PSedit (good old DOS) or Hexworkshop (bloated Windows), you'll find everything on the Web: *** cracking PSP 2.1 nagscreen *** by +ORC *** dec 1996 *** ren psp.exe psp.ded ;need a "dead" copy for old symdeb symdeb psp.ded ;good old symdeb launched - s (cs+0000):0 Lffff 0B C0 74 0D 9A ;search 1F3F:0000056D etc xxxx:yyyy ;result from debug - e xxxx:yyyy+2 75 ;change JZ in JNZ - e xxxx:yyyy+3 2C ;jump after final call - w ;write back our changes - q ;bye symdeb ren psp.ded psp.exe ;ok, cracked, restore exe ***** see how easy? ****************************************** But we are not finished yet! Let's now come to the real content of this lesson: how you should apply what you have learned on an OLDER copy of the target software to the newer versions of it. We'll crack now PSP, version 3.0, where the psp.exe file is 861.856 bytes long, this copy dates 4 march 1995, 2 *YEARS* after the older one, it's a newer and improved program, with a lot of functionality. Now, you would think that we must start anew, breakpointing with a :bpx CreateWindow C=07 (in this case) command? No. They changed a little the routines (here you would be advised to use a :bpx ShowWindow breakpoint following the same approach). The new nagscreen has been coupled with a daycounter, that reminds your guilty as the days goes by, but the nagscreen schema has not changed much: it has been hidden this time in Segment PSP30(07), and you would find it -of course- following the abovementioned approach, but what's the point? there is a much quicker way! I'll never repeat it enough: PROTECTIONISTS ARE STUPID! As usual with people working for money instead than for pleasure, their capacity is severely limited, one of the ugly consequences of the abominable society we are coerced to live in. This overvbloated monstrosity, PSP30, is nagscreened with the SAME simple schema used in the older versions, therefore you just search and modify it using the SAME patterns (and in the same way) as before! We'll use now PSEDIT in order to modify this file, symdeb.com is a good tool, but has memory problems when the programs exceed 600.000 bytes (at the times symdeb was made people knew how to code in assembler and nobody would have ever thought that you needed so much to perform so little). **** Cracking PSP version 3.0, by +ORC *** December 1996 ren psp.exe psp.ded ;always good, even if psedit does not care psedit psp.ded ;fire your tool - use F8 (search) to search for hexstring 0BC0740D9A You'll find three occurrences of it. Looking at the code you'll immediately realize that the only good one is the third one. Just modify the JZ 0D sequence in a JNZ 2D sequence (yes one byte more than in the previous crack, look at the code) and you'll have done your crack. F2 ;quit PSEDIT ren psp.ded psp.exe ;restore exe **************** pretty easy, wasn't it? *********************** A little digression: Why do we search for the hexstring 0BC0740D9A and not for a longer string? You may think that a longer search string would have immediatly given us the correct location, and you may see no point in using a shorter string, which may obviously give us many more useless hits. You would be dead wrong: one byte more (after 9A) and you would not fetch anything at all! The problem, for those of you that do not know nothing, is that same hexcodes are RELOCATED each time an EXE program compiles in memory (this was true for DOS, for windows there is a real relocation galore going on behind the scene, one wonders at times that windows get something accomplished at all, given the huge amount of relocations that this overbloated pseudo-OS pushes around. Choosing a search hexstring you must always be *very* careful: choose search patterns that DO NOT relocate in memory, like OR AX,AX, JZ fixed length, ADD SP,+0C, JL fixed length and so on. Your searches for hexstrings that do relocate will not harvest anything at all. Never. HAve a good look at the following code examples, you'll recognize immediately that only the third (and last) occurrence of our search string is the correct one: it is the only one that shows "later on" shows the correct instruction sequence (the later three moves and five PUSHES we have seen in the listing for PSP 2.1 above). Let's have a look at the three occurrences of our search string inside PSP30: Occurrence 1 of search string 0BC0740D9A inside PSP30: 1CEF:0000B8E3 0BC0 OR AX,AX ;checks previous call 1CEF:0000B8E5 740D JZ B8F4 ;it's zero, forget show 1CEF:0000B8E7 9AE413671C CALL 1C67:13E4 ;new call to fetch 1CEF:0000B8EC 50 PUSH AX ;the hWnd for show 1CEF:0000B8ED 6A04 PUSH 04 ;activate 1CEF:0000B8EF 9A3E10E706 CALL USER!SHOWWINDOW ;herein 1CEF:0000B8F4 FF363E46 PUSH WORD PTR [46E3] ;fetch hWnd 1CEF:0000B8F8 9A2D19A704 CALL USER!ISICONIC ;is iconic? 1CEF:0000B8FD 0BC0 OR AX,AX ;check if zero 1CEF:0000B8FF 7537 JNZ B938 ;it's iconic! Here you see that after our search string "0BC0740D9A" follows a "E4" byte. The function "IsIconic" has nothing to do with our protection scheme. This function returns non zero if the specified windows (pointer at location 46E3) is displayed in its iconic form, zero if it is not. Well it's definitely NOT our protection scheme: we should find (at least) three MOV instructions and four PUSHES instructions (see PSP21) after our call to SHOWWINDOW, and our protection scheme has nothing to do with any call to ISICONIC. Let's have a look at occurrence 2 of our search string inside the code of our PSP30 target: Occurrence 2 of search string 0BC0740D9A: 1CEF:0000B927 0BC0 OR AX,AX ;checks previous call 1CEF:0000B929 740D JZ B938 ;it's zero, forget show 1CEF:0000B92B 9A5817A71C CALL 1CA7:1754 ;new call to fetch 1CEF:0000B930 50 PUSH AX ;the hWnd for show 1CEF:0000B931 6A04 PUSH 04 ;activate 1CEF:0000B933 9A3E10E706 CALL USER!SHOWWINDOW ;herein 1CEF:0000B938 FF363E46 PUSH WORD PTR [46E3] ;fetch hWnd 1CEF:0000B93C 9A2D19A704 CALL USER!ISICONIC ;is iconic? 1CEF:0000B941 0BC0 OR AX,AX ;check if zero 1CEF:0000B943 7537 JNZ B97C ;it's iconic! Well, hey, no, we are not yet there... this is just a "mirror" of the previous occurrence one! That means a complete repetition of the same code of occurrence one... tehrefore the same as above yelds true: it is not yet our protection scheme. Here you see that after our search string "0BC0740D9A" follows a "58" byte. Let's see the third (and last) occurrence of our search string: 1CEF:0000B96B 0BC0 OR AX,AX ;checks previous call 1CEF:0000B96D 740D JZ B97C ;it's zero, forget show 1CEF:0000B96F 9A1E958F1C CALL 1C8F:951E ;new call to fetch 1CEF:0000B974 50 PUSH AX ;the hWnd for show 1CEF:0000B975 6A04 PUSH 04 ;activate 1CEF:0000B977 9A3E10E706 CALL USER!SHOWWINDOW ;herein 1CEF:0000B97C A13E46 MOV AX,[463E] 1CEF:0000B97F A33A3C MOV [3C3A],AX 1CEF:0000B982 C7063E460000 MOV WORD PTR [46E3],0000 1CEF:0000B988 68EF1C PUSH 1CEF 1CEF:0000B98B 687C21 PUSH 217C 1CEF:0000B98E 1E PUSH DS 1CEF:0000B98F 680217 PUSH 1702 1CEF:0000B992 FF36105C PUSH WORD PTR [5C10] 1CEF:0000B996 50 PUSH AX 1CEF:0000B997 9AA401271D CALL 1D27:01A4 ;final call 1CEF:0000B99C 83C40C ADD SP, +0C ;resume Here we are! This is obviously our protection scheme, see the analogies (almost identities) with the older PSP21 nagscreen protection we found and cracked above! In this third occurrence you see that after our search string "0BC0740D9A" follows a "1E" byte. To defeat this protection along the same line of our previous PSP21 crack, we could jump -here- to the 1CEF:0000B99C (resume after final call) instruction, modifying the instruction at 1CEF:0000B96D (740D JZ B97C) -exactly as we did in PSP20- to a nice JNZ B99C 75 2D (that's the distance between the location of this very JNZ instruction and the location where you want to jump, coz b99C-(b96D+2) = 2D. This crack requires a byte more (2D instead of 2C) than in PSP21 to fly over the nagscreen calls, coz an extra PUSH DS has been added inside this version's nagscreen protection scheme (a reason more to be careful with "longer" search strings: if you fetch too many occurences with a short search string you just "cross check" the same occurrences with another short search string from a later prortion of the code you are trying to individuate: write a short program to do it automatically for you: the best cracking tools, remember, are the tools that you write yourself). A last word, should you be interested in the "final call" of this nagscreen scheme: it's a routine (here inside module PSP30(04) which calls the two functions KERNEL!MAKEPROCINSTANCE (which must be called for 16 bits Windows in order to effectuate a call to Dialogbox) and USER!DIALOGBOX, which is (de facto) the nagscreen itself. Now let's go over to the last version of PAint Shop Pro for Windows 3.1 I know of: PSP.EXE version 3.12-32, length: 1.042.944 bytes, 27 december 1995. Let's bpx on CreateWindow and let's see... We fire PSP and we pop inside Winice at the *only* occurrence of CreateWindow... MMM! Something fishy here? When you proceed as above you get only one break in Winice on bpx CreateWindow, and no stack at all, just the CreateWindow call! You do not get no heap segments for PSP32 either... how comez? The fact is, that in order to crack Win32 applications like this one, we must move over to Winice95, coz Winice for Win3.1 has its limits. You'll of course find Winice 95 on the Web, there are always cracked copies roaming around, the best pages offer some links to them, you should learn HOW TO SEARCH. You'll find everything on the web for free, as a matter of fact. It's amazing HOW MUCH you can get from internet, and this could make the Web potentially dangerous from a "human-social" point of view... how will we keep social and human contacts if we roam around so much without ever touching each other? A good idea in order to re-establish somehow our "humanity" "contact" balance is to seek physical contact not only with your loved one (which is always very good) but also with many other human beings: I have for instance three massage sessions every week with my masseuse, which is half my age but strong enough to cure my rheumatisms... just to make another example, I enjoy very much all restaurants which have the so called "tables d'hote" i.e. where everybody sits together at a couple of long tables, me, my wife and my kids exchanging views and opinions with other people, people you never saw before and will probably never see again, drinking excellent wines, instead of sitting grimly on the petty, bourgeois, "4 chairs" little tables for stupid greedy families that abound inside "normal" restaurants... (I'll not ever mention the "fast food" abominations: I am definitely in favour of "slow food" and believe McDonald should be hanged for what he has done -in the whole world- to 4000 years of gorgeous gastronomical traditions... what's the point of eating quickly (and badly), unless you are a slave of your time?)... enough: You could crack Win32 applications even using Winice for Windows 3.1 though, albeit slowly... you would have to go through Winice's VxD command, and need a little zen and a deep understanding of virtual memory management in Windows. Anyway, there is no point in using wrong tools. Should you however try to crack Win32 applications with Winice 3.1, have a look first of all at the modules inside windows as soon as winice pops up, using Winice's command :mod... there you'll find the hmod=1C3F W32SCXXXX D:\PSP\PSP.EXE Now :heap w32sxxxx in order to get the heap segments you need to start your crack with. However, as I said, we better crack applications like this one using Winice for Windows 95 and we'll see together -in the next lesson- that the nagscreen of the 3.12-32 version AND the one in the Windows 95 "4.1" version (the last one I know of) can both be cracked pretty quickly on the same line as the previous ones. We will also see that the nagscreen mechanism -believe it or not- is more or less always the same. The protectionists added a "delayed" OK button focus and mixed some "alien" (but useful) routines in-between. This said, it's still always the same soup, as usual with nagscreens and mercantile programmers. Well, that's it for this lesson, reader. Not all lessons of my tutorial are or will be on the Web. You 'll obtain the missing lessons IF AND ONLY IF you mail me back (via anon.penet.fi) with some tricks of the trade I may not know that YOU discovered. Mostly I'll actually know them already, but if they are really new you'll be given full credit, and even if they are not, should I judge that you "rediscovered" them with your work, or that you actually did good work on them, I'll send you the remaining lessons nevertheless. Your suggestions and critics on the whole crap I wrote are also welcomed. Do not annoy me with requests for warez, everything is on the Web, learn how to search, for goddam sake. "If you give a man a crack he'll be hungry again tomorrow, but if you teach him how to cPKl/#5I SOLYTARE.GFXj0!7 8ink.