home *** CD-ROM | disk | FTP | other *** search
-
-
- HOW TO CRACK, by +ORC, A TUTORIAL
-
-
-
-
-
- ------------------------------------------------------------------------
- Lesson 9 (4): How to crack Windows, Hands on
-
-
-
-
-
- ------------------------------------------------------------------------
- [WEBEXPRESS] [REDIRECTION]
-
-
-
-
- á 'Dead listing' approach - second part
-
-
-
-
-
- ------------------------------------------------------------------------
-
-
-
-
- ***********
- +HCU material FEBRUARY 1997
- LECTIO IN FIERI
- ***********
- (Hic sunt tabulae: Best viewed with good old Courier 10)
-
- First of all I'll give you a fundamental advice: don't stroll too
- much inside the dark codewoods without taking a due amount of
- notes: our paths are narrow, and wind in and out among
- codetrunks.
- Everything may seem 'obvious' to you when you are
- continuously cracking a given target, but after a break, or
- having cracked something else, you'll notice, as soon as you
- begin working anew on the original target, that many 'obvious'
- things are not so evident any more, and that you'll probably have
- to follow once more quite a lot of previous steps.
- Therefore heed my advice! NEVER WORK without taking notes,
- and never leave a crack without 'assembling' these notes in a
- short review where you'll synthesize 1) the paths you have
- followed in order to find the protection scheme, 2) a short
- description of the protection scheme itself and/or 3) the
- eventual new tricks you'll have found.
- Beginning with this lesson we will slowly drift towards 'higher'
- cracking, i.e., simply put, beginning from now I will give as
- acquired the minimum skills and knowledge you do need in order
- to crack (at least at this elementary level). Should you not feel
- able to follow a lesson, just re-read the 'basic' ones and
- practices on those lines until you do.
- To day we'll work on WEBEXPRESS, an 'html page designer'
- program whose 'triple' protection scheme (nagscreens and time
- protection and disabled functions) has some interest for us.
- I am using here version 1.0 of Webexpress for Win 3.1 by
- Microvision Development (at http://www.mvd.com). There is now a
- new beta version 2.0 out, but I reckon more useful to crack the
- older 16 bit Windows 3.1 application (august 1996) because this
- crack can be followed both by Windows 95 and by Windows 3.1 users
- (which -notwithstanding Microsoft's efforts- are still the
- majority). Besides, the Windows95 version's protection scheme and
- the beta one seem both to be more or less the same: you should
- be able to apply the following approaches, cracking the newer
- versions, without many problems (I did'nt check very thoroughly,
- though).
- I am using version 1.0 of Webexpress, with following files:
- WEBEX.EXE 1.309.200 12 august 1996 Main program
- WEBEX.DWR 120.885 12 august 1996 ASCII & resources
- (As usual you'll be able to fetch the whole application on the
- Web searching the archies).
- First of all let's fire Webexpress snapping the nagscreens (use
- snap32, cracked elsewhere in my tutorial, or PaintShopPro,
- cracked elsewhere in my tutorial, in order to get the printed
- snaps). This gives us a rough idea of our target's protection
- schema:
- This application is
- 1) 4 TIMES NAGSCREENED
-
-
- 1) Evaluation copy 'smallscreen' at the beginning
- 2) Evaluation copy Webexpress is NOT Freeware. This copy...
- 3) Evaluation copy 'smallscreen' at the end
- 4) To register Webexpress, enter your registration name...
- 2) TIME-LIMITED (30 days)
- 3) CRIPPLED (Prints 'Printed with an evaluation copy...' after
- 30 days).
- Gosh, quite a lot of annoyances... that's NICE for us little
- crackers! (That's actually the real reason I have chosen this
- crap). There is obviously a lot to learn for us inside its
- protection scheme... wipe your hands, prepare your cocktail (may
- I suggest a good Martini-Wodka? Remember: put in your glass
- always the ice cubes first, then the Martini dry and then the
- Moskowskaja)... at work!
- We proceed first with a little reverse engineering, using our
- 'dead listing' approach (see lesson - 9.3) and loading Webex.exe
- inside W32dasm in order to get the disassembled listing of the
- program. A word of caution: I am using only for teaching purposes
- version 5 of W32dasm, because this is the disassembler that the
- masses will use (watch carefully the file lengths after you
- searched w32dasm through the archies, before ftpmailing it, else
- you'll fish only the shareware and incomplete versions of it) but
- I originally used WCB, a much older, DOS based, Windozes
- disassembler, which has, as you will see, some advantages vis-a-
- vis of W32dasm. Remember that you DO NOT NEED to run windows in
- order to crack windows programs... cracking has not much to do
- with a particular OS... since you learn (here) how to 'interact'
- with an application at a 'fundamental', machine language, level,
- you'll be ALWAYS able to apply 'DOS cracks' or 'Windows cracks'
- or 'Unix cracks' to whatever OS the idiots will fancy in 5 years
- time... you are learning a technique that will NEVER BE OBSOLETE,
- believe me.
- Well firing w32dasm (which, I insist, is not a very good
- disassembler) you'll be able to save the webex.alf listing
- (which is 16 million bytes long, BTW, a real tribute to the
- 'overbloatility' of C++ in general and Windows programming in
- particular). Now load this *.alf inside a wordprocessor (you
- would be well advised to use a fast and good wordprocessor, i.e.
- not Microsoft's one, when you deal with such monstrosities, once
- more there is no reason to work inside Windoze).
- Ok, let's start with the cracking! Alas! Searching our nagging
- ASCII strings inside the listing, we do NOT find any trace of the
- two main nagscreens of Webexpress (Evaluation copy... & To
- register Webexpress...). These ASCII data are indeed NOT in the
- main *.exe module, but inside WEBEX.DWR, a file containing the
- resources for Webex (which seems compiled with Borland C++ 4,5
- btw). What now? Should we switch to Winice in order to find our
- protection scheme then? Has our dead listing approach failed?
- Well... let's examine a little more our listings... let's forget
- the ASCII strings -for the moment- and let's start with the
- easiest possible search in such cases: Since the limit of allowed
- days is 30 (which corresponds to 1Ex, duh) we could/should have
- somewhere an instruction like (we are here in a 16 bit
- application, not 32 one) mov ax,001E (B81E00)... would not we?
- Well, er... yes, quite. If you think this string of bytes is TOO
- SHORT and that you'll find much too many mov ax,001E inside a
- 1309200 bytes long file you are dead right... we would indeed
- find quite a lot of occurrences where 1E does not represent the
- 30 days limit at all, but only a parameter for a subsequent
- call:... let's conclude by saying that with overbloated programs
- -i.e. all Windows programs- there is no point in searching 'too
- short' shortcuts.
- Our search for 'mov ax, 001E'... would fail for sure... But
- wait! Couldn't we narrow the search a little more?
- Yes, hey, we can! But we'll need both a little experience and a
- little feeling: You see: the normal code for such a protection
- inside Borland C++ would consist in a COUPLE of instructions:
- E81E00 mov ax,001E
- 2B06xxxx sub ax,[gone_days]
- and since the code for 'sub ax,[whatever]' is 2B06xxxx, we now
- have a more 'robust' sequence of bytes for our search:
- E8 1E 00 2B 06
- Obviously we CANNOT search two consecutive instructions inside
- our disassembled listing using our wordprocessor search
- facilities, we will therefore have to search the above sequence
- inside Hexworkshop (a fairly good hexeditor that we cracked with
- - lesson 9.3 if you are using windoze, but you could anytime use
- old good (and powerful) PSEDIT). Let's do it... ahh! Things look
- muuuch better: splendid! There is only a single occurrence, at
- bytes 84565-84569 of our hexfile. Ok, done. Struck and destroyed.
- It's easy now to fetch this part of the code from our
- disassembled listing (we'll obviously have to translate the
- address 84565-84569 using the tables at the beginning of our
- Wdasm disassembly: here the relevant part:
- ...
- CSEG053 Off:83400 Size:1FFC Flags:0x1D10-CODE,MOVEABLE ; *53*
- ... and since 84565-83400 gives us 1165 bytes, the same address
- inside our listing will be :0053.1165... here it is!
- :THE_BINGO_QUICK_CRACK
- :0053.1162 8956EA mov [bp-16], dx
- :0053.1165 B81E00 mov ax, 001E ;load 30 *** BINGO!
- :0053.1168 2B066A46 sub ax, [466A] ;subtract gone_days
- :0053.116C 50 push ax
-
- Well, this shows us immediately the importance of location
- [466A], which is the memory location where the day_counter
- "grows".
- OK, bingo! This search has worked here without flaw or
- error... nevertheless beware! The abovementioned 'zen' method is
- NOT correct, coz it would in many cases NOT work (even if it
- actually worked here). Much too many protection schemes would
- have either
- a) a different (masked or concealed) initial value for ax instead
- of the exact one (here 1E): The protectionists could have a 'mov
- ax, 1F' (which is 31) and a 'dec ax' following it (which gives
- back our 30 days limit), or a zillion other possibilities in
- order to 'conceal' (more or less slightly :=) the purposes of the
- main comparison inside the code;
- b) another, completely different, assembler construction... say
- different instructions instead of sub ax,[gone_days], or
- c) junk between 'real' instructions (see elsewhere in my tutorial
- the 'junking' techniques for protection schemes).
- Therefore the abovementioned approach (unless you 'feel' the
- code) could make you waste too much time and would often miss the
- mustard... even if, interestingly enough, we ARE as a matter of
- fact landed smack in the middle of our protection using the
- simple trick above... but since you are here to learn the solid
- basic ways of cracking first (and you are not yet ready to feel
- the code, even if I believe you will, once you understand my
- 'zen' lessons at the end of this tutorial) here is a more 'sound'
- approach to this sort of cracking:
- Looking at all the many data strings inside Webex.exe, as
- said above, we have NOT found the text of the nagscreens (which
- is located inside the resource file Webex.dwr), but we can
- nevertheless find ONE very interesting stringdata reference (did
- they forgot it?)... just have a look at the "string data
- references" inside W32dasm once you load webex.exe...
- HERE!: "Printed with an evaluation copy"
- Ahha! Protectionist's squalor... how awful! This is a nagstring
- that should be WRITTEN inside any text printed with our copy of
- the application, should a user deem necessary to use it for more
- than the allowed 30 days... you remember our PaintShopPro
- cracking (- lessons 9.2 and 9.3) don't you? PaintShop had a
- counter as well, but there was no 'punishment' should you
- heedlessly 'overuse' the program. These 'MicroVision development'
- guys have purposely added a protection which cripples the program
- if you do not register it after 30 days! Buu! Buu!
- Now please examine code segment 109.1A06... (using W32dasm)
- there you'll find a whole series of code protection strings.
- Let's now have a look at the part of the code that pushes
- "Printed with an evaluation copy", it's segment 82... as you will
- see, even coming from this direction we land immediately inside
- the protection scheme. As I said elsewhere... protection schemes
- inside the code of an application are like tarantulas on a
- wedding suit, it's impossible not to see them from pretty far
- away.
-
- :COMPARE_VALUES_ADD_FB_AND_PRINT_NAGSTRING... NAGSTRING_ROUTINE
- :82.0B5F 8CD0 mov ax, ss ;start of routine
- :82.0B61 90 nop
- :82.0B62 45 inc bp
- :82.0B63 55 push bp
- :82.0B64 8BEC mov bp, sp
- :82.0B66 1E push ds
- :82.0B67 8ED8 mov ds, ax
- :82.0B69 B8D400 mov ax, D4 ;parameter D4 for the next
- :82.0B6C 9AFFFF0000 call 0001.517Fh ;(and only) ubiquitous call
- :82.0B71 8C5EFC mov [bp-04], ds
- :82.0B74 C746FAC319 mov word ptr [bp-06], 19C3 ;fix XX start
- :82.0B79 8D468E lea ax, [bp-72] ;ax = [bp-72]
- :82.0B7C 8C56F4 mov [bp-0C], ss ;save ss
- :82.0B7F 8946F2 mov [bp-0E], ax ;[bp-0E] = [bp-72]
- :82.0B82 EB14 jmp 0B98 ;begin loop
-
- :82.0B84 C45EFA les bx, [bp-06] ;loop from B9F,begin=[19C3]
- :82.0B87 268A07 mov al , es:[bx] ;load in al es:[19C3](XX)
- :82.0B8A 04FB add al, FB ;add FB
- :82.0B8C C45EF2 les bx, [bp-0E] ;load [bp-72] in bx
- :82.0B8F 268807 mov es:[bx], al ;save XXX at es:[bp-72]
- :82.0B92 FF46FA inc word ptr [bp06] ;next value loc gets+FB
- :82.0B95 FF46F2 inc word ptr [bp0E] ;next save location
- :82.0B98 C45EFA les bx, [bp-06] ;we begin/began at19C3
- :82.0B9B 26803F00 cmp byte ptr es:[bx], 0 ;are we done?
- :82.0B9F 75E3 jne 0B84 ;not yet, so loop up
- :82.0BA1 C45EF2 es bx, [bp-0E]
- :82.0BA4 26C60700 mov byte ptr es:[bx], 00
- :82.0BA8 16 push ss
- :82.0BA9 8D468E lea ax, [bp-72] ;prepare for the call
- :82.0BAC 50 push ax ;passing all...
- :82.0BAD 1E push ds ;...these params...
-
- * StringData Ref from Data Seg 109 -Printed with EvaluationCopy
- |
- :82.0BAE 68061A push 1A06 ;push and be betrayed
- :82.0BB1 9AFFFF0000 call USER.LSTRCMP ;AhHa!
-
- A very interesting block of code! You can easily see that here
- we have a reference to an obvious protection and at the end we
- have a call to USER.LSTRCMP, which is a case sensitive comparison
- of two null terminated strings, wildly used by windows
- protectionists (sic!).
- As 'usual' (you remember our crack of Hexworkshop in -
- lesson 9.2, don't you?) we must search the 'caller' of this block
- of code, i.e., where, inside webex.exe, dwells one of the
- following calling strings
- Either call 0B5F
- or jmp, je, jz... you name it, 0B5F
- or call 0082.0B5F
- Since the only common denominator of the above strings is a
- '0B5F' inside them, let's search first of all for 0B5F
- occurrences inside our 'protection' segment 82 (we should look
- further for the eventual call 0082.0B5F inside the other segments
- only if we do not fetch anything inside 82).
- And look! We land, almost immediately (remember that protection
- routines are most of the time 'compacted' inside one -or at most
- two- segments of wincode):
- :BE_NAGGED_INFIDEL
- :0082.0C8F 90 nop
- :0082.0C90 0E push cs ;prepare for call
- :0082.0C91 E86202 call 0EF6 ;call DECIDING_ROUTINE and...
- :0082.0C94 0BC0 or ax, ax ;...check flag ax. IS it 0?
- :0082.0C96 7506 jne 0C9E ;call compare if ax=1
- :0082.0C98 B80100 mov ax, 1 ;AX now 1 if it was zero...
- :0082.0C9B E9EE01 jmp 0E8C ;...and do NOT call NAGSTRING
- :compare_howbadareyou
- :0082.0C9E 833E6E4602 cmp word ptr [466E], 2 ;is it 2?
- :0082.0CA3 7D02 jge 0CA7 ;[466E] = 2 call NAGSTRING!
- :0082.0CA5 EBF1 jmp 0C98 ;[466E] 10?
- :82.07EE 7E08 jle 07F8 ;if yes, Jesus,
- :82.07F0 C7066E460300 mov word ptr [466E], 3 ;flag 3=VERY BAD
- :82.07F6 EB15 jmp popout
-
- :82.07F8 833E684605 cmp word ptr [4668], 5 ;is 4668 10?
- :82.0814 7E1E jle 0834 ;yes, then...
- :82.0816 6A00 push 0 ;...let's...
- :82.0818 1E push ds ;...prepare
- * StringData Ref from Data Seg 109 -"CODE"
- |
- :82.0819 686D19 push 196D ;...and
- :82.081C 1E push ds ;...then
- * StringData Ref from Data Seg 109 -"WB_10"
- |
- :82.081D 685119 push 1951
- :82.0820 9AFFFF0000 call 0069.09F4h ;...fire this routine
- :82.0825 83C40A add sp, 000A
- :82.0828 0BC0 or ax, ax ;and if not zero...
- :82.082A 7508 jne 0834 ;...then check can use
- :82.082C C7066E460300 mov word ptr [466E], 3 ;flag=3=VERY BAD
- :82.0832 EB15 jmp popout
-
- :OK_4668_IS_MORE_THAN_10_THEREFORE_CAN_USE_OR_ALMOST:
- :82.0834 833E6A460A cmp word ptr [466A], A ;is [466A] 10?
- :82.0839 7E08 jle 0843 ;can use if [466A] = 4.1-4.4: protection schemes based on time), this
- is done in a very rich number of ways, a double counter being one
- of the most common.
- OK, let's resume our findings:
- 1) We found our good old location [466A] compared to 1E (i.e.
- 30), which is very interesting to say the least.
- 2) We know now the meaning of location [466E], which may be
- either: 3=VERY BAD, DISABLING, or 2=TIME IS OVER or 1=TIME IS
- ALMOST OVER or 0=OK GO ON USING OUR CRAP
- So we'll 'name' this [466E] HOWBADAREYOU.
- Since we know that its value depends on the TWO parameters in
- [466A] and [4668], let's search for them. If we start with [466A]
- We land immediately to our 'first' block of code (the one found
- at the beginning of this lesson, the one inside segment 53,
- which seems to be an 'initialisation' segment):
- :FIRST_NEW_OCCURRENCE_OF_gone_days
- :0053.1162 8956EA mov [bp-16], dx
- :0053.1165 B81E00 mov ax, 001E ;load 30 ****
- :0053.1168 2B066A46 sub ax, [466A] ;subtract gone_days
- :0053.116C 50 push ax
- And we'll therefore 'name' [466A] GONEDAYS
- Let's do our first 'HANDS ON' checking.
- Pick up WEBEXP.EXE with hexworkshop (we cracked it in lesson -
- 9.3) and substitute (for instance)
- :0053.1165 B81E00 mov ax, 001E
- with
- :0053.1165 B81E1E mov ax, 1E1E
- This should allow for more than 21 years of undisturbed use of
- this program (1E1E=7710 days) and if we run the program now we'll
- see that the 'Evaluation days remaining' of the nagscreen are
- indeed 7710. This crack will not work (alone), though, because
- there are, as we saw, other 'crosschecking' locations in play.
- Let's therefore gather a little more facts about these locations
- inside our code.
- :ANOTHER_OCCURRENCE_OF_[466A]_gone_days
- :0082.074E E843FC call 0394 ;SHELL calls
- :0082.0751 83C406 add sp, 0006
- :0082.0754 A36846 mov [4668], ax ;UPDATE [4668]
- :0082.0757 6A03 push 0003
- :0082.0759 6A00 push 0000
- :0082.075B 6A00 push 0000
- :0082.075D 0E push cs
- :0082.075E E833FC call 0394 ;SHELL calls
- :0082.0761 83C406 add sp, 0006
- :0082.0764 A36C46 mov [466C], ax ;save ax here
- :0082.0767 8B46FA mov ax, [bp-06] ;get param
- :0082.076A 2B066046 sub ax, [4660] ;sub ax with [4660]
- :0082.076E A36A46 mov [466A_GONEDAYS], ax ;UPDATE
- GONEDAYS!
- :0082.0771 8B46FC mov ax, [bp-04]
- :0082.0774 8B56FA mov dx, [bp-06]
- :0082.0777 3B066646 cmp ax, [4666]
- :0082.077B 7506 jne 0783
- :0082.077D 3B166446 cmp dx, [4664]
- :0082.0781 742F je 07B2
- :0082.0783 FF066846 inc word ptr [4668] ;INCREASE [4668]!!
-
- ****************** THE WHAT_THE_CUCKOO_PROBLEM ***************
- We better -first of all- have a closer look at this 'double' call
- 394 for learning purposes, coz here hides a very common 'mistake'
- of Wdasm: a problem that you may not be aware of: DISASSEMBLER
- OFTEN MISS THE BEGINNING OF THE ROUTINES.
- Look! Our listing does not seem to report any :0082.0394 routine
- at all!
- :WHAT_THE_CUCKOO?_NO_ROUTINE_AT_82.0394?
- :0082.038A 91 xchg ax,cx
- :0082.038B 029B02AF add bl , [bp+di-50FE]
- :0082.038F 02A502D2 add ah, [di-2DFE]
- :0082.0393 028CD090 add cl , [si-6F30]
- :0082.0397 45 inc bp
- :0082.0398 55 push bp
- ... But since missing the start of routines is a 'routinely'
- mistake for all disassemblers we can repair 'by hand' this piece
- of code, which in reality should read, once you rearrange the
- same bytes:
- :EVERYTHING_OK_AT_394
- 82.0394 8CD0 mov ax, ss
- 82.0396 90 nop
- 82.0397 45 inc bp
- 82.0398 55 push bp
- 82.0399 8BEC mov bp, sp
- 82.039B 1E push ds
- The above listing comes from WCB, which is a much older
- disassembler than W32dasm, but which DOES NOT miss the beginning
- of the routines.
-
- ... For now, just remember -always- that 8CD090 is a common start
- for routines and that you should -never- completely trust your
- disassembler (or you debugger, or anybody for that matter) Work
- always cum grano salis!
- ******************************************************
- What IS interesting in the ANOTHER_OCCURRENCE routine above is
- that we have our GONEDAYS correlated to an increase of [4668],
- a parameter whose meaning we do not yet know. Let's also notice
- that location [4660] is a 'gone days' basher, i.e. a location
- that 'remembers' how much must be 'diminished' from GONEDAYS,
- let's call it [4660_BASHER]. And now we would search for these
- locations and so on and so on, sinking deeper and deeper in our
- shadowy codewoods, always (well, almost always :=) knowing what
- we are doing.
- We could continue like this in order to completely reverse
- engineering this application. But all these paths have been
- showed for your 'homework', and you should -obviously- use the
- help of Winice for such examinations. I wanted with all this
- cracking WITHOUT Winice (once more) just show you the untarnished
- POWER of the dead listing approach. Now let's go on to the real
- crack, which we'll do still only looking at our listings, without
- even a glimpse at Winice (no debugger in my hands, ladies and
- gentlemen! Only three or four sheets of printed paper).
- As we saw before, clearly the protection scheme acts inside
- the call to 0EF6 at the beginning of the BE_NAGGED_INFIDEL?
- routine... what happens to our beloved flag ax, then, inside the
- 82.OEF6 'deciding' routine?
- Routines inside routines... like the Russian Mathrioskas
- dolls... this kind of fishing is part of the sublime art of
- reverse engineering a program, a sport that requires some
- feeling, some luck and some experience.
- Let's have a close look at this routine.
- :DECIDING_IF_BE_NAGGED_INFIDEL... DECIDING_ROUTINE!
- :0082.0EF6 8CD0 mov ax, ss
- :0082.0EF8 90 nop
- :0082.0EF9 45 inc bp
- :0082.0EFA 55 push bp
- :0082.0EFB 8BEC mov bp, sp
- :0082.0EFD 1E push ds
- :0082.0EFE 8ED8 mov ds, ax
- :0082.0F00 33C0 xor ax, ax
- :0082.0F02 9AFFFF0000 call 0001.517Fh ;call ubiquitous
- :0082.0F07 A19846 mov ax, [4698] ;HERE!!***
- :0082.0F0A EB00 jmp 0F0C ;therefore
- :0082.0F0C 1F pop ds ;everything
- :0082.0F0D 5D pop bp ;depends
- :0082.0F0E 4D dec bp ;from location
- :0082.0F0F CB retf ;[4698]!
-
- Here we call once more this ubiquitous 1.517Fh routine, which
- -being at segment one- is probably one of the main display
- routines... we do not have necessarily to care... let's just
- check that 1.517F does not modify our TREASURE, i.e. location
- [4698], which is the location moved in AX. How will we check it?
- It's easy: just search for [4698] inside the listing...
- Whoa! No problem! The first occurrence of [4698] found is
- already inside our 'protection segment' 82... and it's a most
- interesting piece of code indeed from our cracking perspective...
- :82.01FB 9AFFFF0000 call USER.LSTRCMPI ;call LSTRCMPI
- :82.0200 0BC0 or ax, ax ;same strings?
- :82.0202 750B jne 020F ;no, so go flag1
- :82.0204 C70698460000 mov word ptr [4698], 0 ;flag0=samestrings
- :82.020A B80100 mov ax, 1 ;ax = 1
- :82.020D EB0A jmp 0219 ;continue
- :82.020F C70698460100 mov word ptr [4698], 1
- ;flag1=stringsdiffer
- :82.0215 33C0 xor ax, ax ;ax = zero
- :82.0217 EBF4 jmp 020D ;goto continue
-
- I assume you all know that the function
- int lstrcmpi (LPCSTR lpszStr1, LPCSTR lpszStr2)
- makes a non case sensitive comparison of two null terminated
- strings... a zero return value indicates that the two strings
- where identical. A negative value means that string1 < string2 and a positive one means that string1> string2.
- OK, it's MADE! The above piece of code represents obviously the
- final comparison between the user input and the registration key
- (what else?).
- THEREFORE the crack can be made with a very simple modification
- of the DECIDING ROUTINE... we must ensure that location [4698]
- is always flagged TRUE (i.e. zero) and therefore we modify
- :0082.0F07 A19846 mov ax, [4698]
- with
- :0082.0F07 B80000 mov ax, 0
- That's all we need to crack completely this program.
- No more nagscreens, (all three fetch the value of 4698 with a
- call to the same routine 82.EF6, all three will not snap any more
- now) should we really use this program, and we have made the
- first steps towards higher cracking. A word about it: higher
- cracking is something more than just defeating a protection, it's
- understanding what's going on in ANY part of a program we may
- wish to modify. Say you hate (just kidding) Microsoft enough to
- distribute cracked copies of their (awful slow) proggies where
- there is NO Microsoft logo whatsoever, or that you fancy a pink
- wordprocessor... go ahead and crack all the applications you use!
- And then distribute everything on the web for free!
- BTW, you should NOT believe that the two approaches I have shown
- you ('live' cracking through Winice, i.e. examining the
- protection scheme when it snaps, and the examining of the 'dead'
- listing as we are doing here) are the only methods to crack such
- protection... many more possibilities are open... just to give
- you an example, the (very old) utilities that show the 'imported'
- API functions of a program from its *.DLL and from KERNEL, USER
- and SHELL are a formidable cracking tool for windows programs...
- if you for instance search for KEYBOARD, you'll find the
- following occurrences...
- 59.1354 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 79.1F7A 9AFFFF0000 call KEYBOARD.OEMTOANSI
- 79.1FCB 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.13DA 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.1550 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.1588 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.1599 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.15D7 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 82.1629 9AFFFF0000 call KEYBOARD.OEMTOANSI
- 82.16D5 9AFFFF0000 call KEYBOARD.OEMTOANSI
- 83.063A 9AFFFF0000 call KEYBOARD.ANSITOOEM
- 83.06B2 9AFFFF0000 call KEYBOARD.OEMTOANSI
- 102.0721 9AFFFF0000 call KEYBOARD.ANSITOOEMBUFF
- 102.074C 9AFFFF0000 call KEYBOARD.OEMTOANSIBUFF
- ...and even lower beings would notice that segment 82 has SEVEN
- occurrences of KEYBOARD out of 14 and would smell a rat...
- KEYBOARD.DRV is a windows device driver, i.e. a DLL with another
- name, which is extensively used by the USER module. I hope you
- will not ask for the 'meaning' of the various KEYBOARD
- functions... you should know them by heart! Suffice to say that
- all ANSI APIs have MUCH to do with protection schemes, and than
- therefore the calls to KEYBOARD 5,6,134 and 135 are INDEED
- important from our point of view. Applications use the
- AnsiToOem(const char_huge* hpszWinString, const char_huge*
- hpszOEMString) function to convert a string stored in the windows
- character set into one stored in the specified OEM character set
- (in WinNT/32 there is a macro that calls the CharToOem()
- function)... As a matter of fact the USER.LSTRCMPI API from
- 82.01FB uses -in our case- these Keyboard functions. Are we
- finished with 'alternative' cracking approaches? Nooo! There are
- zillion cracking ways... say you use WRT (WIndows Resources
- Toolkit, a BEAUTIFUL Borland utility which is of UTMOST interest
- in our trade)... there you'll immediately find out that the Menu
- option 'Register' corresponds to 164. Decimal 164 is A4h... have
- a search for it... you'll land to 82.1575!
- As you have seen, we could have located the protection
- segment of our target using a completely different approach...
- but let's go back to our VERY POWERFUL dead listing... just a
- moment! A cool breeze outside my windows... say, do you know the
- names of the winds? Boreas (Aquila), Notus (Auster), Eurus and
- Zephyrus (Favonius) are the basic North, south, east and west
- ones... you may add Thrascias (NNW), Libs (WSW), Corus (Caurus
- or Argestes) (NW), Volturnus (SE), Africus (Afer ventus) (SW)...
- you did read Milton's Paradise, didn't you... how can you hope
- to crack if you did not? Back to our target, now. Let's have a
- look at the protection scheme itself... let's see how the
- comparison between user input and serial number is made.
- Here the relevant part of the routine:
- :CHECK_IF_USER_CHEATS
- :0082...01A2-01B2... ;prepare for REGNAME
- :0082.01B3 E84AFE call 0000 ;call SHELL.REGOPENKEYetc
- :0082.01B6 0BC0 or ax, ax
- :0082.01B8 7455 je 020F ;you are BAD, beggar off
- :0082.01BA 1E push ds
- :0082.01BB 687046 push 4670
- :0082.01BE 9AFFFF0000 call 1.4590h
- :0082.01C3 83C404 add sp, 4
- :0082.01C6 3D0400 cmp ax, 4
- :0082.01C9 7244 jb 020F ;you are BAD, beggar off
- :0082...01CB-01DC... ;prepare for REGKEY
- :0082.01DD E820FE call 0000 ;call SHELL.REGOPENKEYetc
- :0082.01E0 0BC0 or ax, ax
- :0082.01E2 742B je 020F ;you are BAD, beggar off
- :0082.01E4 1E push ds
- :0082.01E5 687046 push 4670
- :0082.01E8 16 push ss
- :0082.01E9 8D46AE lea ax, [bp-52] ;USER INPUT LOCATION
- :0082.01EC 50 push ax
- :0082.01ED 0E push cs
- :0082.01EE E8E7FE call 00D8 ;call loadchars and...
- :0082.01F1 16 push ss ;...ansilower and magic
- :0082.01F2 8D46D6 lea ax, [bp-2A] ;MAGIC LOCATION
- :0082.01F5 50 push ax
- :0082.01F6 16 push ss
- :0082.01F7 8D46AE lea ax, [bp-52] ;USER INPUT
- :0082.01FA 50 push ax
- :0082.01FB 9AFFFF0000 call USER.LSTRCMPI ;check strings
- :0082.0200 0BC0 or ax, ax ;strings differ?
-
- :0082.0202 750B jne 020F ;you are BAD, beggar off
- :0082.0204 C70698460000 mov word ptr [4698], 0 ;good guy!
- :0082.020A B80100 mov ax, 0001 ;flag ax=1,OK
- :0082.020D EB0A jmp 0219 ;continue
- :0082.020F C70698460100 mov word ptr [4698], 1 ;beggar off!
- :0082.0215 33C0 xor ax, ax ;flag ax=0
- :0082.0217 EBF4 jmp 020D ;NO GOOD, continue
- ...
- :retf
-
- The above block of code makes EVIDENT how such a protection
- scheme works:
- 1) first of all it performs the 'usual' checks on the entered
- strings (something must be written there, chars must make sense,
- minimum length, etc)
- 2) after the usual checks the loadchars and trasformchars
- routines are fired.
- If you look at the listing, routine 82.00D8 calls among
- other things the LPSTR AnsiLower(LPSTR lpszString) function which
- under Windows NT/32 does not exist any more and has been
- substituted with a macro (Yes, a macro! This should make you
- shiver thinking at what for a monstrosity is this Windows OS
- swelling towards) that calls the CharLower() function.
- 3) as soon as we have in memory our magic string, made
- transforming the user name input, we can compare it with the
- numbers inside the second inputted string. Should magic number
- and magic string differ you beggar off.
- Let's crack once more this program, this time we'll crack it
- here, i.e. we'll seek a correct registration 'result'
- substituting instruction
-
- :0082.020F C70698460100 mov word ptr [4698], 1 ;beggar off!
- with instruction
- :0082.020F C70698460000 mov word ptr [4698], 0 ;OK, nice sucker
-
- [REDIRECTION] (First elements of)
- The above crack solves location [4698], but that is not enough:
- WE MUST ALSO MODIFY THE AX FLAG... remember: each routine jumps
- back with a flag (mostly in ax) upon which the calling routine
- reacts... therefore we must also modify following piece of code:
- :0082.0215 33C0 xor ax, ax ;flag ax=0
- in order to substitute it with
- :0082.0215 B80100 mov ax,1 ;flag ax=1
- But, alas, this crack is a 3 bytes instructions! The original
- instruction was only two bytes long! How should we crack?
- Independently from the fact that actually there are 2 bytes
- instructions that do indeed perform the abovementioned flagging,
- I'll teach you here, a simple 'redirection', a method that you'll
- use a lot for higher cracking when we will 'patch'
- applications... Yeah! Time to leave the ONE BYTE FOR ONE
- BYTE petty and miserable cracking, time to insert whole new
- PIECES OF OUR code inside the applications we crack... what about
- having -somewhere inside a cracked Word for Windows- the string
- 'Warning: Microsoft can damage your health'? :=)
- You'll learn pretty complicate 'patching' redirection
- techniques in my +HCU, for now, let's just understand the
- fundament of this method here: the very short block of code we
- need to crack inside our target was originally this one:
- :0082.0204 C70698460000 mov word ptr [4698], 0 ;good guy!
- :0082.020A B80100 mov ax, 0001 ;flag ax=1, OK
- :0082.020D EB0A jmp 0219 ;continue
- :0082.020F C70698460100 mov word ptr [4698], 1 ;beggar off!
- :0082.0215 33C0 xor ax, ax ;flag ax=0
- :0082.0217 EBF4 jmp 020D ;NO GOOD, continue
- What about cracking the LAST instruction? Let's see... the
- code jumps back FF-F4 bytes (218-(FF-F4))=20d i.e. back to
- :0082.020d which is 'continue' (in this case after having being
- badflagged).
- Well, what if we redirect this to :0082.020A? Then having
- already cracked instruction 20F in order to have our necessary
- 0 inside [4698], we would now 'redirect' a correct 1 inside ax
- AFTER having already had the bad guy 0 there at line 215.
- Therefore, let's 'redirect' this jump:
- :0082.0217 EBF4 jmp 020D ;NO GOOD, continue
- with
- :0082.0217 EBF1 jmp 020A ;get_da_good_flag
- But Hey! Just a moment... What's the point of having loaded
- OURSELF a zero inside [4698] in the first time? WE DO NOT NEED
- IT! Let's use for the same aim the stupid protection itself...
- let's redirect FURTHER, DEEPER, BETTER.
- There is -indeed- a final cracking solution for this program
- (and a much more ELEGANT one: I still grudge the criticisms I
- suffered on the ground I used simple and 'unelegant' cracks in
- this tutorial). Let's redirect 82.217 to instruction 82.204 and
- let's merryly forget the whole previous cracking of instruction
- 82.020F... I mean... who cares if the protection, there, loads
- one in the [4698] and flags to 0 our sad ax? As soon as our last
- redirection snaps, the OTHER PART of the same protection scheme,
- the 'good guy' one, will snap and 'cover' the badflagged [4698]
- with TRUE zeros and will flag to 1 our beloved, but unfortunately
- zeroed, ax.
- Therefore forget ALL the previous cracks, this is the last
- but not least one (I mean, do not forget them... just fetch a new
- original nagged copy of webex.exe and start anew) and crack with
- that unnatural elegance that should always characterize all
- crackers from my school... solid crackers, old red's ones.
- I'll leave to you the obvious disassembly solution: if EBF4
- jumps to 020D and EBF1 jumps to 020A, what will land our cracked
- copies to 0204? Ebbene? :=)
- Now, you see, we have gone a long way cracking our silly
- Webexpress... as you saw, we could have cracked this target in
- quite a lot of different ways, but eventually the best (and less
- intrusive) crack required indeed a slight knowledge of the
- working of this program. Once more we worked on a 'dead'
- application... and once more we have demonstrated that Winice,
- though a splendid tool, is NOT the 'only' or 'absolute' cracking
- tool... Often a good disassembler, a wordprocessor and a
- hexeditor (and a good cocktail) are more than enough to crack
- every single application you can think of.
- I will tell you something you may already have supposed: in
- order to prepare this lesson I originally cracked this Windows'
- application without EVER FIRING WINDOWS... using WCB (100.294
- bytes which -unlike W32dasm, did not miss any routine), List
- (26.507 bytes... a quick 'lister' which is a *.com... not even
- an *.exe!) and PSEDIT (which is a very powerful, 65.862 bytes
- long hexeditor), all DOS quick application (to work REALLY you
- cannot use windoze)... but many of my readers will probably have
- to crack inside Microsoft's slow abomination... using W32dasm,
- Word and Hexworkshop and wasting time... after all... why not?
- The results will be the same, it's only a matter of -good or bad-
- taste.
- Now that you (begin to) understand re-direction cracking,
- you are ready to step over to 'real' higher cracks: what we call
- 'crackpatching'.
-
- 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 goddess 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
-
-
-