HOW TO CRACK, by +ORC, A TUTORIAL


Lesson 9 (2): How to crack Windows, Hands on


[PaintShopPro]


  

          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 crack, he'll

     never be hungry again"


E-mail +ORC

+ORC na526164@anon.penet.fi