+ORC Tutorials


LESSON 9 (2) - How to Wincrack, Hands on
Nagscreens galore: The Paint Shop Pro crack (part A)

How to crack, an approach LESSON 1
How to crack, tools and tricks of the trade LESSON 2
How to crack, hands on, paper protections LESSON 3.1  3.2
How to crack, hands on, time limits LESSON 4.1  4.2
How to crack, hands on, disk-CDrom access LESSON 5
How to crack, funny tricks LESSON 6
How to crack, intuition and luck LESSON 7
How to crack windows, an approach LESSON 8.1  8.2
How to crack windows, tools of the trade LESSON 9.1  9.2  9.3  9.4
How to crack, advanced cracking LESSON A
How to crack, zen-cracking LESSON B
How to crack, cracking as an art LESSON C.1  C.2  C.3
How to crack INDEX

Lesson 9.2
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
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):
3)bmsg relevant_window wm_gettext
sequence of commands, as follows
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

: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
: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

: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
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:008E107F ;echo
0030:008E1867 ;echo
0030:008E601A ;echo

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

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
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:
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:
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

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
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
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
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: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"
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

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
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 crack, he'll
never be hungry again"

+ORC na526164@anon.penet.fi

+ORC contents