home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-05-25 | 82.4 KB | 1,628 lines |
-
-
- Uncle Joe's CrackBook (volume 1)
-
- or
-
- A beginners Guide to Cracking
-
-
-
-
-
- Chapter 1 overview
-
- Chapter 2 some tips on how to use the debugger
-
- Chapter 3 some basic cracking techniques
-
- Chapter 4 walk through of an easy crack
-
- Chapter 5 how to use the disk editor
-
- Chapter 6 other cracking tools
-
- Chapter 7 source code to a simple byte patcher
-
- Chapter 8 conclusion
-
-
- Programs included at the end of this guide
-
-
- Section 1 uuencoded cracking tool
-
- Section 2 another uuencoded cracking tool
-
- Section 3 uuencoded program to crack for the walk through
-
-
-
-
- CHAPTER 1 OVERVIEW
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- You might be wondering what type of programming skills you need to become a
- cracker. Knowing a higher level language such as Basic, Pascal, or C++ will
- help you somewhat in that you will have an understanding of what's involved in
- the process of writing a program and how certain aspects of a program
- function. If you don't have any programming skills, you have a long road ahead
- of you. But even if you can program in a high level language, in order to
- crack you have to know assembly...
-
- It really doesn't matter what language a program was written in in order to
- crack it, because all programs do the same thing. And that is issue commands
- to the microprocessor. And all programs when broken down to their simplest
- form are nothing more than a collection of 80XXX instructions and program
- specific data. This is the level of assembly language. In assembly you have
- total control of the system. This is also the level that the debugger operates
- at.
-
- You don't have to become a master at assembly to crack a program, but it
- helps. You do need to learn some rudimentary principles, and you absolutely
- have to become familiar with the registers of the cpu and how the 8088
- instruction set uses them. There is no way around this.
-
- How proficient you are at assembly will determine how good of a cracker you
- become. You can get by on learning a few basic instructions, how to use a
- debugger, and one or two simple techniques. This will allow you to remove a
- few shareware nag screens, and maybe you'll luck out and remove the copy
- protection from a game or two, but that's it.
-
- As soon as a programmer throws some anti-debugging code into a program or
- starts revectoring interrupts, you'll be whining for someone to post a crack
- for this or that... And you can forget about ever learning to crack windows
- programs.
-
- It's much much easier to learn to crack in DOS than windows. DOS is the
- easiest environment to debug in. This guide will focus on DOS programs as
- cracking windows apps is a little bit overwhelming unless you are already an
- experienced cracker. And if you are, your wasting your time by reading this.
- This manual is geared towards the raw beginner who has no clue as to where to
- start and needs a little hand holding in order to get going.
-
- There are several good beginners manuals out there, but most of them assume a
- person has at least some experience in cracking or knows how to use the
- different tools of the cracker, and the raw beginner usually becomes
- frustrated with them very quickly because they don't understand the concepts
- contained in them.
-
- I wrote this guide as sort of a primer for the beginner to read before reading
- the more comprehensive guides. I tried to keep it as simple as possible and
- left a great deal of information out so as not to overwhelm anyone with too
- much information at once. Hopefully after reading this guide it will be easier
- for the beginner to understand the concepts of the more arcane guides out
- there. So if you are reading this and it seems a little bit remedial,
- remember, at one time you didn't know what a debugger was used for either.
-
- Now in case your not familiar with the debugger and disk editor and what their
- different roles in cracking are, I'll give a brief explanation of each. As
- these are the crackers most valuable tools.
-
- The debugger is what you will use to actually crack the program. When you load
- a program you wish to crack into the debugger, it will load the program and
- stop at the first instruction to be executed within the code segment. Or, you
- can also optionally break into an already running program and it will halt the
- program at the instruction you broke into it at and await further input from
- you. At this point, you are in control of the program.
-
- You can then dynamically interact with the program and run it one line of code
- at a time, and see exactly what the program is doing in real time as each line
- of code is executed. You will also be able to re-assemble instructions (in
- memory only), edit the contents of memory locations, manipulate the cpu's
- registers, and see the effects your modifications have on the program as it's
- running. This is also where all your system crashes will occur... There is a
- lot of trial and error involved in cracking.
-
- As stated above, the debugger will only modify the program while it's up and
- running in memory. In order to make permanent changes, you need to load the
- program file to be patched into the disk editor and permanently write the
- changes you've made to disk. A detailed explanation of how to do this will be
- made in chapter 5.
-
- So, with this in mind, you need a few essential tools... The first one is a
- good debugger. The original draft of this guide gave explicit instructions on
- how to use my favorite debugger. After considerable deliberation, I decided to
- re-write it and make the instructions more generic so you could apply them to
- most any debugger. You will also need a disk editor, it doesn't matter which
- one you use as long as it will load the program file, search for and edit the
- bytes you want to change.
-
- I uuencoded a few cracking tools that you will find indespensible and placed
- them at the end of this guide. I won't go into the use of the cracking tools
- right now. But believe me, you absolutely need one of them, and the other one
- will save you a lot of effort. I also uuencoded the program that we will crack
- in the walk through and included it in this guide as well.
-
- As you get better, you'll have to write programs that will implement your
- patches if you decide to distribute them. The patches themselves don't have to
- be written in assembly.
-
- The source code I included in this manual for the byte patcher is the first
- patcher program I ever wrote, and is extremely simple. It's written in
- assembly because that's the only language I know how to program in. but if you
- are already proficient in a higher level language, it should be trivial for
- you to duplicate it's methods in your preferred language.
-
-
-
-
- CHAPTER 2 SOME TIPS ON HOW TO USE THE DEBUGGER
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- Ok, before I begin, I'd just like to stress how important it is that you know
- at least some assembly before trying to continue. If you don't, you will get
- lost pretty quick from here on out. Comprehension of the base 16 (hexadecimal)
- number system is also required.
-
- I'm not about to give a remedial course on assembly or hex math, that would
- take too long and I'd probably leave too many questions un-answered. Besides,
- there is enough information on them available from a myriad of other sources.
-
- So, from now on in this guide, I'm assuming you have a fair working knowledge
- of assembly and hexadecimal. If I say something you don't understand or you
- cannot grasp some concept, look it up somewhere...
-
- I've tried to make this section as generic as possible. I used general
- descriptions when explaining HOTKEYS and COMMANDS as different debuggers will
- use different keys and command syntax to implement these functions.
-
- You should be able to translate these instructions to the actual key strokes
- and commands that your debugger uses... If you don't know how to use a
- debugger, PAY ATTENTION!!! If you already know how to use a debugger you can
- skip this section as it is only a general overview of different windows and
- functions designed for the absolute beginner who has no clue as to what he is
- looking at.
-
- First, I'll give an overview on the different windows that most debuggers use.
-
-
- REGISTER WINDOW:
-
- The register window contains the general purpose and flags registers of the
- cpu. You will notice that the general purpose registers contain hexadecimal
- values. These values are just what happened to be in there when you brought up
- the debugger. you will also notice that some of the flags are highlighted
- while some are not. Usually, the highlighted flags are the ones that are SET.
- While the ones that are not highlighted are CLEARED. The layout of this window
- will vary from debugger to debugger, but they all basically are the same.
-
- From this window you will be able to manipulate the contents of the cpu's
- registers. some debuggers accomplish this by clicking on the register fsto
- modify with the mouse and then entering a new value. Other more powerful
- debuggers use a command line interface, you'll have to discover how your
- debugger goes about this yourself.
-
- You will change the values of the registers while debugging a program in order
- to change the behavior of the running program. Say you come across a JNZ
- instruction (jump if not zero), that instruction makes the decision on whether
- or not to make the jump based on the state of the (Z)ero flag. You can modify
- the condition of the (Z)ero flag in order to alter the flow of the programs
- code.
-
- By the same token, you can modify the general purpose registers in the same
- manner. Say the AX register contains 0000, and the program bases it's actions
- on that value, modifying the AX register to contain a new value will also have
- the effect of modifing the flow of the code. After you become comfortable with
- using a debugger you'll begin to appreciate just how powerful this window is,
- and you'll aslo discover soon enough just how totally it can screw your
- system if you fuck up.
-
-
- DATA WINDOW:
-
- The data window will display data as it exists in memory. From this window you
- can usually display, search, edit, fill, and clear entire ranges of memory.
- The two most common commands for this window are display and edit. The search
- command is also useful in cracking. But for the level of debugging I'll be
- teaching you in this guide, we won't make use of this window. You have a lot
- to learn before this window becomes an asset to you.
-
-
- CODE WINDOW:
-
- The code window is the window in which you will interact with the running
- program. This is the most complex window, and it is where the bulk of
- debugging occurs. I'll just go over some keystrokes and a few commands here,
- as the majority of learning how to use this window will come when I show you
- how to crack a program.
-
- The layout of the window is pretty simple, the group of 8 numbers with the
- colon in the middle of them to the far left of the window is the
- address:offset of that line of code. Each line of code in this window is an
- instruction that the program will issue to the microprocessor, and the
- parameters for that instruction. The registers that contain the address for
- the current instruction waiting to be executed are the CS:IP registers (code
- segment and instruction pointer).
-
- You will also notice a group of hex numbers to the right of the addresses,
- this group of numbers is the hexadecimal equivalent of the mnemonic
- instructions (pronounced new-mon-ik). The next group of words and numbers to
- the right of the hex numbers are the mnemonic instructions themselves.
-
- HOTKEYS AND COMMANDS:
-
- Now we'll move onto the HOTKEYS. I won't go into all of them, only the most
- useful ones, same for the commands.
-
- The RESTORE USER SCREEN KEY: This key will toggle the display between the
- debugger and the program you are debugging without actually returning control
- to the program itself. it's useful to check what the program is doing from
- time to time, especially after stepping over a CALL.
-
- The HERE KEY: This key is the non-sticky breakpoint key. To use it, Place the
- cursor on a line of code and hit it. The program will then run until it
- reaches that line. When (and if) the program reaches that line, program
- execution will halt, control will be returned to the debugger and the
- breakpoint will be removed.
-
- The TRACE KEY: This key will execute one line of code at a time and will trace
- into all calls loops and interrupts.
-
- The BREAKPOINT KEY: This is the sticky breakpoint key. This will enable a
- permanent (sticky) breakpoint on the line of code that the cursor is on. When
- a sticky breakpoint is enabled, program execution will halt and control will
- be returned to the debugger every time that line of code is encountered within
- the running program until you manually remove it.
-
- The SINGLE STEP KEY: The most used key on the keyboard. This key will execute
- one line of code at a time but will not trace into calls loops or interrupts.
- When you step over a call interrupt or loop with this key, all the code
- contained within the sub-routine is executed before control is returned to the
- debugger. If the program never returns from the sub-routine, you will lose
- control and the program will execute as normal.
-
- The RUN KEY: This key will return control to the program being debugged and
- allow it to execute as normal. Control will not be returned to the debugger
- unless a breakpoint that you've set is encountered.
-
- Now for a few commands. The GO TO command functions like the HERE key in that
- it will insert a non-sticky breakpoint at the specified address.
-
- When you enter this command the debugger will return control to the program
- until the line of code you specified in the GO TO command is reached. When
- (and if) the CS:IP registers equal the address you typed in, the program will
- halt, control will be returned to the debugger and the breakpoint will be
- removed.
-
- You might be wondering why you would want to type all this in when you can
- just hit the HERE KEY instead. The answer is this; the HERE KEY is great if
- you want to set a local breakpoint. By a local breakpoint I mean that the
- breakpoint you want to set is somewhat close to your current location in the
- program.
-
- But what if you want to set a breakpoint on a line of code that isn't in the
- current code segment? You wouldn't want to use the HERE KEY cause the address
- is no where near the point you are at in the program. This, among other uses
- is where the GO TO command comes in.
-
- The ASSEMBLE command is the command you will use to re-write the programs
- instructions. This command will allow you to assemble new instructions
- beginning at the address you type in, or at the current CS:IP. The
- instructions you enter will replace (in memory only) the existing program code
- at the address you specified. This is another method you will use to alter the
- running program to behave as you wish and not as the programmer intended it
- to.
-
- EXAMPLE: Lets say that there is a line of code that reads JNZ 04FC, and we
- want to change it to read JMP 04FC. You would issue the ASSEMBLE command and
- specify the address of the code you wish to change, then type in JMP 04FC.
- Now the line of code in the code window who's address you specified in the
- ASSEMBLE command will be overwritten with the code you typed in. Some
- debuggers automatically default to the address contained in the CS:IP for this
- command.
-
- There are a whole host of other commands available in this window depending on
- what debugger you are using, including commands to set breakpoints on
- interrupts, memory locations, commands that list and clear breakpoints,
- commands to un-assemble instructions etc etc... And as for the commands I
- don't go over, the best lessons learned are the ones that are self taught.
-
- Well, that's pretty much it on debuggers without going into explicit
- instructions for specific debuggers. The only other thing I can tell you is
- that the more you use it, the easier it'll get. Don't expect to become
- familiar with it right away. As with anything, practice makes perfect. It's
- taken me 5 years and thousands of hours of debugging to reach the level I'm at
- now. And I still learn something new, or re-learn something I forgot on just
- about every program I crack. Don't ever think that you know everything,
- cracking is a constant learning process.
-
-
-
-
- CHAPTER 3: SOME BASIC CRACKING TECHNIQUES
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- The first thing I want to do before going into some simple techniques is to
- explain the purpose of one of the uuencoded cracking tools at the end of this
- guide. And also to go over some general procedures you should perform before
- actually loading a program you wish to crack into the debugger.
-
- Nowadays a lot of programmers will compress the executable files of their
- programs to save space and to make it difficult for people who don't know any
- better to hack those files. There are a lot of losers out there who will get
- ahold of a program and lacking any skill or talent of their own, will load the
- program into a disk editor and hex edit their name into it. Or they will make
- other similarly feeble modifications.
-
- This is the reason I encrypt all of the cracks that I distribute. The routines
- I write are not that hard to defeat, but I figure anyone with the skill to
- crack them is far above having to hack their name into them...
-
- Ok, back to the file, the name of the program is UNP and it is an executable
- file expander. It's purpose is to remove the compression envelope from
- executable programs. And it supports most of the compression routines
- currently in use...
-
- A lot of the compression routines will cause a debugger to lock up with a
- protected mode violation if you try to step through the compressed file,
- especially PKLITE v1.15. And seeing as how the file is compressed, if you load
- it into a disk editor it will just look like a bunch of garbage and you'll not
- be able to find the bytes you want to edit anyway.
-
- UNP is very easy to use, just type UNP [filename] and if there is any type of
- compression envelope that UNP understands on the file, UNP will remove it. You
- can then load the file into a debugger and hack away...
-
- But before you load a program into the debugger you should run the program a
- few times and get a feel for it. You want to see how the protection is
- implemented. Whether it's nag or delay screens and at what point in the
- program they fist appear, or where in the program does the first mention of
- being unregistered or an evaluation copy appear?
-
- This is important. Because before the program displays the first mention of
- being unregistered, it has to do the protection check. and this is where you
- will usually want to concentrate. Also look for registered functions being
- disabled, and sometimes date expirations. The program could also be looking
- for a registration key.
-
- In the case of commercial software what type of copy protection is used? Is it
- a doc check, or does the program want you to input a serial number before it
- will install itself? Once you see how and where the offending routines are
- implemented you can begin to develop an overall strategy on the best approach
- to circumvent them. It's also a good idea to read the docs, you can pick up a
- lot of useful info from doc files.
-
- There are basically three categories that shareware programs fall into... They
- are begware, crippleware, and deadware.
-
- The begware category is comprised of programs that have all the registered
- features enabled but every time you run them they will display screens that
- bug you to register. This is the easiest form of protection to remove and it's
- the type I'll go over in the walk through.
-
- The crippleware category is comprised of programs that in the unregistered
- version have certain functions disabled, and maybe nag screens as well. This
- type of protection can be slightly more complex, but often times is just as
- easy to defeat as a simple nag screen.
-
- The deadware category is comprised of programs that are totally stripped of
- the code for the registered features so there is really nothing to crack. A
- good example of this is DOOM by ID software. You can get the shareware version
- just about anywhere, however no matter how much you hack at it you cannot make
- it into the commercial version cause it only contains the code for the first
- episode.
-
- Ok, you've run the program a few times and you know what you want to remove
- and have a general idea on where to concentrate your efforts. you also have
- run UNP on it and it's ready to debug. You load the program into the debugger
- and wonder what to do next...
-
- Most forms of copy protection have one weak spot, and this is the spot you
- will concentrate on. They have to perform the protection check and then make a
- decision based on the results of that check. And that decision is usually a
- conditional jump. If the check was good the program will go in one direction,
- if it was bad it will go somewhere else.
-
- Don't think that as soon as you spot a compare or conditional jump you've
- found the protection routine. These instructions are part of the 8088
- instruction set and all programs use them constantly for everything. What you
- want to do is to step through the code until something significant happens
- like a nag screen gets displayed, or a doc check comes up or the program tells
- you that the function you just tried to use is only available in the
- registered version. When you reach that point you can then start to evaluate
- what portion of code to begin studying.
-
- Let's say you have a program that displays a nag screen and you want to remove
- it. You step through the program until the nag screen pops up, you now know
- the location of the instructions that are causing it to be displayed. So you
- reload the program and trace back to a point a few instructions before the
- call to the nag screen, and this is what you see:
-
- 09D8:0140 CMP BYTE PTR [A76C],00
- 09D8:0145 JNZ 014B
- 09D8:0148 CALL 0C50
- 09D8:014B MOV AH,18
-
- Now, let's assume that the memory location referenced by the first line of
- code does indeed contain 00 and that it is the default value placed in there
- by the programmer to indicate that the program is unregistered.
-
- The first line of code is checking the value contained in the memory location
- to see if it is 00 or not. If the location does contain 00, the compare
- instruction will cause the Zero flag to be set. If the location contains any
- other value than 00, the Zero flag will be cleared.
-
- The second line of code makes the decision on how to proceed based on the
- results of the compare instruction. The JNZ instruction will make the jump to
- the fourth line of code if the zero flag is cleared. This will bypass the call
- to the nag screen on the third line. If the zero flag is set, no jump will
- occur and the call will be made.
-
- The third line of code contains the call to the nag screen. If it is executed
- the nag screen will be displayed. The fourth line of code is just the next
- instruction in the program.
-
- Once you have found and analyzed this piece of code within the program, you
- can now decide on how to bypass the call on the third line. There is no single
- way to do this. I can think of a half dozen different ways to patch the
- program so it will not make the call. But there is a best way...
-
- First, you could just replace the JNZ 014B with JMP 014B. This is an
- unconditional jump and it will bypass the call on the third line no matter
- what the memory location that the first line of code is referencing contains.
-
- You could also change it to read JZ 014B so that the jump will be made if the
- location contains 00, and not the other way around. You could even change the
- CMP BYTE PTR [A76C],00 instruction to JMP 014B.
-
- Or you could just NOP out the call on the third line altogether seeing as how
- it's a local call. By a local call I mean that the code contained within the
- call resides in the same code segment as the call instruction itself.
-
- This is an intersegment call. You will see other calls that reference lines of
- code outside of the current code segment. These are intrasegment calls, and
- have to be handled differently. They will look something like CALL 0934:0AC5,
- or CALL FAR 0002. I'll go over how to handle intrasegment calls later on.
-
- NOP is short for no op-code, and it is a valid instruction that the
- microprocessor understands. It is only one byte in length, and the call
- instruction is three bytes in length. So if you wanted to nop out the call
- instruction you would have to enter the NOP instruction three times in order
- to replace it. And if you replaced the CMP BYTE PTR [A76C],00 with JMP 014B,
- you would have to pad it out with a few nop's as well.
-
- The compare instruction is 5 bytes and the jump instruction is only 2 bytes,
- so you would have to add 3 nops in order to equal the length of the original
- compare instruction. Otherwise you would throw off the address of every
- instruction after it in the program and end up with a bunch of unintelligible
- garbage. Not to mention a major system crash...
-
- The NOP instruction is mainly used as a filler and when this instruction is
- encountered no operations will take place and the CS:IP will then be
- incremented to the next instruction to be executed. A lot of compilers leave
- nop's in the code all the time and it's a great instruction you can use to
- wipe out entire lines of code with.
-
- The above methods of bypassing the call are called 'dirty' cracks in that they
- have only modified the end result of the protection check and have done
- nothing to alter the actual protection check itself.
-
- All the techniques I showed you above are only implemented after the check is
- made. They will bypass the nag screen, but what if the program also has
- registered features that are disabled or displays another nag screen upon
- exit? The above methods only remove the original nag screen and don't address
- the reason the screen is being displayed in the first place.
-
- A much cleaner way to crack the above piece of code would modify the cause and
- not the effect. And could be written like this:
-
- original code new code
-
- 09D8:0140 CMP BYTE PTR [A76C],00 09D8:0140 MOV BYTE PTR [A76C],01
- 09D8:0145 JNZ 014B 09D8:0145 JMP 014B
- 09D8:0148 CALL 0C50 09D8:0148 CALL 0C50
- 09D8:014B MOV AH,18 09D8:014B MOV AH,18
-
- Remember that the protection check is basing it's actions on the value
- contained in the memory location that the first line of code is checking. The
- original code displayed the nag screen if the value of that location was 00,
- meaning it was unregistered. So that means a value of 01 indicates a
- registered copy. It could be the other way around as well, it just depends on
- how the programmer worded the source code. But we know in this case that
- 00=false so 01=true. These are Boolean expressions and most compilers use the
- AX register to return these values.
-
- By changing the first line from CMP BYT PTR [A76C],00 to MOV BYTE PTR
- [A76C],01 the program no longer performs the protection check. Instead, it
- places the correct value in the memory location to indicate a registered copy.
- Now if the program checks that memory location again later on it will think
- that it is registered and activate all of it's disabled features, or not
- display a second nag screen upon it's exit if it has one.
-
- I changed the second line of code to an unconditional jump because the compare
- instruction on the first line no longer exists, and the conditional jump on
- the second line may still access the call to the nag screen on the third line
- if the Z flag was already set before the old compare instruction was
- encountered.
-
- Don't think that all programs are this easy, they're not. I just
- over-simplified this example for instructional purposes. And I really wouldn't
- crack the code like that, although the last method should work fine for all
- registered features to be enabled. Remember I told you there was a best way to
- crack this?
-
- What I would actually do is to trace further back into the program and find
- the line of code that sets up the memory location referenced by line one of
- the code for the protection check in the first place and modify it there. This
- is an example of a 'clean' crack.
-
- I just did it in the above manner to try and show you the difference between
- clean and dirty cracks without totally confusing you. And to give you a
- general idea on how to creatively modify existing code.
-
- If you are using soft ice as your debugger, an easy way to find the
- instruction that sets up the memory location for the protection check is to
- set a breakpoint on the location when it gets 00 written to it. The syntax
- would be BPM XXXX:XXXX W EQ 00, where XXXX:XXXX is the address of the memory
- location referenced by the compare instruction on line 1.
-
- Now when the program wrote 00 to that memory location, soft ice will pop back
- up and the CS:IP will be sitting at the next instruction after the one that
- wrote 00 to the memory location. You will now be able to evaluate the code
- around the instruction that writes to the memory location and decide on how to
- proceed.
-
- This also could just be a general purpose location that the program uses for
- generic references (especially if it's in the stack segment), and it could
- write 00 to it several times throughout the course of the program for a
- variety of functions. You should let the program run normally after soft ice
- broke in to see if it will trigger the breakpoint again. If it doesn't you
- know that the location is only used for the protection check. But if the
- breakpoint gets triggered several more times, you will have to figure out
- which set of instructions are being used to set up for the protection check
- before proceeding.
-
- The above examples were based on shareware programs. Now I'll go over a few
- techniques to remove copy protection from commercial games that have doc
- checks in them as the methods are slightly different...
-
- shareware programs are usually coded so that they check a variable in memory
- before deciding if they are registered or not and how to proceed, unless of
- course they are looking for a registration key. Commercial games with doc
- checks take a different approach as they check nothing before calling the copy
- protection. It always gets called every time you play the game no matter what.
- As a result, the doc check routine is usually easier to find, and there are
- basically two types of doc checks... The passive check, and the active check.
-
- The passive doc check is easier to defeat than the active. In the passive doc
- check, the program will issue a call to the copy protection routine. And if it
- is unsuccessful will either abort the program, or loop back to the beginning
- of the routine and give you a few more tries before aborting. The entire
- protection routine will be included in a single call, so merely nopping out
- or bypassing the call will be sufficient to remove the copy protection.
-
- A few good examples of this are Spear of Destiny by ID, and the Incredible
- Machine by Sierra. Yes I know that they are old, but if you happen to have a
- copy of either one laying around they are excellent examples of passive doc
- checks to practice on.
-
- Look at the following piece of code:
-
- 0277:01B5 MOV [AF56],AX
- 0277:01B8 PUSH BX
- 0277:01B9 PUSH CX
- 0277:01BA CALL 0234
- 0277:01BD POP CX
- 0277:01BE POP BX
- 0277:01BF JMP 0354
-
- The first three lines of code are just setting up for the call, the call on
- the fourth line is the protection check itself. It will display the input
- window asking for a word from the manual, will perform the protection check,
- and will display an error message if you input the wrong word. It can also
- optionally give you a few more tries if you type in the wrong word.
-
- If you fail the protection check, the program will abort without ever having
- returned from the call. The fifth, sixth, and seventh lines are the next
- instructions to be executed if the protection check was successful and the
- program returns from the call.
-
- This type of protection is trivial to defeat, all you have to do is the
- following:
-
- original code new code
-
- 0277:01B5 MOV [AF56],AX 0277:01B5 MOV [AF56],AX
- 0277:01B8 PUSH BX 0277:01B8 PUSH BX
- 0277:01B9 PUSH CX 0277:01B9 PUSH CX
- 0277:01BA CALL 0234 0277:01BA NOP
- 0277:01BD POP CX 0277:01BB NOP
- 0277:01BE POP BX 0277:01BC NOP
- 0277:01BF JMP 0354 0277:01BD POP CX
- 0277:01BE POP BX
- 0277:01BF JMP 0354
-
- Simply nopping out the call to the protection routine will be sufficient to
- crack this type of doc check. No window asking for input will appear, and the
- program will continue on as if you had entered the correct word from the
- manual. Remember that I told you that the NOP instruction is only one byte in
- length, so you have to enter as many nop's as it takes to equal the length of
- the code you are modifying.
-
- The active doc check is more complex. The program will issue the check and
- unlike the passive protection, will set a variable in memory somewhere and
- reference it later on in the program.
-
- You can crack this type of protection somewhat using the methods for the
- passive check and it will run fine for a while. But if you didn't crack it
- right, later on when the next episode gets loaded or you reach a crucial point
- in the game, the program will reference a memory location and bring up the
- copy protection again, or abort. This type of protection is more akin to how
- most shareware programs operate and MUST be done with a CLEAN crack.
-
- Look at the following piece of code:
-
- 0234:0B54 MOV CX,0003 ;Sets up to give you three tries
- 0234:0B57 DEC CX ;deducts one for every time through the loop
- 0234:0B58 JCXZ 031A ;when CX=0000, program will abort
- 0234:0B60 PUSH CX ;just setting up for the call
- 0234:0B61 PUSH DS ; " "
- 0234:0B62 PUSH ES ; " "
- 0234:0B63 CALL 035F:112D ;call to input window and validation routine
- 0234:0B68 OR AL,AL ;seeing if check was successful
- 0234:0B6A JNZ 0B6E ;yes, continue on with the program
- 0234:0B6C JMP 0B57 ;no, set up for another try
- 0234:0B6E CALL 8133 ;next line in the program if check was good
-
- The above code is the outer loop of the protection routine. Look at the call
- on the seventh line and the compare instruction on the eighth line. When the
- call to the input routine or in the case of shareware, the check routine is
- paired with a compare instruction in this manner, You can bet that the program
- set a memory variable somewhere inside the call. Especially suspicious is the
- unconditional jump on line 10 that jumps backwards in the code.
-
- This won't always be the case as no two programs are alike, and simply
- changing line one of the code from MOV CX,003 to JMP 0B6E to bypass the entire
- routine may allow the program to run just fine. Let's say that this is how you
- patched the program and it runs. Great, your work is done... But what if
- before the first level loads, or at some other point within the program the
- input window pops up again asking for a word from the manual?
-
- You realize that you should have patched it right in the first place as you
- now have to go back in there and fix it. This is why so many groups have to
- release crack fixes, they patch the program in a half assed manner and don't
- even run it all the way through to see if it's going to work.
-
- Ok, back to the problem at hand... The above method of patching the program
- didn't work, so you now have to load the program back into the debugger and
- trace into the call on line seven to see whats going on in there. And you
- can't NOP this kind of call out either, this is an intrasegment call.
-
- Certain things in programs get assigned dynamic memory locations, and
- intrasegment calls are one of those things. When the program gets executed,
- the code segment, data segment, extra segment, and stack segment get assigned
- their respective addresses based on the memory map of your computer.
-
- And when a program does a FAR call (a call to a segment of memory outside the
- current code segment), The program goes to the address that was assigned to
- that segment at run time. The CS, DS, ES, and SS will be different on every
- computer for the same program.
-
- And seeing as how these addresses don't get assigned until run time, the
- actual bytes for the addresses of far calls don't exist in the program file as
- it resides on your disk. That's why you can't just NOP a CALL FAR instruction
- out.
-
- However, the bytes for calls that are within the same segment of code as the
- calling instructions themselves will be contained within the file as it
- resides on disk. And that is because even though the program doesn't get the
- addresses for the actual segments until run time, the offsets within those
- segments will always be the same.
-
- Back to the example, let's say you've traced into the call on line seven and
- this is what you see:
-
-
- 035F:112D MOV [324F],BX ;
- 035F:1131 CMP BYTE PTR [BX+06],03 ; just some error checking
- 035F:1135 JNZ 0339 ;
-
- 035F:1137 CALL F157 ; call to the input window that
- ; asks you to type a word in from
- ;the manual
-
- 035F:113A MOV DI,[0332] ; this routine is comparing the
- 035F:113D MOV ES,DX ; word you typed in to a word
- 035F:1140 MOV DS,BX ; in memory that the program is
- 035F:1144 MOV SI,[0144] ; referencing. As long as the
- 035F:1148 MOV CX,[0097] ; bytes match the loop will
- 035F:114C REPE CMPSB ; continue.
-
- 035F:114F JCXZ 1154 ; This is the routine that sets
- 035F:1151 JMP 1161 ; the memory variable. 01 will be
- 035F:1154 MOV AX,0001 ; placed in it if you typed in
- 035F:1159 MOV [0978],AX ; the correct word. 00 will be
- 035F:115E JMP 116B ; placed in it if you typed in
- 035F:1161 MOV AX,0000 ; the wrong word.
- 035F:1166 MOV [0978],AX ;
-
- 035F:116B POP ES ; setup to return from call
- 035F:116C POP DS ; " "
- 035F:116D POP CX ; " "
- 035F:116E RETF ; return from call
-
-
- Again, this code is over simplified as I figured all of the code would be
- overwhelming and really is not needed to get my point across. And as I've
- stated before, every program will be different anyway, so the actual code
- wouldn't help you. Instead, I want to give you a general overview on what to
- look out for.
-
- So, what do you think is the best way to patch the above piece of code? Take a
- few minutes to study the code and formulate some ideas before reading on. Then
- compare your methods to mine. And remember, as with any code there is no
- single way. But as always, there is a best way... I'll go over few of them one
- at a time, starting with the dirtiest and finishing up with the cleanest.
-
- The dirtiest crack for this piece of code also happens to be the method you
- will use to nop out intrasegment calls. It really isn't nopping out, but
- seeing as how you can't nop it out, just let the program make the call and
- change the first line of the code within the call to RETF. This will return
- from the call without ever having executed any of the code contained within
- it.
-
- In the case of registers needing to be restored as in the above code, change
- the first line of code to jump to the part of the routine that restores the
- registers for the return. However, in the above example if you use this method
- and just return from the call without executing any of the code, you will also
- have to patch the outer loop as well.
-
- Remember that this call only displays the input window and sets the memory
- variable. The outer loop of the routine makes the decision on how to proceed
- based on the results of the call.
-
- To do this, you would change line one of the call from MOV [324F],BX to JMP
- 116B. This will restore the registers and return from the call without ever
- having executed any of the code within the call. But seeing as none of the
- code got executed, you'll have to patch line 9 of the outer loop from JNZ 0B6E
- to JMP 0B6E as you now need an unconditional jump to force the program to
- continue. This doesn't address the problem of the memory variable though, and
- the program won't be completely cracked. That's why if you did it like this
- you would end up releasing a fix.
-
- A cleaner crack would be to change line 11 of the call from JCXZ 1154 to JMP
- 1154. Now when the window pops up and asks for a word, it will set the correct
- memory variable and the program will run no matter what word you type in. This
- method is still not desirable because the end user will get the input window
- and have to type something every time they play the game.
-
- The cleanest way to crack this, and the way I would do it is to change line 4
- of the call from CALL F157 to JMP 1154. This method will totally bypass the
- input window, place the correct variable in memory and return from the call
- without the end user ever having seen even a hint of copy protection.
-
- With this method, the outer loop does not need to be patched cause the program
- now thinks that it displayed the input window and the correct word was typed
- in. Now when the program checks that memory variable later on, it will think
- that you successfully passed the original check and skip the second protection
- check.
-
- There is also an added benefit to the last method... Some games will bring up
- the protection check between each and every level of the game even though you
- type the correct word in every time. But if you've completely killed the
- routine as in the last example, you'll never be bothered by it again no matter
- how many times the program tries to bring it up.
-
- Before we move onto the walk though, there is one other technique I want to go
- over with you. And that is how to get out of a loop. You will get stuck in
- loops constantly during the course of debugging a program and knowing how to
- get out of them will save you a lot of time and frustration. You will find
- that programs contain loops within loops within loops etc... Some loops can
- execute hundreds of times before the program will advance, especially ones
- that draw screens.
-
- When you realize that you are stuck in a loop, execute the loop several times
- and keep an eye on the highest address the loop reaches before jumping
- backwards within the code. Once you have found the end of the loop, write down
- the address of the jump that re-executes the loop, and then look for
- conditional jumps inside the loop that will put you past the address of that
- backwards jump. You will want to set a breakpoint on the address this
- instruction jumps to and then let the program run normally. The HERE KEY is
- excellent for this type of situation.
-
- If you guessed right, control will be returned to the debugger when the
- program reaches that address. If you guessed wrong, you will lose control of
- the program and will have reload it and try again. This is where writing down
- the address comes in handy, just reload the program and then issue the GO TO
- command and supply it the address of the backwards jump that you wrote down.
-
- The program will run until it reaches that address and control will then be
- returned to the debugger. This will save you from having to trace all the way
- through the code again in order to reach the point where you lost control of
- the program in the first place. You could just use sticky breakpoints instead,
- but what you will end up with is a half dozen or so breakpoints in as many
- different locations in the code, and it's very easy to loose track as to which
- breakpoint is which.
-
- That's why I use non-sticky breakpoints and write down the address I'm
- currently at before executing suspicious looking calls and jumps. My desk is
- usually scattered with scraps of paper filled with notes and addresses. I only
- use sticky breakpoints for specific situations. It's much easier to just
- reload the program and use the GO TO command to get back to the point in the
- program where I lost control.
-
-
-
-
- CHAPTER 4 WALK THROUGH OF AN EASY CRACK
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- First of all, I want to go over some of the criteria I used in choosing the
- program I used for the walk through. An important factor was the programs
- size. I want to keep this manual as small as possible, and I chose the program
- that is included in this guide because among other things it is the smallest
- one I could find that best illustrated the example of a simple nag screen.
-
- Whether or not the program was one that you would actually find useful was not
- a consideration, as you should eventually be able to crack just about any
- program you wish if your serious about cracking. If you come across a program
- that has you stumped, leave it alone for a while and then try again after
- you've cracked something else. You may find that whatever you were having
- problems with is now easier to understand.
-
- Before we start I want to go over one other thing. When you load a program
- into a debugger, the debugger will load the program and halt at the very first
- instruction to be executed within the program. You can also at this point let
- the program run normally and then break back into it at a later point.
-
- When you use the second method it will halt the program at the current
- instruction and return control to the debugger, but you may not end up in the
- program itself. You could have broken into the program while it was in the
- middle of executing either a DOS or BIOS interrupt, and the code you are in
- belongs to either DOS or BIOS and not the program you are debugging.
-
- You can tell by looking at the addresses of the instructions in the code
- window where you are, low segment addresses indicate you are in DOS, and
- addresses that start with FXXX indicate a BIOS routine.
-
- If you break into the program while it is in one of these interrupt routines
- you will have to trace your way back into the programs code, this will usually
- be indicated by an IRET (interrupt return) instruction. When you do get back
- to the program code, you will then have to trace your way back to the top of
- the call that issued the interrupt you broke into. Then you may also have to
- trace back to the top of that call, and to the top of that call, etc etc,
- until you reach the top level of the program. After you've done this a few
- times you'll begin to recognize when you've gotten back to the main flow of
- the program...
-
- On the other hand, when you load a program into the debugger and begin
- stepping through the code from the very first instruction to be executed
- within the program, you have the best picture on the overall flow of the
- program as you are sitting on top of everything.
-
- But some programs don't access the copy protection until they are further
- along in the code. In this case, it's best to let the program run normally and
- then break into it at a later point. Otherwise, you will have a ton of code to
- trace through before the protection routine is accessed, and this can become
- quite tedious. Which method you choose will be determined after you've run the
- program through a few times and decide how and where you want to break into
- it.
-
- One last thing, DOS will always load a program into the same memory range
- provided that no other programs are run in the interim. It's important that
- you always boot with the same config files and don't run any other memory
- resident programs between cracking sessions.
-
- If you load a program into the debugger and start tracing, then quit. And
- before The next time you load that program into the debugger, you boot with a
- different config or load a memory resident program that you didn't have loaded
- the first time you started cracking that program, the segment addresses will
- change and the addresses you wrote down will be useless.
-
- This is because the memory map of your computer will change. Every time you
- start the debugger, use the same config files and don't load anything that
- wasn't loaded the first time you started the debugger.
-
- When I boot with my debugging config, the only things I load are a mouse
- driver, 4DOS, my debugger and ansi.sys (needed for cracking bbs doors). This
- way I'm assured that the program I want to crack gets loaded into the same
- memory region every time I run it, providing I don't run any other memory
- resident programs before loading the program to be cracked into the debugger.
-
- Take soft ice as an example, if you load a program into it using LDR.EXE and
- begin debugging, then later on you decide to just execute the program and
- break into it without first loading it with LDR.EXE, the segment addresses
- will change. That's because LDR.EXE is a program and using it will throw the
- segment addresses off by one word as opposed to just breaking into an already
- running program without first loading it with LDR.EXE.
-
- The program we will crack is budget minder, it is an extremely simple crack
- (it took me about 2 minutes to crack it) and is ideal for the lesson on how to
- remove nag screens from otherwise fully functional programs. It also deals
- with intrasegment calls, so it serves a dual purpose. That's another reason I
- chose it for the lesson.
-
- From now on, when I say step, step through, or step over, I want you to use
- the SINGLE STEP key. When I say trace, I want you to use the TRACE key once
- and only once!!!! The TRACE key is a highly specialized key and is not
- intended to be used multiple times like the SINGLE STEP key. If you don't
- follow these instructions, your gonna get lost...
-
- OK, once you've run budget minder a few times you will notice that it displays
- a nag screen before the main program is executed. You will also notice that
- this nag screen is the only type of protection that the program has. It
- doesn't contain any features that are disabled, nor does it display an
- additional nag screen upon exit.
-
- It's okay to apply a dirty crack to this program as all you want to do is kill
- the nag screen, so you have a little more leeway on how to patch it. And if
- you want to try different methods of patching it than the ones I give, it
- should still work fine.
-
- That was the most important factor in my decision to use this program for the
- lesson. I wanted to walk you through a program so you would become comfortable
- with it's flow, and I also wanted the program to be easy enough so that once
- you became familiar with it, there was enough room for you to experiment and
- try out your own methods.
-
- In this case, it's best to load the program into the debugger and start
- stepping through it right away. The protection is implemented very close to
- the beginning of the program, and this method of loading the program will put
- you right on top of everything.
-
- Allowing the program to run and breaking into it later on will not serve any
- useful purpose. You'll just end up having to trace your way back to the top.
- Besides, the nag screen comes up so fast you'll probably miss it if you try
- the second method anyway.
-
- Before you load it into the debugger, run UNP on BUDGET.EXE... AHA! The file
- was compressed with EXEPACK. It's now ready to debug as you've removed the
- compression envelope. Just for the hell of it, run UNP on it again. I've come
- across a few programs that have had multiple compression routines on them. If
- it shows up negative, your set to go.
-
- Now load BUDGET.EXE into the debugger, the program will be sitting at the
- first instruction to be executed awaiting your next command... Use the SINGLE
- STEP key to start stepping through the code and keep an eye on the
- instructions as you are stepping through them.
-
- Shortly you will come to a couple of calls, before you step over the first
- one, write down it's address. Now step over the first call with the SINGLE
- STEP key. Nothing happened, so you have to continue stepping through the code.
- But if something did happen when you stepped over this call like the nag
- screen being displayed or if you lost control of the program, you could just
- reload the program and issue the GO TO command to get back to that point using
- the address you wrote down.
-
- Step over the second call, nothing again. Ok, keep stepping through the code
- and keep an eye on the instructions. You will encounter a third call about 6
- instructions or so after the second call, step over it with the SINGLE STEP
- key... Bingo, you have found the call to the nag screen. Hit a key to exit the
- nag screen and you will now be sitting in the main program screen.
-
- But you no longer have control of the program. Remember I said you would loose
- control if you step over a call loop or interrupt and the program never
- returns from it? Hopefully you wrote down the address of that last call before
- you executed it. Now you can just quit out of the program and reload it. Then,
- once it's reloaded, issue the GO TO command to get back to the call without
- having to trace your way back there. So go ahead and do this before reading
- on...
-
- Ok, we are all back at the third call. It's address will be CS:0161, remember
- that the segment adresses will always be different for every computer, but the
- offsets will be the same. So from now on I'll write the addresses in that
- manner...
-
- We know that the last time we executed this call, the program never returned
- from it. So now we are going to have to trace into it for a closer look. Trace
- into the call with the TRACE key, don't use the SINGLE STEP key this time or
- you'll loose control again.
-
- You will now be inside the code for that call, start stepping through it again
- with the SINGLE STEP key, you will see some calls. Better write down your
- address before you step over them.
-
- Step over the first two calls, nothing... Use the RESTORE USER SCREEN key to
- toggle the display between the debugger and the program. Still a blank screen,
- so nothing important has happened yet. Now toggle the RESTORE USER SCREEN key
- to get the debugger screen back and continue stepping through the code.
-
- You will see another call and some more code, just step through them until you
- reach the RETF instruction and stop there. Toggle the display with the RESTORE
- USER SCREEN key, the screen is still blank...
-
- But we executed all of the code within the call and are ready to return
- without anything happening. The nag screen didn't get displayed nor did we
- loose control and end up in the main program, How come?
-
- Step over the RETF instruction with the SINGLE STEP key and you'll see why...
- The address that we return to is not the next instruction after the original
- call. Part of the code within the call we traced into revectored the return
- address for the original call and sent us to an entirely different location
- within the program.
-
- This is why we lost control when we first stepped over the call, the debugger
- was expecting the program to return to the next instruction after the original
- call, but it never did...
-
- So the instruction that we returned to was not the original line of code that
- was expected, instead we are at another far call. If you haven't gotten lost
- you should be at CS:0030 CALL CS:28BC.
-
- Write down the address of the CS:IP and then step over this call with the
- SINGLE STEP key, there is that annoying nag screen again. Hit a key to exit
- the nag screen and control will be returned to the debugger. This time the
- program returned from the call and you are in control again. So you now know
- that this call is the one that displays the nag screen and it is the one you
- want to kill.
-
- Hit the RUN key and let the program run, now quit out of it from the main
- program screen and reload it into the debugger. Use the GO TO command and
- supply it the address for the call to the nag screen.
-
- Ok, now lets see if the program will run or not if we don't execute the call
- to the nag screen. The call is at CS:0030 and the next instruction after the
- call is at address CS:0035... A quick way to jump past this call without
- executing it is to just increment the instruction pointer register to the next
- instruction.
-
- In this case we want to manipulate the IP register, and we want to set it to
- point to the instruction at CS:0035 instead of the instruction it is currently
- pointing to at CS:0030. You are going to have to figure out the command on how
- to do this with the debugger you are using yourself.
-
- If you are using turbo debugger, place the mouse cursor on the line of code at
- CS:0035 and right click the mouse. A window will pop up, then left click on
- new IP, or increment IP. If you are using soft ice, type rip=0035 and hit
- enter. Any other debugger, I have no clue...
-
- Now that we've moved the IP past the call to the nag screen let's see if the
- program is going to run. Hit the RUN key, hot damn! The nag screen doesn't
- come up, instead you are brought right into the main program.
-
- It looks like getting rid of that call is going to do the trick. Now that we
- know the program will run without making that call, it's time to decide on how
- to patch the program so the call is never made again.
-
- Think back to the original call we traced into for a minute, that call was the
- one that revectored the return address and brought us to the call to the nag
- screen. Therefore, it's reasonable to assume that that call is the protection
- check, and it might be a good idea to have another look at it.
-
- Before we do that there is one other thing I want to show you, and that's how
- to allow the program to make the call to the nag screen and return from the
- call without executing any of the code contained within it.
-
- This isn't the method we will use to patch this program, but it's an important
- concept to grasp as you'll end up doing it sooner or later on some other
- program anyway. Remember that this is a far call and you can't just nop it
- out.
-
- Quit the program, reload it, and get to the address of the call to the nag
- screen. Last time through we just incremented the IP to bypass it. Now we will
- trace into it to see what it is doing.
-
- Hit the TRACE key and trace into the call. Now start stepping through it with
- the SINGLE STEP key, don't bother writing any addresses down for now. There
- are several dozen calls in this routine along with shitloads of other code.
-
- Toggle the display with the RESTORE USER SCREEN key after you step over a few
- of the calls and you will see that the program is in the process of drawing
- the nag screen.
-
- Keep stepping through it and you'll see more and more of the screen being
- drawn as the code progresses. This is getting boring, so stop stepping through
- the code and start scrolling the code window down with the down arrow key and
- watch the code.
-
- What you are looking for is the RETF instruction as this is the end of the
- call. Keep scrolling, I told you this call had a ton of code in it. When you
- do find the RETF instruction write down it's address, it is CS:2B0E in case
- your having trouble finding it. Ok, you've got the address of the RETF far
- instruction written down so now just let the program run, quit out of it,
- reload it, and get back to the call for the nag screen.
-
- You should now be sitting at the call to the nag screen, trace into it and
- stop. The first instruction of the call is MOV CX,0016 and this is where the
- CS:IP should be pointing to. What we want to do now is to jump to the RETF
- instruction and bypass all of the code within the call itself. So let's
- re-assemble the MOV CX,0016 instruction and replace it with a new one.
-
- First, make sure you are at this instruction, if you've traced passed it your
- gonna have to reload the program and get back to it... OK, we are all sitting
- at the MOV CX,0016 instruction and it's address is contained in the CS:IP
- registers.
-
- Now ASSEMBLE JMP 2B0E (the offset address of the RETF instruction) and specify
- the address of the CS:IP. The MOV CX,0016 instruction will be replaced with
- JMP 2B0E. And seeing as how both of these instructions are the same length we
- didn't have to pad it out with any nop's.
-
- Now hit the RUN key, you are brought into the main program and the nag screen
- didn't get displayed! We allowed the program to make the call, but we didn't
- allow any of the code within the call to be executed. And as far as the
- program is concerned, it made the call and the nag screen was displayed.
-
- Now let's go back and take another look at the call that we suspect is the one
- that contains the protection check itself. Reload the program and go to the
- original call that revectored the return address, now trace into it. I've
- traced into the calls that are contained in here and they are setting up the
- addresses for the RETF instruction at the end of this call among other things.
- You don't need to trace into them as you might not understand what's going on,
- but if you feel up to it, go right ahead.
-
- What I want to concentrate on are the last four lines of code in the call as
- they are the ones that finally set up the address to return to. Step through
- the code until you are at CS:00A8 and take a look:
-
- CS:00A8 8B04 MOV AX,[SI] DS:SI=0000
- CS:00AA 053000 ADD AX,0030
- CS:00AD 50 PUSH AX
- CS:00AE CB RETF
-
- The first instruction is loading the AX register with the contents of the
- memory location that the SI register is pointing to. And you can see by
- looking at the memory location that the DS:SI pair is pointing to that it
- contains 0000. (this is where the display command and data window come in
- handy).
-
- The second instruction is adding 0030 to the contents of the AX register.
-
- The third instruction is placing the contents of the AX register onto the top
- of the stack.
-
- The fourth instruction is returning from the call, and where do you think that
- the RETF instruction gets the address for the return? Yep, you guessed it, it
- gets it off the top of the stack. Funny that the instruction right before it
- just placed something there isn't it?
-
- Also funny is that it happens to be the address of the nag screen. Look at
- what is being added to the AX register on the second line of code. Boy that
- sure looks like the offset address to the nag screen to me. Well, we are about
- to cut the comedy and kill the bitch.
-
- Remember that the next instruction after the nag screen is CS:0035, now look
- at the first line of code. The contents of the memory location it's
- referencing contains 0000, and I'll bet that if your copy was registered it
- would contain 0005 instead.
-
- Why? because if the first instruction placed 0005 in the AX register, when the
- second line of code added 0030 to it, you would end up with 0035 which happens
- to be the address of the next line of code after the nag screen.
-
- Then the third instruction would place 0035 on the stack and that is where the
- RETF instruction would go to. If this were the case, the nag screen would
- never get displayed... Cool huh?
-
- Well, what do you think we should do? We could trace further back in the
- program and try to find the instruction that places 0000 in that memory
- location and modify it to place 0005 in there instead, but this process is
- somewhat involved and I don't want to throw too much at you at once.
-
- Instead, I have an easier solution. Seeing as how the memory location will
- always contain 0000, why don't we just change the ADD AX,0030 instruction to
- ADD AX,0035? This should get the correct address placed on the stack for the
- RETF instruction to bypass the nag screen...
-
- Let's try it and see how it works. SINGLE STEP through the code until the
- CS:IP is at the instruction ADD AX,0030. Now, ASSEMBLE the instruction to read
- ADD AX,0035 and hit the RUN key. We are placed in the main program screen
- without any stinkin' nag screen getting displayed!
-
- Congratulations! you have just cracked your first program :) Try other methods
- of patching the program besides the ones I went over. The next chapter will
- deal with how to make the changes you've made permanent.
-
-
-
- CHAPTER 5 HOW TO USE THE DISK EDITOR
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- Ok, we cracked budget.exe in the debugger and know it's going to work. Now we
- need to make those changes permanent. The first thing we have to do before we
- load the file into the disk editor is to create a search string.
-
- So we are going to have to reload budget.exe into the debugger and trace back
- to the location where we want to make the patch in order to get the hex bytes
- of the instructions we want to search the disk file for.
-
- Load budget.exe back into the debugger and trace back to the last four
- instructions of the original call that revectored the return address. You
- should be looking at this:
-
- CS:00A8 8B04 MOV AX,[SI]
- CS:00AA 053000 ADD AX,0030
- CS:00AD 50 PUSH AX
- CS:00AE CB RETF
-
- The group of numbers to the right of the addresses are the hexadecimal
- representations of the mnemonic instructions. These are the bytes that we will
- use for our search string. So write them down beginning from top left to
- bottom right so you end up with this: 8B0405300050CB
-
- This is the byte pattern that we will search for when we load the file into
- the disk editor. We have a search string, but we also need to make a patch
- string as well. In order to do this, we will have to assemble the new
- instructions in memory, and then write down the changes we've made to the
- code.
-
- So ASSEMBLE ADD AX,35 and specify the address for the old ADD AX,0030
- instruction. The new code should look like this:
-
- CS:00A8 8B04 MOV AX,[SI]
- CS:00AA 053500 ADD AX,0035
- CS:00AD 50 PUSH AX
- CS:00AE CB RETF
-
- Notice that we only re-assembled the second line of code and that is the only
- difference between the new code and the original code. So what I want you to
- do is to write down the changes under the old code it replaced so it looks
- like this:
-
- 8B0405300050CB <-- search string
- ^
- 5 <-- patch string
-
- Now we are all set to load the file into the disk editor. We have a string to
- search for and another one to replace it with. Load budget.exe into your disk
- editor, select the search function, and input the search string.
-
- NOTE: some disk editors default to an ASCII search so you may have to toggle
- this to hex search instead. If your in the wrong mode, the disk editor will
- not find the byte pattern your looking for.
-
- Once the disk editor finds the byte pattern of the search string, just replace
- the bytes of the old code with the bytes to the new code and save it to disk.
- The program is now permanently cracked.
-
- Sometimes however, the code you want to patch is generic enough that the
- search string will pop up in several different locations throughout the file.
- It's always a good idea to keep searching for the byte pattern after you've
- found the first match. If the disk editor doesn't find any more matches your
- all set.
-
- If the string you are searching for is contained in more than one location and
- you patch the wrong one the crack will not work, or you will end up with a
- system crash when you run the program. In this case, you'll have to reload the
- program back into the debugger and create a more unique search string by
- including more instructions around the patch site in the search string.
-
- One last thing, you cannot include instructions that reference dynamic memory
- locations in the search string. These bytes are not contained in the disk
- file. So keep this in mind when you are creating your search strings...
-
- And the protection might not be included in the main executable either. If you
- cannot find the search string in the main exe file, load the other program
- files into the disk editor and search them as well, especially overlay files.
- Fortunately for you, I've included a tool to help you do this.
-
-
-
-
- CHAPTER 6 OTHER CRACKING TOOLS
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-
- In addtion to UNP, there are several other tools that you can utilize to make
- your job easier. These tools were not designed with the cracker in mind, but
- they can be adapted to serve our purposes rather than the ones which they were
- written for.
-
- UNP and other programs like it were written to remove the compression
- envelopes from exectables so you would be able to scan those files with a
- virus scanner among other things. If someone were to attach a virus to an exe
- file and then compress it, the file for all intents and purposes would be
- encrypted. Now when you downloaded that file and ran your virus scanner on it,
- it might not find the virus.
-
- But crackers found a different use for these types of programs. We use them to
- remove the compression envelope so that we can find the byte strings we want
- to search the files for. I'm sure most of the programmers who wrote these
- programs never intended them for this purpose. There are some out there though
- that were written by crackers with this exact purpose in mind.
-
- Don't just rely on UNP as your only program to do this. No one program will be
- able to remove evrything you come across. It's a good idea to start collecting
- these types of programs so you have more than one alternative if you come
- across a compressed file, and your favorite expander doesn't understand the
- routines. Be aware though that some programs are actually encrypted and not
- compressed. In this case the expander programs will prove useless.
-
- Your only recourse in this instance is to reverse engineer the decryption
- routine while the program is decrypting to memory, and modify your search
- string to search for the encrypted version of the bytes. Or you could write a
- tsr patcher that impliments your patch after the program is decrypted to
- memory.
-
- There is another category of programs you can adapt to your use and they work
- in conjunction with the file expanders. These types of programs will scan
- entire directories of files and pop up a window that displays which files are
- compressed and what they are compressed with. They won't remove the
- compression routines from the files themselves, but will only inform you which
- files are compressed and which are not. UNP also includes a command line
- switch to do this...
-
- Now instead of blindly running UNP on several different program files to see
- if they are compressed or not, you can see at a glance if you even need to run
- it at all. And if you do, you'll know exactly which files to run it on. This
- is another time saving type of program and there are several out there, you
- just have to look for them.
-
- Another type of program that you will find useful will scan entire
- disks/directories/subdirectories of files for specific hex or ascii byte
- patterns contained within those files, and this is the purpose of the second
- uuencoded cracking tool contained in this guide.
-
- One method I use to determine if a shareware program is registerable or not
- before actually loading it into the debugger is to use this tool.
-
- I usually will have it scan all the programs files and input the string REG.
- This will show all files that contain the string unREGistered and REGistered.
- If it returns a string that contains REGistered in a file other than the doc
- files, I know the program can be made into the registered version. This is
- just a quick check I do on programs that have certain features diabled to
- determine if the program does contain the code for the registered version.
-
- An added feature of this program is that after you've cracked a program and
- have a byte string to search for, you can run this program in hex mode and
- input your search string. Now it will search all of the programs files and
- return the name of the file that contains your search string, then you can
- just load that file into the disk editor and make the patch.
-
- It will also let you know if your search string is contained in more than one
- location within the file. Remember, if this is the case you'll have to reload
- the program back into the debugger and create a larger search string by
- including more instructions around the patch site.
-
- The programs name is SS303 and it's very easy to use, just read the docs for
- it...
-
- These are the programs I use as cracking tools, I'm sure that there are more
- types of programs that can be adapted for cracking purposes out there, I've
- just not found a use for them yet. If you come across anything useful drop me
- a note at an575063@anon.penet.fi.
-
-
-
- CHAPTER 7 SOURCE CODE TO A SIMPLE BYTE PATCHER
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- As I've stated in the overview chapter, if you want to distribute your patches
- you are going to have to write a patcher program. Simply releasing the patched
- version of the program file is not desirable. For one thing it's illegal,
- another consideration is size. Some files you patch will be 300K or more, and
- this is quite a large crack to release. The patcher program included in this
- guide is much much smaller, it will assemble to about 600 bytes or so,
- depending on the size of your logo.
-
- And what if you want the end user to be able to register the program in their
- own name? A patched .exe or .ovr file will not allow this.
-
- When you release a patch that you yourself wrote, you are not breaking any
- laws. The program was written by you and is your intellectual property to do
- with as you see fit, including making it available for public use. The person
- breaking the law is the end user who will use it to illegally modify someone
- elses intellectual property contrary to the licencing terms they agreed to
- when they installed the program. Remember, it's not illegal to write and
- distribute a crack, but it is illegal to apply a crack.
-
- That's why all of the programs I've included in this guide are shareware
- programs in the original archives as released by the authors and have not been
- tampered with in any way. I'm not about to release a modified version of
- someone elses copyrighted property. The only thing I am doing is supplying you
- with the original archive and the information on how to modify it if you wish,
- this is not illegal. If you decide to take the program and modify it that's
- your problem, not mine...
-
- This patcher routine is very simple, I wrote it about 5 years ago and it was
- my very first patcher program. It is a brute force patcher in that it will not
- do any error checking and blindly patch the program you specify with the byte
- pattern you supply. This method has it's advantages and disavantages.
-
- The disadvantage to this method is that seeing how the program does not
- perform any error checking it will patch the file specified with the
- replacement string even if it's not the correct version of the program. If the
- filename is the same, the patch will be applied.
-
- Let's say you crack a program called Ultimate Menu and the version number is
- 1.0, and the file you patch is called menu.exe. Now let's say a little while
- later version 1.5 of the program comes out and someone who has your patch for
- version 1.0 decides to run it on version 1.5 of the program.
-
- This byte patcher will not check the new menu.exe for any changes before
- making the patch, it will just patch the program in the location you specified
- with the string you supplied even if the code you want to change is no longer
- there. This could very well be the case if the programmer has significantly
- re-written the code between versions, and what will end up happening is the
- file will be corrupted and probably crash the system when it is run.
-
- But this is also the advantage of my byte patcher. If the code to be replaced
- is still in the same location in the new version, you'll not have to release a
- new crack for each version of the program. Bear in mind that when I wrote this
- program I was just starting out and didn't consider these possibilities. The
- reason I included it in this guide was to give you an idea on how to write
- your own patcher or to modify this one to suit your own purposes.
-
- The patcher program that I use now is extremely complex and would just confuse
- the hell out of you. Basically what I do is to make a backup of the original
- file I am going to patch and then patch the original file. Then I run my
- patcher program on the two files, it compares the differences between the
- original file and the patched one and saves them to a data file. I then
- assemble a patch using the data file.
-
- What I end up with is a patch that will check the file you are running it on
- to see if it is indeed the correct version before applying the patch. If it's
- not, the patch won't be made. This method also allows me to make multiple
- patches at different locations throughout the program. The byte patcher
- included in this guide will only allow one string to be patched in one
- location. But if you do a clean crack, that's all you'll need anyway.
-
- Ok. here is the source code to the patcher program, I've commented as much as
- I could throughout the code to make it more understandable. I also wrote it to
- be generic enough so that you can re-use it over and over simply by plugging
- in certain values and re-assembling it.
-
- NOTE: the patch offsets are not the segment:offset adresses of the code as it
- resides in memory, but the offset from the beginning of the disk file.
-
- .model small
- .code
- ORG 100H
- start: JMP begin
-
- ;******************************************************************************
- ; these are all the variables you set to crack a file,
- ; simply change the values and then assemble the program
- ;******************************************************************************
-
- msb EQU 0000H ;the first part of the patch offset
- lsb EQU 055AH ;the second part of the patch offset
- cnt EQU 3H ;number of bytes in your patch
- patch_data DB 'EB2E90',0 ;the byte string to be written
- file_name DB 'go.pdm',0 ;the name of the file to be patched
-
- logo DB 'Cracked by Uncle Joe',0AH,0DH
- DB ' -=W.A.S.P. 92=- ',0AH,0DH
-
- error1 DB 'FILE NOT FOUND',0AH,0DH
- DB 'Make sure you have GO_CRACK.COM in the same',0AH,0DH
- DB 'directory as GO.PDM',0AH,0DH
- DB '$'
-
- error2 DB 'A FATAL ERROR HAS OCCURED',0AH,0DH
- DB 'THE CRACK WAS NOT APPLIED',0AH,0DH
- DB '$'
-
- error3 DB 'GO.PDM has the read only attribute set',0AH,0DH
- DB 'reset it before attempting to make the patch',0AH,0DH
- DB '$'
-
- handle DW 0
-
- ;******************************************************************************
- ; this procedure opens the file to be cracked
- ;******************************************************************************
-
- open_it PROC near
- MOV DX,offset file_name ;setup to open file to be
- MOV AX,3D02H ;cracked
- INT 21H
- JNC done ;if successful, continue
-
- CMP AX,05H
- JZ read_only
- MOV AH,09H ;else display error message
- MOV DX,offset error1 ;and exit
- INT 21H
- JMP exit
- read_only: MOV AH,09H
- MOV DX,offset error3
- INT 21H
- JMP exit
-
- done: MOV handle,AX ;store the file handle for
- RET ;use later and return
- open_it ENDP
-
- ;******************************************************************************
- ; this procedure sets the file pointer to the patch location
- ;******************************************************************************
-
- move_it PROC near
- MOV AH,42H ;setup to move the file
- MOV AL,00H ;pointer to the patch site
- MOV BX,handle ;load the file handle
- MOV CX,msb ;the first part of offset
- MOV DX,lsb ;and the second part
- INT 21H ;move the pointer
- JNC ok ;if successful, continue
-
- MOV AH,09H
- MOV DX,offset error2
- INT 21H ;else print error message and
- JMP exit ;exit
- ok: RET
- move_it ENDP
-
- ;******************************************************************************
- ; this procedure writes the crack to the file and closes it
- ;******************************************************************************
-
- patch_it PROC near
- MOV AH,40H ;setup to write the crack
- MOV BX,handle ;load file handle
- MOV CX,cnt ;load number of bytes to write
- MOV DX,offset patch_data ;point DX to patch data
- INT 21H ;make the patch
-
- JNC close_it ;if successful, contintue
- MOV AH,3EH
- INT 21H
- MOV AH,09H ;if not then something
- MOV DX,offset error2 ;is wrong, disk may be write
- INT 21H ;protected. If so, print error
- JMP exit ;message and exit
-
- close_it: MOV AH,3EH ;crack was successful
- INT 21H ;close file and return
- RET
- patch_it ENDP
-
- ;******************************************************************************
- ; the main program
- ;******************************************************************************
-
- begin PROC near
- CALL open_it ;open file to be patched
- CALL move_it ;move pointer to patch site
- CALL patch_it ;make the patch and close file
- MOV AH,09H
- MOV DX,offset logo ;display logo
- INT 21H
-
- EXIT: MOV AX,4C00H ;and exit
- INT 21H
- BEGIN ENDP
-
- END START
-
-
-
-
- CHAPTER 8 CONCLUSION
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
- Hopefully this guide has been useful in helping you understand the cracking
- process. It is by no means an all inclusive guide, the main goal I had in mind
- when I wrote it was to give beginners a push without confusing the hell out of
- them.
-
- It is not feasable to try and include all of the tricks of the trade that a
- beginner might find useful into one single guide, nor would I want to do this.
- For one thing, this guide would be ten times the size it is now, and even then
- it would not be an encyclopedia of what to do for every situation. If your
- serious enough about cracking, you will discover enough tricks and develop
- your own methods as you progress. And you have to be creative! What works in
- one situation may not work again in a similar one.
-
- Instead, I tried to give you a general idea on how a programs code might
- operate and what to look for. A successful cracker is not someone who
- memorizes a specific set of actions to perform on a specific piece of code. A
- successful cracker is someone who understands the flow of the code, and how to
- adapt his methods to successfuly re-write the programs code to behave as he
- wishes and not as the programmer intended it to. There are no set rules for
- this, the very nature of the PC won't allow it.
-
- If you have any questions about cracking or are stumped by something, drop me
- a note at an575063@anon.penet.fi, I'll be glad to give any advice I can. Or if
- you simply just wish to discuss cracking techniques or anything of that
- nature, I'd love to hear from you.
-
- NOTE: Do NOT mail me and ask me to crack programs for you! I'm not interested
- in cracking for the masses. If you need something cracked, learn how to crack
- it yourself. If you are unwilling to learn how, then register it.
-
- Most people who frequent the cracking newsgroups nowadays in my opinion are
- clueless ungrateful fucks, and I'll not supply these losers with cracks. 95%
- of the users in the newsgroups are useless parasites who only take and do not
- give anything in return, all the posts you see now are from losers saying give
- me this, give me that. These people are scum and do not deserve what we as
- crackers have to offer. The only thing they have done is to trash the
- newsgroups I used to love... I do hate them.
-
- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-
-
-
-