home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Mendoza / JOE.TXT < prev    next >
Text File  |  2000-05-25  |  84KB  |  1,628 lines

  1.  
  2.  
  3.            Uncle Joe's CrackBook  (volume 1)
  4.  
  5.                    or
  6.  
  7.             A beginners Guide to Cracking
  8.  
  9.  
  10.  
  11.  
  12.  
  13.       Chapter  1         overview
  14.  
  15.       Chapter  2         some tips on how to use the debugger
  16.  
  17.       Chapter  3         some basic cracking techniques
  18.  
  19.       Chapter  4         walk through of an easy crack
  20.  
  21.       Chapter  5         how to use the disk editor
  22.  
  23.       Chapter  6         other cracking tools
  24.  
  25.       Chapter  7         source code to a simple byte patcher
  26.  
  27.       Chapter  8         conclusion
  28.  
  29.  
  30.         Programs included at the end of this guide
  31.  
  32.       
  33.       Section  1         uuencoded cracking tool
  34.  
  35.       Section  2         another uuencoded cracking tool
  36.  
  37.       Section  3         uuencoded program to crack for the walk through
  38.  
  39.  
  40.  
  41.  
  42. CHAPTER 1       OVERVIEW
  43. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  44.  
  45. You might be wondering what type of programming skills you need to become a
  46. cracker. Knowing a higher level language such as Basic, Pascal, or C++  will
  47. help you somewhat in that you will have an understanding of what's involved in
  48. the process of writing a program and how certain aspects of a program
  49. function. If you don't have any programming skills, you have a long road ahead
  50. of you. But even if you can program in a high level language, in order to
  51. crack you have to know assembly...
  52.  
  53. It really doesn't matter what language a program was written in in order to
  54. crack it, because all programs do the same thing. And that is issue commands
  55. to the microprocessor. And all programs when broken down to their simplest
  56. form are nothing more than a collection of 80XXX instructions and program
  57. specific data. This is the level of assembly language. In assembly you have
  58. total control of the system. This is also the level that the debugger operates
  59. at.
  60.  
  61. You don't have to become a master at assembly to crack a program, but it
  62. helps. You do need to learn some rudimentary principles, and you absolutely
  63. have to become familiar with the registers of the cpu and how the 8088
  64. instruction set uses them. There is no way around this.
  65.  
  66. How proficient you are at assembly will determine how good of a cracker you
  67. become. You can get by on learning a few basic instructions, how to use a
  68. debugger, and one or two simple techniques. This will allow you to remove a
  69. few shareware nag screens, and maybe you'll luck out and remove the copy
  70. protection from a game or two, but that's it.
  71.  
  72. As soon as a programmer throws some anti-debugging code into a program or
  73. starts revectoring interrupts, you'll be whining for someone to post a crack
  74. for this or that... And you can forget about ever learning to crack windows
  75. programs.
  76.  
  77. It's much much easier to learn to crack in DOS than windows. DOS is the
  78. easiest environment to debug in. This guide will focus on DOS programs as
  79. cracking windows apps is a little bit overwhelming unless you are already an
  80. experienced cracker. And if you are, your wasting your time by reading this.
  81. This manual is geared towards the raw beginner who has no clue as to where to
  82. start and needs a little hand holding in order to get going.
  83.  
  84. There are several good beginners manuals out there, but most of them assume a
  85. person has at least some experience in cracking or knows how to use the
  86. different tools of the cracker, and the raw beginner usually becomes
  87. frustrated with them very quickly because they don't understand the concepts
  88. contained in them.
  89.  
  90. I wrote this guide as sort of a primer for the beginner to read before reading
  91. the more comprehensive guides. I tried to keep it as simple as possible and
  92. left a great deal of information out so as not to overwhelm anyone with too
  93. much information at once. Hopefully after reading this guide it will be easier
  94. for the beginner to understand the concepts of the more arcane guides out
  95. there. So if you are reading this and it seems a little bit remedial,
  96. remember, at one time you didn't know what a debugger was used for either.
  97.  
  98. Now in case your not familiar with the debugger and disk editor and what their
  99. different roles in cracking are, I'll give a brief explanation of each. As
  100. these are the crackers most valuable tools.
  101.  
  102. The debugger is what you will use to actually crack the program. When you load
  103. a program you wish to crack into the debugger, it will load the program and
  104. stop at the first instruction to be executed within the code segment. Or, you
  105. can also optionally break into an already running program and it will halt the
  106. program at the instruction you broke into it at and await further input from
  107. you. At this point, you are in control of the program.
  108.  
  109. You can then dynamically interact with the program and run it one line of code
  110. at a time, and see exactly what the program is doing in real time as each line
  111. of code is executed. You will also be able to re-assemble instructions (in
  112. memory only), edit the contents of memory locations, manipulate the cpu's
  113. registers, and see the effects your modifications have on the program as it's
  114. running. This is also where all your system crashes will occur... There is a
  115. lot of trial and error involved in cracking.
  116.  
  117. As stated above, the debugger will only modify the program while it's up and
  118. running in memory. In order to make permanent changes, you need to load the
  119. program file to be patched into the disk editor and permanently write the
  120. changes you've made to disk. A detailed explanation of how to do this will be
  121. made in chapter 5.
  122.  
  123. So, with this in mind, you need a few essential tools... The first one is a
  124. good debugger. The original draft of this guide gave explicit instructions on
  125. how to use my favorite debugger. After considerable deliberation, I decided to
  126. re-write it and make the instructions more generic so you could apply them to
  127. most any debugger. You will also need a disk editor, it doesn't matter which
  128. one you use as long as it will load the program file, search for and edit the
  129. bytes you want to change.
  130.  
  131. I uuencoded a few cracking tools that you will find indespensible and placed
  132. them at the end of this guide. I won't go into the use of the cracking tools
  133. right now. But believe me, you absolutely need one of them, and the other one
  134. will save you a lot of effort. I also uuencoded the program that we will crack
  135. in the walk through and included it in this guide as well.
  136.  
  137. As you get better, you'll have to write programs that will implement your
  138. patches if you decide to distribute them. The patches themselves don't have to
  139. be written in assembly.
  140.  
  141. The source code I included in this manual for the byte patcher is the first
  142. patcher program I ever wrote, and is extremely simple. It's written in
  143. assembly because that's the only language I know how to program in. but if you
  144. are already proficient in a higher level language, it should be trivial for
  145. you to duplicate it's methods in your preferred language.
  146.  
  147.  
  148.  
  149.  
  150. CHAPTER 2       SOME TIPS ON HOW TO USE THE DEBUGGER
  151. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  152.  
  153. Ok, before I begin, I'd just like to stress how important it is that you know
  154. at least some assembly before trying to continue.  If you don't, you will get
  155. lost pretty quick from here on out. Comprehension of the base 16 (hexadecimal)
  156. number system is also required.
  157.  
  158. I'm not about to give a remedial course on assembly or hex math, that would
  159. take too long and I'd probably leave too many questions un-answered. Besides,
  160. there is enough information on them available from a myriad of other sources.
  161.  
  162. So, from now on in this guide, I'm assuming you have a fair working knowledge
  163. of assembly and hexadecimal. If I say something you don't understand or you
  164. cannot grasp some concept, look it up somewhere...
  165.  
  166. I've tried to make this section as generic as possible. I used general
  167. descriptions when explaining HOTKEYS and COMMANDS as different debuggers will
  168. use different keys and command syntax to implement these functions.
  169.  
  170. You should be able to translate these instructions to the actual key strokes
  171. and commands that your debugger uses... If you don't know how to use a
  172. debugger, PAY ATTENTION!!! If you already know how to use a debugger you can
  173. skip this section as it is only a general overview of different windows and
  174. functions designed for the absolute beginner who has no clue as to what he is
  175. looking at.
  176.                       
  177. First, I'll give an overview on the different windows that most debuggers use.
  178.  
  179.  
  180. REGISTER WINDOW:
  181.  
  182. The register window contains the general purpose and flags registers of the
  183. cpu. You will notice that the general purpose registers contain hexadecimal
  184. values. These values are just what happened to be in there when you brought up
  185. the debugger. you will also notice that some of the flags are highlighted
  186. while some are not. Usually, the highlighted flags are the ones that are SET.
  187. While the ones that are not highlighted are CLEARED. The layout of this window
  188. will vary from debugger to debugger, but they all basically are the same.
  189.  
  190. From this window you will be able to manipulate the contents of the cpu's
  191. registers. some debuggers accomplish this by clicking on the register fsto
  192. modify with the mouse and then entering a new value. Other more powerful
  193. debuggers use a command line interface, you'll have to discover how your
  194. debugger goes about this yourself.
  195.  
  196. You will change the values of the registers while debugging a program in order
  197. to change the behavior of the running program. Say you come across a JNZ
  198. instruction (jump if not zero), that instruction makes the decision on whether
  199. or not to make the jump based on the state of the (Z)ero flag. You can modify
  200. the condition of the (Z)ero flag in order to alter the flow of the programs
  201. code.
  202.  
  203. By the same token, you can modify the general purpose registers in the same
  204. manner. Say the AX register contains 0000, and the program bases it's actions
  205. on that value, modifying the AX register to contain a new value will also have
  206. the effect of modifing the flow of the code. After you become comfortable with
  207. using a debugger you'll begin to appreciate just how powerful this window is,
  208. and you'll aslo discover soon enough just how totally it can screw your
  209. system if you fuck up.
  210.  
  211.  
  212. DATA WINDOW:
  213.  
  214. The data window will display data as it exists in memory. From this window you
  215. can usually display, search, edit, fill, and clear entire ranges of memory.
  216. The two most common commands for this window are display and edit. The search
  217. command is also useful in cracking. But for the level of debugging I'll be
  218. teaching you in this guide, we won't make use of this window. You have a lot
  219. to learn before this window becomes an asset to you.
  220.  
  221.  
  222. CODE WINDOW:
  223.  
  224. The code window is the window in which you will interact with the running
  225. program. This is the most complex window, and it is where the bulk of
  226. debugging occurs. I'll just go over some keystrokes and a few commands here,
  227. as the majority of learning how to use this window will come when I show you
  228. how to crack a program.
  229.  
  230. The layout of the window is pretty simple, the group of 8 numbers with the
  231. colon in the middle of them to the far left of the window is the
  232. address:offset of that line of code. Each line of code in this window is an
  233. instruction that the program will issue to the microprocessor, and the
  234. parameters for that instruction. The registers that contain the address for
  235. the current instruction waiting to be executed are the CS:IP registers (code
  236. segment and instruction pointer).
  237.  
  238. You will also notice a group of hex numbers to the right of the addresses,
  239. this group of numbers is the hexadecimal equivalent of the mnemonic
  240. instructions (pronounced new-mon-ik). The next group of words and numbers to
  241. the right of the hex numbers are the mnemonic instructions themselves.
  242.  
  243. HOTKEYS AND COMMANDS:
  244.  
  245. Now we'll move onto the HOTKEYS. I won't go into all of them, only the most
  246. useful ones, same for the commands.
  247.  
  248. The RESTORE USER SCREEN KEY: This key will toggle the display between the
  249. debugger and the program you are debugging without actually returning control
  250. to the program itself. it's useful to check what the program is doing from
  251. time to time, especially after stepping over a CALL.
  252.  
  253. The HERE KEY: This key is the non-sticky breakpoint key. To use it, Place the
  254. cursor on a line of code and hit it. The program will then run until it
  255. reaches that line. When (and if) the program reaches that line, program
  256. execution will halt, control will be returned to the debugger and the
  257. breakpoint will be removed.
  258.  
  259. The TRACE KEY: This key will execute one line of code at a time and will trace
  260. into all calls loops and interrupts.
  261.  
  262. The BREAKPOINT KEY: This is the sticky breakpoint key. This will enable a
  263. permanent (sticky) breakpoint on the line of code that the cursor is on. When
  264. a sticky breakpoint is enabled, program execution will halt and control will
  265. be returned to the debugger every time that line of code is encountered within
  266. the running program until you manually remove it.
  267.  
  268. The SINGLE STEP KEY: The most used key on the keyboard. This key will execute
  269. one line of code at a time but will not trace into calls loops or interrupts.
  270. When you step over a call interrupt or loop with this key, all the code
  271. contained within the sub-routine is executed before control is returned to the
  272. debugger. If the program never returns from the sub-routine, you will lose
  273. control and the program will execute as normal.
  274.  
  275. The RUN KEY: This key will return control to the program being debugged and
  276. allow it to execute as normal. Control will not be returned to the debugger
  277. unless a breakpoint that you've set is encountered.
  278.  
  279. Now for a few commands. The GO TO command functions like the HERE key in that
  280. it will insert a non-sticky breakpoint at the specified address.
  281.  
  282. When you enter this command the debugger will return control to the program
  283. until the line of code you specified in the GO TO command is reached. When
  284. (and if) the CS:IP registers equal the address you typed in, the program will
  285. halt, control will be returned to the debugger and the breakpoint will be
  286. removed.
  287.  
  288. You might be wondering why you would want to type all this in when you can
  289. just hit the HERE KEY instead. The answer is this; the HERE KEY is great if
  290. you want to set a local breakpoint. By a local breakpoint I mean that the
  291. breakpoint you want to set is somewhat close to your current location in the
  292. program.
  293.  
  294. But what if you want to set a breakpoint on a line of code that isn't in the
  295. current code segment? You wouldn't want to use the HERE KEY cause the address
  296. is no where near the point you are at in the program. This, among other uses
  297. is where the GO TO command comes in.
  298.  
  299. The ASSEMBLE command is the command you will use to re-write the programs
  300. instructions. This command will allow you to assemble new instructions
  301. beginning at the address you type in, or at the current CS:IP. The
  302. instructions you enter will replace (in memory only) the existing program code
  303. at the address you specified. This is another method you will use to alter the
  304. running program to behave as you wish and not as the programmer intended it
  305. to.
  306.  
  307. EXAMPLE: Lets say that there is a line of code that reads JNZ 04FC, and we
  308. want to change it to read JMP 04FC. You would issue the ASSEMBLE command and
  309. specify the address of the code you wish to change, then type in JMP 04FC.
  310. Now the line of code in the code window who's address you specified in the
  311. ASSEMBLE command will be overwritten with the code you typed in. Some
  312. debuggers automatically default to the address contained in the CS:IP for this
  313. command.
  314.  
  315. There are a whole host of other commands available in this window depending on
  316. what debugger you are using, including commands to set breakpoints on
  317. interrupts, memory locations, commands that list and clear breakpoints,
  318. commands to un-assemble instructions etc etc... And as for the commands I
  319. don't go over, the best lessons learned are the ones that are self taught.
  320.  
  321. Well, that's pretty much it on debuggers without going into explicit
  322. instructions for specific debuggers. The only other thing I can tell you is
  323. that the more you use it, the easier it'll get. Don't expect to become
  324. familiar with it right away. As with anything, practice makes perfect. It's
  325. taken me 5 years and thousands of hours of debugging to reach the level I'm at
  326. now.  And I still learn something new, or re-learn something I forgot on just
  327. about every program I crack. Don't ever think that you know everything,
  328. cracking is a constant learning process.
  329.  
  330.  
  331.  
  332.  
  333. CHAPTER 3:      SOME BASIC CRACKING TECHNIQUES
  334. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  335.  
  336. The first thing I want to do before going into some simple techniques is to
  337. explain the purpose of one of the uuencoded cracking tools at the end of this
  338. guide. And also to go over some general procedures you should perform before
  339. actually loading a program you wish to crack into the debugger.
  340.  
  341. Nowadays a lot of programmers will compress the executable files of their
  342. programs to save space and to make it difficult for people who don't know any
  343. better to hack those files. There are a lot of losers out there who will get
  344. ahold of a program and lacking any skill or talent of their own, will load the
  345. program into a disk editor and hex edit their name into it. Or they will make
  346. other similarly feeble modifications.
  347.                                      
  348. This is the reason I encrypt all of the cracks that I distribute. The routines
  349. I write are not that hard to defeat, but I figure anyone with the skill to
  350. crack them is far above having to hack their name into them...
  351.  
  352. Ok, back to the file, the name of the program is UNP and it is an executable
  353. file expander. It's purpose is to remove the compression envelope from
  354. executable programs. And it supports most of the compression routines
  355. currently in use...
  356.  
  357. A lot of the compression routines will cause a debugger to lock up with a
  358. protected mode violation if you try to step through the compressed file,
  359. especially PKLITE v1.15. And seeing as how the file is compressed, if you load
  360. it into a disk editor it will just look like a bunch of garbage and you'll not
  361. be able to find the bytes you want to edit anyway.
  362.  
  363. UNP is very easy to use, just type UNP [filename] and if there is any type of
  364. compression envelope that UNP understands on the file, UNP will remove it. You
  365. can then load the file into a debugger and hack away...
  366.  
  367. But before you load a program into the debugger you should run the program a
  368. few times and get a feel for it. You want to see how the protection is
  369. implemented. Whether it's nag or delay screens and at what point in the
  370. program they fist appear, or where in the program does the first mention of
  371. being unregistered or an evaluation copy appear?
  372.  
  373. This is important. Because before the program displays the first mention of
  374. being unregistered, it has to do the protection check. and this is where you
  375. will usually want to concentrate. Also look for registered functions being
  376. disabled, and sometimes date expirations. The program could also be looking
  377. for a registration key.
  378.  
  379. In the case of commercial software what type of copy protection is used? Is it
  380. a doc check, or does the program want you to input a serial number before it
  381. will install itself? Once you see how and where the offending routines are
  382. implemented you can begin to develop an overall strategy on the best approach
  383. to circumvent them. It's also a good idea to read the docs, you can pick up a
  384. lot of useful info from doc files.
  385.  
  386. There are basically three categories that shareware programs fall into... They
  387. are begware, crippleware, and deadware.
  388.  
  389. The begware category is comprised of programs that have all the registered
  390. features enabled but every time you run them they will display screens that
  391. bug you to register. This is the easiest form of protection to remove and it's
  392. the type I'll go over in the walk through.
  393.  
  394. The crippleware category is comprised of programs that in the unregistered
  395. version have certain functions disabled, and maybe nag screens as well. This
  396. type of protection can be slightly more complex, but often times is just as
  397. easy to defeat as a simple nag screen.
  398.  
  399. The deadware category is comprised of programs that are totally stripped of
  400. the code for the registered features so there is really nothing to crack. A
  401. good example of this is DOOM by ID software. You can get the shareware version
  402. just about anywhere, however no matter how much you hack at it you cannot make
  403. it into the commercial version cause it only contains the code for the first
  404. episode.
  405.  
  406. Ok, you've run the program a few times and you know what you want to remove
  407. and have a general idea on where to concentrate your efforts. you also have
  408. run UNP on it and it's ready to debug. You load the program into the debugger
  409. and wonder what to do next...
  410.  
  411. Most forms of copy protection have one weak spot, and this is the spot you
  412. will concentrate on. They have to perform the protection check and then make a
  413. decision based on the results of that check. And that decision is usually a
  414. conditional jump. If the check was good the program will go in one direction,
  415. if it was bad it will go somewhere else.
  416.  
  417. Don't think that as soon as you spot a compare or conditional jump you've
  418. found the protection routine. These instructions are part of the 8088
  419. instruction set and all programs use them constantly for everything. What you
  420. want to do is to step through the code until something significant happens
  421. like a nag screen gets displayed, or a doc check comes up or the program tells
  422. you that the function you just tried to use is only available in the
  423. registered version. When you reach that point you can then start to evaluate
  424. what portion of code to begin studying.
  425.  
  426. Let's say you have a program that displays a nag screen and you want to remove
  427. it. You step through the program until the nag screen pops up, you now know
  428. the location of the instructions that are causing it to be displayed. So you
  429. reload the program and trace back to a point a few instructions before the
  430. call to the nag screen, and this is what you see:
  431.  
  432. 09D8:0140       CMP BYTE PTR [A76C],00
  433. 09D8:0145       JNZ  014B
  434. 09D8:0148       CALL 0C50
  435. 09D8:014B       MOV  AH,18
  436.  
  437. Now, let's assume that the memory location referenced by the first line of
  438. code does indeed contain 00 and that it is the default value placed in there
  439. by the programmer to indicate that the program is unregistered.
  440.  
  441. The first line of code is checking the value contained in the memory location
  442. to see if it is 00 or not. If the location does contain 00, the compare
  443. instruction will cause the Zero flag to be set. If the location contains any
  444. other value than 00, the Zero flag will be cleared.
  445.  
  446. The second line of code makes the decision on how to proceed based on the
  447. results of the compare instruction. The JNZ instruction will make the jump to
  448. the fourth line of code if the zero flag is cleared. This will bypass the call
  449. to the nag screen on the third line. If the zero flag is set, no jump will
  450. occur and the call will be made.
  451.  
  452. The third line of code contains the call to the nag screen. If it is executed
  453. the nag screen will be displayed. The fourth line of code is just the next
  454. instruction in the program.
  455.  
  456. Once you have found and analyzed this piece of code within the program, you
  457. can now decide on how to bypass the call on the third line. There is no single
  458. way to do this. I can think of a half dozen different ways to patch the
  459. program so it will not make the call. But there is a best way...
  460.  
  461. First, you could just replace the JNZ 014B with JMP 014B. This is an
  462. unconditional jump and it will bypass the call on the third line no matter
  463. what the memory location that the first line of code is referencing contains.
  464.  
  465. You could also change it to read JZ 014B so that the jump will be made if the
  466. location contains 00, and not the other way around. You could even change the
  467. CMP BYTE PTR [A76C],00 instruction to JMP 014B.
  468.  
  469. Or you could just NOP out the call on the third line altogether seeing as how
  470. it's a local call. By a local call I mean that the code contained within the
  471. call resides in the same code segment as the call instruction itself.
  472.  
  473. This is an intersegment call. You will see other calls that reference lines of
  474. code outside of the current code segment. These are intrasegment calls, and
  475. have to be handled differently. They will look something like CALL 0934:0AC5,
  476. or CALL FAR 0002. I'll go over how to handle intrasegment calls later on.
  477.  
  478. NOP is short for no op-code, and it is a valid instruction that the
  479. microprocessor understands. It is only one byte in length, and the call
  480. instruction is three bytes in length. So if you wanted to nop out the call
  481. instruction you would have to enter the NOP instruction three times in order
  482. to replace it. And if you replaced the CMP BYTE PTR [A76C],00 with JMP 014B,
  483. you would have to pad it out with a few nop's as well.
  484.  
  485. The compare instruction is 5 bytes and the jump instruction is only 2 bytes,
  486. so you would have to add 3 nops in order to equal the length of the original
  487. compare instruction. Otherwise you would throw off the address of every
  488. instruction after it in the program and end up with a bunch of unintelligible
  489. garbage. Not to mention a major system crash...
  490.  
  491. The NOP instruction is mainly used as a filler and when this instruction is
  492. encountered no operations will take place and the CS:IP will then be
  493. incremented to the next instruction to be executed. A lot of compilers leave
  494. nop's in the code all the time and it's a great instruction you can use to
  495. wipe out entire lines of code with. 
  496.  
  497. The above methods of bypassing the call are called 'dirty' cracks in that they
  498. have only modified the end result of the protection check and have done
  499. nothing to alter the actual protection check itself.
  500.  
  501. All the techniques I showed you above are only implemented after the check is
  502. made. They will bypass the nag screen, but what if the program also has
  503. registered features that are disabled or displays another nag screen upon
  504. exit? The above methods only remove the original nag screen and don't address
  505. the reason the screen is being displayed in the first place.
  506.  
  507. A much cleaner way to crack the above piece of code would modify the cause and
  508. not the effect. And could be written like this:
  509.  
  510.        original code                        new code
  511.  
  512. 09D8:0140  CMP BYTE PTR [A76C],00    09D8:0140  MOV BYTE PTR [A76C],01
  513. 09D8:0145  JNZ  014B                 09D8:0145  JMP  014B
  514. 09D8:0148  CALL 0C50                 09D8:0148  CALL 0C50
  515. 09D8:014B  MOV  AH,18                09D8:014B  MOV  AH,18
  516.                    
  517. Remember that the protection check is basing it's actions on the value
  518. contained in the memory location that the first line of code is checking. The
  519. original code displayed the nag screen if the value of that location was 00,
  520. meaning it was unregistered. So that means a value of 01 indicates a
  521. registered copy. It could be the other way around as well, it just depends on
  522. how the programmer worded the source code. But we know in this case that
  523. 00=false so 01=true. These are Boolean expressions and most compilers use the
  524. AX register to return these values.
  525.  
  526. By changing the first line from CMP BYT PTR [A76C],00 to MOV BYTE PTR
  527. [A76C],01 the program no longer performs the protection check. Instead, it
  528. places the correct value in the memory location to indicate a registered copy.
  529. Now if the program checks that memory location again later on it will think
  530. that it is registered and activate all of it's disabled features, or not
  531. display a second nag screen upon it's exit if it has one.
  532.  
  533. I changed the second line of code to an unconditional jump because the compare
  534. instruction on the first line no longer exists, and the conditional jump on
  535. the second line may still access the call to the nag screen on the third line
  536. if the Z flag was already set before the old compare instruction was
  537. encountered.
  538.  
  539. Don't think that all programs are this easy, they're not. I just
  540. over-simplified this example for instructional purposes. And I really wouldn't
  541. crack the code like that, although the last method should work fine for all
  542. registered features to be enabled. Remember I told you there was a best way to
  543. crack this?
  544.  
  545. What I would actually do is to trace further back into the program and find
  546. the line of code that sets up the memory location referenced by line one of
  547. the code for the protection check in the first place and modify it there. This
  548. is an example of a 'clean' crack.
  549.  
  550. I just did it in the above manner to try and show you the difference between
  551. clean and dirty cracks without totally confusing you. And to give you a
  552. general idea on how to creatively modify existing code.
  553.  
  554. If you are using soft ice as your debugger, an easy way to find the
  555. instruction that sets up the memory location for the protection check is to
  556. set a breakpoint on the location when it gets 00 written to it. The syntax
  557. would be BPM XXXX:XXXX W EQ 00, where XXXX:XXXX is the address of the memory
  558. location referenced by the compare instruction on line 1.
  559.  
  560. Now when the program wrote 00 to that memory location, soft ice will pop back
  561. up and the CS:IP will be sitting at the next instruction after the one that
  562. wrote 00 to the memory location. You will now be able to evaluate the code
  563. around the instruction that writes to the memory location and decide on how to
  564. proceed.
  565.  
  566. This also could just be a general purpose location that the program uses for
  567. generic references (especially if it's in the stack segment), and it could
  568. write 00 to it several times throughout the course of the program for a
  569. variety of functions. You should let the program run normally after soft ice
  570. broke in to see if it will trigger the breakpoint again. If it doesn't you
  571. know that the location is only used for the protection check. But if the
  572. breakpoint gets triggered several more times, you will have to figure out
  573. which set of instructions are being used to set up for the protection check
  574. before proceeding.
  575.  
  576. The above examples were based on shareware programs. Now I'll go over a few
  577. techniques to remove copy protection from commercial games that have doc
  578. checks in them as the methods are slightly different...
  579.  
  580. shareware programs are usually coded so that they check a variable in memory
  581. before deciding if they are registered or not and how to proceed, unless of
  582. course they are looking for a registration key. Commercial games with doc
  583. checks take a different approach as they check nothing before calling the copy
  584. protection. It always gets called every time you play the game no matter what.
  585. As a result, the doc check routine is usually easier to find, and there are
  586. basically two types of doc checks... The passive check, and the active check.
  587.  
  588. The passive doc check is easier to defeat than the active. In the passive doc
  589. check, the program will issue a call to the copy protection routine. And if it
  590. is unsuccessful will either abort the program, or loop back to the beginning
  591. of the routine and give you a few more tries before aborting. The entire
  592. protection routine will be included in a single call, so merely nopping out
  593. or bypassing the call will be sufficient to remove the copy protection.
  594.  
  595. A few good examples of this are Spear of Destiny by ID, and the Incredible
  596. Machine by Sierra. Yes I know that they are old, but if you happen to have a
  597. copy of either one laying around they are excellent examples of passive doc
  598. checks to practice on.
  599.  
  600. Look at the following piece of code:
  601.  
  602. 0277:01B5  MOV [AF56],AX
  603. 0277:01B8  PUSH BX
  604. 0277:01B9  PUSH CX
  605. 0277:01BA  CALL 0234
  606. 0277:01BD  POP CX
  607. 0277:01BE  POP BX
  608. 0277:01BF  JMP 0354
  609.  
  610. The first three lines of code are just setting up for the call, the call on
  611. the fourth line is the protection check itself. It will display the input
  612. window asking for a word from the manual, will perform the protection check,
  613. and will display an error message if you input the wrong word. It can also
  614. optionally give you a few more tries if you type in the wrong word.
  615.  
  616. If you fail the protection check, the program will abort without ever having
  617. returned from the call. The fifth, sixth, and seventh lines are the next
  618. instructions to be executed if the protection check was successful and the
  619. program returns from the call.
  620.  
  621. This type of protection is trivial to defeat, all you have to do is the
  622. following:
  623.  
  624.     original code                       new code
  625.  
  626. 0277:01B5  MOV [AF56],AX           0277:01B5  MOV [AF56],AX
  627. 0277:01B8  PUSH BX                 0277:01B8  PUSH BX
  628. 0277:01B9  PUSH CX                 0277:01B9  PUSH CX
  629. 0277:01BA  CALL 0234               0277:01BA  NOP
  630. 0277:01BD  POP CX                  0277:01BB  NOP
  631. 0277:01BE  POP BX                  0277:01BC  NOP
  632. 0277:01BF  JMP 0354                0277:01BD  POP CX
  633.                    0277:01BE  POP BX
  634.                    0277:01BF  JMP 0354
  635.  
  636. Simply nopping out the call to the protection routine will be sufficient to
  637. crack this type of doc check. No window asking for input will appear, and the
  638. program will continue on as if you had entered the correct word from the
  639. manual. Remember that I told you that the NOP instruction is only one byte in
  640. length, so you have to enter as many nop's as it takes to equal the length of
  641. the code you are modifying.
  642.  
  643. The active doc check is more complex. The program will issue the check and
  644. unlike the passive protection, will set a variable in memory somewhere and
  645. reference it later on in the program.
  646.  
  647. You can crack this type of protection somewhat using the methods for the
  648. passive check and it will run fine for a while. But if you didn't crack it
  649. right, later on when the next episode gets loaded or you reach a crucial point
  650. in the game, the program will reference a memory location and bring up the
  651. copy protection again, or abort. This type of protection is more akin to how
  652. most shareware programs operate and MUST be done with a CLEAN crack.
  653.  
  654. Look at the following piece of code:
  655.      
  656. 0234:0B54  MOV CX,0003     ;Sets up to give you three tries
  657. 0234:0B57  DEC CX          ;deducts one for every time through the loop
  658. 0234:0B58  JCXZ 031A       ;when CX=0000, program will abort
  659. 0234:0B60  PUSH CX         ;just setting up for the call
  660. 0234:0B61  PUSH DS         ; "                        "
  661. 0234:0B62  PUSH ES         ; "                        "
  662. 0234:0B63  CALL 035F:112D  ;call to input window and validation routine
  663. 0234:0B68  OR AL,AL        ;seeing if check was successful
  664. 0234:0B6A  JNZ 0B6E        ;yes, continue on with the program
  665. 0234:0B6C  JMP 0B57        ;no, set up for another try
  666. 0234:0B6E  CALL 8133       ;next line in the program if check was good
  667.  
  668. The above code is the outer loop of the protection routine. Look at the call
  669. on the seventh line and the compare instruction on the eighth line. When the
  670. call to the input routine or in the case of shareware, the check routine is
  671. paired with a compare instruction in this manner, You can bet that the program
  672. set a memory variable somewhere inside the call. Especially suspicious is the
  673. unconditional jump on line 10 that jumps backwards in the code.
  674.  
  675. This won't always be the case as no two programs are alike, and simply
  676. changing line one of the code from MOV CX,003 to JMP 0B6E to bypass the entire
  677. routine may allow the program to run just fine. Let's say that this is how you
  678. patched the program and it runs. Great, your work is done... But what if
  679. before the first level loads, or at some other point within the program the
  680. input window pops up again asking for a word from the manual?
  681.  
  682. You realize that you should have patched it right in the first place as you
  683. now have to go back in there and fix it. This is why so many groups have to
  684. release crack fixes, they patch the program in a half assed manner and don't
  685. even run it all the way through to see if it's going to work.
  686.  
  687. Ok, back to the problem at hand... The above method of patching the program
  688. didn't work, so you now have to load the program back into the debugger and
  689. trace into the call on line seven to see whats going on in there. And you
  690. can't NOP this kind of call out either, this is an intrasegment call.
  691.  
  692. Certain things in programs get assigned dynamic memory locations, and
  693. intrasegment calls are one of those things. When the program gets executed,
  694. the code segment, data segment, extra segment, and stack segment get assigned
  695. their respective addresses based on the memory map of your computer.
  696.  
  697. And when a program does a FAR call (a call to a segment of memory outside the
  698. current code segment), The program goes to the address that was assigned to
  699. that segment at run time. The CS, DS, ES, and SS will be different on every
  700. computer for the same program.
  701.  
  702. And seeing as how these addresses don't get assigned until run time, the
  703. actual bytes for the addresses of far calls don't exist in the program file as
  704. it resides on your disk. That's why you can't just NOP a CALL FAR instruction
  705. out. 
  706.  
  707. However, the bytes for calls that are within the same segment of code as the
  708. calling instructions themselves will be contained within the file as it
  709. resides on disk. And that is because even though the program doesn't get the
  710. addresses for the actual segments until run time, the offsets within those
  711. segments will always be the same.
  712.  
  713. Back to the example, let's say you've traced into the call on line seven and
  714. this is what you see:
  715.  
  716.  
  717. 035F:112D   MOV   [324F],BX            ;
  718. 035F:1131   CMP   BYTE PTR [BX+06],03  ; just some error checking
  719. 035F:1135   JNZ   0339                 ;
  720.  
  721. 035F:1137   CALL  F157                 ; call to the input window that
  722.                        ; asks you to type a word in from
  723.                        ;the manual
  724.                     
  725. 035F:113A   MOV   DI,[0332]            ; this routine is comparing the
  726. 035F:113D   MOV   ES,DX                ; word you typed in to a word
  727. 035F:1140   MOV   DS,BX                ; in memory that the program is
  728. 035F:1144   MOV   SI,[0144]            ; referencing. As long as the
  729. 035F:1148   MOV   CX,[0097]            ; bytes match the loop will
  730. 035F:114C   REPE  CMPSB                ; continue.
  731.  
  732. 035F:114F   JCXZ  1154                 ; This is the routine that sets
  733. 035F:1151   JMP   1161                 ; the memory variable. 01 will be
  734. 035F:1154   MOV   AX,0001              ; placed in it if you typed in
  735. 035F:1159   MOV   [0978],AX            ; the correct word. 00 will be
  736. 035F:115E   JMP   116B                 ; placed in it if you typed in
  737. 035F:1161   MOV   AX,0000              ; the wrong word.
  738. 035F:1166   MOV   [0978],AX            ;
  739.  
  740. 035F:116B   POP   ES                   ; setup to return from call
  741. 035F:116C   POP   DS                   ;  "                     "
  742. 035F:116D   POP   CX                   ;  "                     "
  743. 035F:116E   RETF                       ; return from call
  744.  
  745.  
  746. Again, this code is over simplified as I figured all of the code would be
  747. overwhelming and really is not needed to get my point across. And as I've
  748. stated before, every program will be different anyway, so the actual code
  749. wouldn't help you. Instead, I want to give you a general overview on what to
  750. look out for.
  751.  
  752. So, what do you think is the best way to patch the above piece of code? Take a
  753. few minutes to study the code and formulate some ideas before reading on. Then
  754. compare your methods to mine. And remember, as with any code there is no
  755. single way. But as always, there is a best way... I'll go over few of them one
  756. at a time, starting with the dirtiest and finishing up with the cleanest.
  757.  
  758. The dirtiest crack for this piece of code also happens to be the method you
  759. will use to nop out intrasegment calls. It really isn't nopping out, but
  760. seeing as how you can't nop it out, just let the program make the call and
  761. change the first line of the code within the call to RETF. This will return
  762. from the call without ever having executed any of the code contained within
  763. it.
  764.  
  765. In the case of registers needing to be restored as in the above code, change
  766. the first line of code to jump to the part of the routine that restores the
  767. registers for the return. However, in the above example if you use this method
  768. and just return from the call without executing any of the code, you will also
  769. have to patch the outer loop as well.
  770.  
  771. Remember that this call only displays the input window and sets the memory
  772. variable. The outer loop of the routine makes the decision on how to proceed
  773. based on the results of the call.
  774.  
  775. To do this, you would change line one of the call from MOV [324F],BX to JMP
  776. 116B. This will restore the registers and return from the call without ever
  777. having executed any of the code within the call. But seeing as none of the
  778. code got executed, you'll have to patch line 9 of the outer loop from JNZ 0B6E
  779. to JMP 0B6E as you now need an unconditional jump to force the program to
  780. continue. This doesn't address the problem of the memory variable though, and
  781. the program won't be completely cracked. That's why if you did it like this
  782. you would end up releasing a fix.
  783.  
  784. A cleaner crack would be to change line 11 of the call from JCXZ 1154 to JMP
  785. 1154. Now when the window pops up and asks for a word, it will set the correct
  786. memory variable and the program will run no matter what word you type in. This
  787. method is still not desirable because the end user will get the input window
  788. and have to type something every time they play the game.
  789.  
  790. The cleanest way to crack this, and the way I would do it is to change line 4
  791. of the call from CALL F157 to JMP 1154. This method will totally bypass the
  792. input window, place the correct variable in memory and return from the call
  793. without the end user ever having seen even a hint of copy protection.
  794.  
  795. With this method, the outer loop does not need to be patched cause the program
  796. now thinks that it displayed the input window and the correct word was typed
  797. in. Now when the program checks that memory variable later on, it will think
  798. that you successfully passed the original check and skip the second protection
  799. check.
  800.  
  801. There is also an added benefit to the last method... Some games will bring up
  802. the protection check between each and every level of the game even though you
  803. type the correct word in every time. But if you've completely killed the
  804. routine as in the last example, you'll never be bothered by it again no matter
  805. how many times the program tries to bring it up.
  806.  
  807. Before we move onto the walk though, there is one other technique I want to go
  808. over with you. And that is how to get out of a loop. You will get stuck in
  809. loops constantly during the course of debugging a program and knowing how to
  810. get out of them will save you a lot of time and frustration. You will find
  811. that programs contain loops within loops within loops etc... Some loops can
  812. execute hundreds of times before the program will advance, especially ones
  813. that draw screens.
  814.  
  815. When you realize that you are stuck in a loop, execute the loop several times
  816. and keep an eye on the highest address the loop reaches before jumping
  817. backwards within the code. Once you have found the end of the loop, write down
  818. the address of the jump that re-executes the loop, and then look for
  819. conditional jumps inside the loop that will put you past the address of that
  820. backwards jump. You will want to set a breakpoint on the address this
  821. instruction jumps to and then let the program run normally. The HERE KEY is
  822. excellent for this type of situation.
  823.  
  824. If you guessed right, control will be returned to the debugger when the
  825. program reaches that address. If you guessed wrong, you will lose control of
  826. the program and will have reload it and try again. This is where writing down
  827. the address comes in handy, just reload the program and then issue the GO TO
  828. command and supply it the address of the backwards jump that you wrote down.
  829.  
  830. The program will run until it reaches that address and control will then be
  831. returned to the debugger. This will save you from having to trace all the way
  832. through the code again in order to reach the point where you lost control of
  833. the program in the first place. You could just use sticky breakpoints instead,
  834. but what you will end up with is a half dozen or so breakpoints in as many
  835. different locations in the code, and it's very easy to loose track as to which
  836. breakpoint is which.
  837.  
  838. That's why I use non-sticky breakpoints and write down the address I'm
  839. currently at before executing suspicious looking calls and jumps. My desk is
  840. usually scattered with scraps of paper filled with notes and addresses. I only
  841. use sticky breakpoints for specific situations. It's much easier to just
  842. reload the program and use the GO TO command to get back to the point in the
  843. program where I lost control.
  844.  
  845.  
  846.  
  847.  
  848. CHAPTER 4   WALK THROUGH OF AN EASY CRACK
  849. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  850.  
  851. First of all, I want to go over some of the criteria I used in choosing the
  852. program I used for the walk through. An important factor was the programs
  853. size. I want to keep this manual as small as possible, and I chose the program
  854. that is included in this guide because among other things it is the smallest
  855. one I could find that best illustrated the example of a simple nag screen.
  856.  
  857. Whether or not the program was one that you would actually find useful was not
  858. a consideration, as you should eventually be able to crack just about any
  859. program you wish if your serious about cracking. If you come across a program
  860. that has you stumped, leave it alone for a while and then try again after
  861. you've cracked something else. You may find that whatever you were having
  862. problems with is now easier to understand.
  863.  
  864. Before we start I want to go over one other thing. When you load a program
  865. into a debugger, the debugger will load the program and halt at the very first
  866. instruction to be executed within the program. You can also at this point let
  867. the program run normally and then break back into it at a later point.
  868.  
  869. When you use the second method it will halt the program at the current
  870. instruction and return control to the debugger, but you may not end up in the
  871. program itself. You could have broken into the program while it was in the
  872. middle of executing either a DOS or BIOS interrupt, and the code you are in
  873. belongs to either DOS or BIOS and not the program you are debugging.
  874.  
  875. You can tell by looking at the addresses of the instructions in the code
  876. window where you are, low segment addresses indicate you are in DOS, and
  877. addresses that start with FXXX indicate a BIOS routine.
  878.  
  879. If you break into the program while it is in one of these interrupt routines
  880. you will have to trace your way back into the programs code, this will usually
  881. be indicated by an IRET (interrupt return) instruction. When you do get back
  882. to the program code, you will then have to trace your way back to the top of
  883. the call that issued the interrupt you broke into. Then you may also have to
  884. trace back to the top of that call, and to the top of that call, etc etc,
  885. until you reach the top level of the program. After you've done this a few
  886. times you'll begin to recognize when you've gotten back to the main flow of
  887. the program...
  888.  
  889. On the other hand, when you load a program into the debugger and begin
  890. stepping through the code from the very first instruction to be executed
  891. within the program, you have the best picture on the overall flow of the
  892. program as you are sitting on top of everything.
  893.  
  894. But some programs don't access the copy protection until they are further
  895. along in the code. In this case, it's best to let the program run normally and
  896. then break into it at a later point. Otherwise, you will have a ton of code to
  897. trace through before the protection routine is accessed, and this can become
  898. quite tedious. Which method you choose will be determined after you've run the
  899. program through a few times and decide how and where you want to break into
  900. it.
  901.  
  902. One last thing, DOS will always load a program into the same memory range
  903. provided that no other programs are run in the interim. It's important that
  904. you always boot with the same config files and don't run any other memory
  905. resident programs between cracking sessions.
  906.  
  907. If you load a program into the debugger and start tracing, then quit. And
  908. before The next time you load that program into the debugger, you boot with a
  909. different config or load a memory resident program that you didn't have loaded
  910. the first time you started cracking that program, the segment addresses will
  911. change and the addresses you wrote down will be useless.
  912.  
  913. This is because the memory map of your computer will change. Every time you
  914. start the debugger, use the same config files and don't load anything that
  915. wasn't loaded the first time you started the debugger.
  916.  
  917. When I boot with my debugging config, the only things I load are a mouse
  918. driver, 4DOS, my debugger and ansi.sys (needed for cracking bbs doors). This
  919. way I'm assured that the program I want to crack gets loaded into the same
  920. memory region every time I run it, providing I don't run any other memory
  921. resident programs before loading the program to be cracked into the debugger.
  922.  
  923. Take soft ice as an example, if you load a program into it using LDR.EXE and
  924. begin debugging, then later on you decide to just execute the program and
  925. break into it without first loading it with LDR.EXE, the segment addresses
  926. will change. That's because LDR.EXE is a program and using it will throw the
  927. segment addresses off by one word as opposed to just breaking into an already
  928. running program without first loading it with LDR.EXE.
  929.  
  930. The program we will crack is budget minder, it is an extremely simple crack
  931. (it took me about 2 minutes to crack it) and is ideal for the lesson on how to
  932. remove nag screens from otherwise fully functional programs. It also deals
  933. with intrasegment calls, so it serves a dual purpose. That's another reason I
  934. chose it for the lesson.
  935.  
  936. From now on, when I say step, step through, or step over, I want you to use
  937. the SINGLE STEP key. When I say trace, I want you to use the TRACE key once
  938. and only once!!!! The TRACE key is a highly specialized key and is not
  939. intended to be used multiple times like the SINGLE STEP key. If you don't
  940. follow these instructions, your gonna get lost...
  941.          
  942. OK, once you've run budget minder a few times you will notice that it displays
  943. a nag screen before the main program is executed. You will also notice that
  944. this nag screen is the only type of protection that the program has. It
  945. doesn't contain any features that are disabled, nor does it display an
  946. additional nag screen upon exit.
  947.  
  948. It's okay to apply a dirty crack to this program as all you want to do is kill
  949. the nag screen, so you have a little more leeway on how to patch it. And if
  950. you want to try different methods of patching it than the ones I give, it
  951. should still work fine.
  952.  
  953. That was the most important factor in my decision to use this program for the
  954. lesson. I wanted to walk you through a program so you would become comfortable
  955. with it's flow, and I also wanted the program to be easy enough so that once
  956. you became familiar with it, there was enough room for you to experiment and
  957. try out your own methods.
  958.  
  959. In this case, it's best to load the program into the debugger and start
  960. stepping through it right away. The protection is implemented very close to
  961. the beginning of the program, and this method of loading the program will put
  962. you right on top of everything.
  963.  
  964. Allowing the program to run and breaking into it later on will not serve any
  965. useful purpose. You'll just end up having to trace your way back to the top.
  966. Besides, the nag screen comes up so fast you'll probably miss it if you try
  967. the second method anyway.
  968.  
  969. Before you load it into the debugger, run UNP on BUDGET.EXE... AHA! The file
  970. was compressed with EXEPACK. It's now ready to debug as you've removed the
  971. compression envelope. Just for the hell of it, run UNP on it again. I've come
  972. across a few programs that have had multiple compression routines on them. If
  973. it shows up negative, your set to go.
  974.  
  975. Now load BUDGET.EXE into the debugger, the program will be sitting at the
  976. first instruction to be executed awaiting your next command... Use the SINGLE
  977. STEP key to start stepping through the code and keep an eye on the
  978. instructions as you are stepping through them.
  979.  
  980. Shortly you will come to a couple of calls, before you step over the first
  981. one, write down it's address. Now step over the first call with the SINGLE
  982. STEP key. Nothing happened, so you have to continue stepping through the code.
  983. But if something did happen when you stepped over this call like the nag
  984. screen being displayed or if you lost control of the program, you could just
  985. reload the program and issue the GO TO command to get back to that point using
  986. the address you wrote down.
  987.  
  988. Step over the second call, nothing again. Ok, keep stepping through the code
  989. and keep an eye on the instructions. You will encounter a third call about 6
  990. instructions or so after the second call, step over it with the SINGLE STEP
  991. key... Bingo, you have found the call to the nag screen. Hit a key to exit the
  992. nag screen and you will now be sitting in the main program screen.
  993.  
  994. But you no longer have control of the program. Remember I said you would loose
  995. control if you step over a call loop or interrupt and the program never
  996. returns from it? Hopefully you wrote down the address of that last call before
  997. you executed it. Now you can just quit out of the program and reload it. Then,
  998. once it's reloaded, issue the GO TO command to get back to the call without
  999. having to trace your way back there. So go ahead and do this before reading
  1000. on...
  1001.  
  1002. Ok, we are all back at the third call. It's address will be CS:0161, remember
  1003. that the segment adresses will always be different for every computer, but the
  1004. offsets will be the same. So from now on I'll write the addresses in that
  1005. manner...
  1006.  
  1007. We know that the last time we executed this call, the program never returned
  1008. from it. So now we are going to have to trace into it for a closer look. Trace
  1009. into the call with the TRACE key, don't use the SINGLE STEP key this time or
  1010. you'll loose control again.
  1011.  
  1012. You will now be inside the code for that call, start stepping through it again
  1013. with the SINGLE STEP key, you will see some calls. Better write down your
  1014. address before you step over them.
  1015.  
  1016. Step over the first two calls, nothing... Use the RESTORE USER SCREEN key to
  1017. toggle the display between the debugger and the program. Still a blank screen,
  1018. so nothing important has happened yet. Now toggle the RESTORE USER SCREEN key
  1019. to get the debugger screen back and continue stepping through the code.
  1020.  
  1021. You will see another call and some more code, just step through them until you
  1022. reach the RETF instruction and stop there. Toggle the display with the RESTORE
  1023. USER SCREEN key, the screen is still blank...
  1024.  
  1025. But we executed all of the code within the call and are ready to return
  1026. without anything happening. The nag screen didn't get displayed nor did we
  1027. loose control and end up in the main program, How come?
  1028.  
  1029. Step over the RETF instruction with the SINGLE STEP key and you'll see why...
  1030. The address that we return to is not the next instruction after the original
  1031. call. Part of the code within the call we traced into revectored the return
  1032. address for the original call and sent us to an entirely different location
  1033. within the program.
  1034.  
  1035. This is why we lost control when we first stepped over the call, the debugger
  1036. was expecting the program to return to the next instruction after the original
  1037. call, but it never did...
  1038.  
  1039. So the instruction that we returned to was not the original line of code that
  1040. was expected, instead we are at another far call. If you haven't gotten lost
  1041. you should be at CS:0030  CALL CS:28BC.
  1042.  
  1043. Write down the address of the CS:IP and then step over this call with the
  1044. SINGLE STEP key, there is that annoying nag screen again. Hit a key to exit
  1045. the nag screen and control will be returned to the debugger. This time the
  1046. program returned from the call and you are in control again. So you now know
  1047. that this call is the one that displays the nag screen and it is the one you
  1048. want to kill.
  1049.  
  1050. Hit the RUN key and let the program run, now quit out of it from the main
  1051. program screen and reload it into the debugger. Use the GO TO command and
  1052. supply it the address for the call to the nag screen.
  1053.  
  1054. Ok, now lets see if the program will run or not if we don't execute the call
  1055. to the nag screen. The call is at CS:0030 and the next instruction after the
  1056. call is at address CS:0035... A quick way to jump past this call without
  1057. executing it is to just increment the instruction pointer register to the next
  1058. instruction.
  1059.  
  1060. In this case we want to manipulate the IP register, and we want to set it to
  1061. point to the instruction at CS:0035 instead of the instruction it is currently
  1062. pointing to at CS:0030. You are going to have to figure out the command on how
  1063. to do this with the debugger you are using yourself.
  1064.  
  1065. If you are using turbo debugger, place the mouse cursor on the line of code at
  1066. CS:0035 and right click the mouse. A window will pop up, then left click on
  1067. new IP, or increment IP. If you are using soft ice, type rip=0035 and hit
  1068. enter. Any other debugger, I have no clue...
  1069.  
  1070. Now that we've moved the IP past the call to the nag screen let's see if the
  1071. program is going to run. Hit the RUN key, hot damn! The nag screen doesn't
  1072. come up, instead you are brought right into the main program.
  1073.  
  1074. It looks like getting rid of that call is going to do the trick. Now that we
  1075. know the program will run without making that call, it's time to decide on how
  1076. to patch the program so the call is never made again.
  1077.  
  1078. Think back to the original call we traced into for a minute, that call was the
  1079. one that revectored the return address and brought us to the call to the nag
  1080. screen. Therefore, it's reasonable to assume that that call is the protection
  1081. check, and it might be a good idea to have another look at it.
  1082.  
  1083. Before we do that there is one other thing I want to show you, and that's how
  1084. to allow the program to make the call to the nag screen and return from the
  1085. call without executing any of the code contained within it.
  1086.  
  1087. This isn't the method we will use to patch this program, but it's an important
  1088. concept to grasp as you'll end up doing it sooner or later on some other
  1089. program anyway. Remember that this is a far call and you can't just nop it
  1090. out.
  1091.  
  1092. Quit the program, reload it, and get to the address of the call to the nag
  1093. screen. Last time through we just incremented the IP to bypass it. Now we will
  1094. trace into it to see what it is doing.
  1095.  
  1096. Hit the TRACE key and trace into the call. Now start stepping through it with
  1097. the SINGLE STEP key, don't bother writing any addresses down for now. There
  1098. are several dozen calls in this routine along with shitloads of other code.
  1099.  
  1100. Toggle the display with the RESTORE USER SCREEN key after you step over a few
  1101. of the calls and you will see that the program is in the process of drawing
  1102. the nag screen.
  1103.  
  1104. Keep stepping through it and you'll see more and more of the screen being
  1105. drawn as the code progresses. This is getting boring, so stop stepping through
  1106. the code and start scrolling the code window down with the down arrow key and
  1107. watch the code.
  1108.  
  1109. What you are looking for is the RETF instruction as this is the end of the
  1110. call. Keep scrolling, I told you this call had a ton of code in it. When you
  1111. do find the RETF instruction write down it's address, it is CS:2B0E in case
  1112. your having trouble finding it. Ok, you've got the address of the RETF far
  1113. instruction written down so now just let the program run, quit out of it,
  1114. reload it, and get back to the call for the nag screen.
  1115.  
  1116. You should now be sitting at the call to the nag screen, trace into it and
  1117. stop. The first instruction of the call is MOV CX,0016 and this is where the
  1118. CS:IP should be pointing to. What we want to do now is to jump to the RETF
  1119. instruction and bypass all of the code within the call itself. So let's
  1120. re-assemble the MOV CX,0016 instruction and replace it with a new one.
  1121.  
  1122. First, make sure you are at this instruction, if you've traced passed it your
  1123. gonna have to reload the program and get back to it... OK, we are all sitting
  1124. at the MOV CX,0016 instruction and it's address is contained in the CS:IP
  1125. registers.
  1126.  
  1127. Now ASSEMBLE JMP 2B0E (the offset address of the RETF instruction) and specify
  1128. the address of the CS:IP. The MOV CX,0016 instruction will be replaced with
  1129. JMP 2B0E. And seeing as how both of these instructions are the same length we
  1130. didn't have to pad it out with any nop's.
  1131.  
  1132. Now hit the RUN key, you are brought into the main program and the nag screen
  1133. didn't get displayed! We allowed the program to make the call, but we didn't
  1134. allow any of the code within the call to be executed. And as far as the
  1135. program is concerned, it made the call and the nag screen was displayed.
  1136.  
  1137. Now let's go back and take another look at the call that we suspect is the one
  1138. that contains the protection check itself. Reload the program and go to the
  1139. original call that revectored the return address, now trace into it. I've
  1140. traced into the calls that are contained in here and they are setting up the
  1141. addresses for the RETF instruction at the end of this call among other things.
  1142. You don't need to trace into them as you might not understand what's going on,
  1143. but if you feel up to it, go right ahead.
  1144.  
  1145. What I want to concentrate on are the last four lines of code in the call as
  1146. they are the ones that finally set up the address to return to. Step through
  1147. the code until you are at CS:00A8 and take a look:
  1148.  
  1149. CS:00A8  8B04    MOV AX,[SI]         DS:SI=0000
  1150. CS:00AA  053000  ADD AX,0030
  1151. CS:00AD  50      PUSH AX
  1152. CS:00AE  CB      RETF
  1153.  
  1154. The first instruction is loading the AX register with the contents of the
  1155. memory location that the SI register is pointing to. And you can see by
  1156. looking at the memory location that the DS:SI pair is pointing to that it
  1157. contains 0000. (this is where the display command and data window come in
  1158. handy).
  1159.  
  1160. The second instruction is adding 0030 to the contents of the AX register.
  1161.  
  1162. The third instruction is placing the contents of the AX register onto the top
  1163. of the stack.
  1164.  
  1165. The fourth instruction is returning from the call, and where do you think that
  1166. the RETF instruction gets the address for the return? Yep, you guessed it, it
  1167. gets it off the top of the stack. Funny that the instruction right before it
  1168. just placed something there isn't it?
  1169.  
  1170. Also funny is that it happens to be the address of the nag screen. Look at
  1171. what is being added to the AX register on the second line of code. Boy that
  1172. sure looks like the offset address to the nag screen to me. Well, we are about
  1173. to cut the comedy and kill the bitch.
  1174.  
  1175. Remember that the next instruction after the nag screen is CS:0035, now look
  1176. at the first line of code. The contents of the memory location it's
  1177. referencing contains 0000, and I'll bet that if your copy was registered it
  1178. would contain 0005 instead.
  1179.  
  1180. Why? because if the first instruction placed 0005 in the AX register, when the
  1181. second line of code added 0030 to it, you would end up with 0035 which happens
  1182. to be the address of the next line of code after the nag screen.
  1183.  
  1184. Then the third instruction would place 0035 on the stack and that is where the
  1185. RETF instruction would go to. If this were the case, the nag screen would
  1186. never get displayed... Cool huh?
  1187.  
  1188. Well, what do you think we should do? We could trace further back in the
  1189. program and try to find the instruction that places 0000 in that memory
  1190. location and modify it to place 0005 in there instead, but this process is
  1191. somewhat involved and I don't want to throw too much at you at once. 
  1192.  
  1193. Instead, I have an easier solution. Seeing as how the memory location will
  1194. always contain 0000, why don't we just change the ADD AX,0030 instruction to
  1195. ADD AX,0035? This should get the correct address placed on the stack for the
  1196. RETF instruction to bypass the nag screen...
  1197.  
  1198. Let's try it and see how it works. SINGLE STEP through the code until the
  1199. CS:IP is at the instruction ADD AX,0030. Now, ASSEMBLE the instruction to read
  1200. ADD AX,0035 and hit the RUN key. We are placed in the main program screen
  1201. without any stinkin' nag screen getting displayed!
  1202.  
  1203. Congratulations! you have just cracked your first program :) Try other methods
  1204. of patching the program besides the ones I went over. The next chapter will
  1205. deal with how to make the changes you've made permanent.
  1206.  
  1207.  
  1208.  
  1209. CHAPTER 5     HOW TO USE THE DISK EDITOR
  1210. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1211.  
  1212. Ok, we cracked budget.exe in the debugger and know it's going to work. Now we
  1213. need to make those changes permanent. The first thing we have to do before we
  1214. load the file into the disk editor is to create a search string.
  1215.  
  1216. So we are going to have to reload budget.exe into the debugger and trace back
  1217. to the location where we want to make the patch in order to get the hex bytes
  1218. of the instructions we want to search the disk file for.
  1219.  
  1220. Load budget.exe back into the debugger and trace back to the last four
  1221. instructions of the original call that revectored the return address. You
  1222. should be looking at this:
  1223.  
  1224. CS:00A8  8B04    MOV AX,[SI]
  1225. CS:00AA  053000  ADD AX,0030
  1226. CS:00AD  50      PUSH AX
  1227. CS:00AE  CB      RETF
  1228.  
  1229. The group of numbers to the right of the addresses are the hexadecimal
  1230. representations of the mnemonic instructions. These are the bytes that we will
  1231. use for our search string. So write them down beginning from top left to
  1232. bottom right so you end up with this:  8B0405300050CB
  1233.  
  1234. This is the byte pattern that we will search for when we load the file into
  1235. the disk editor. We have a search string, but we also need to make a patch
  1236. string as well. In order to do this, we will have to assemble the new
  1237. instructions in memory, and then write down the changes we've made to the
  1238. code.
  1239.  
  1240. So ASSEMBLE ADD AX,35 and specify the address for the old ADD AX,0030
  1241. instruction. The new code should look like this:
  1242.  
  1243. CS:00A8  8B04    MOV AX,[SI]
  1244. CS:00AA  053500  ADD AX,0035
  1245. CS:00AD  50      PUSH AX
  1246. CS:00AE  CB      RETF
  1247.  
  1248. Notice that we only re-assembled the second line of code and that is the only
  1249. difference between the new code and the original code. So what I want you to
  1250. do is to write down the changes under the old code it replaced so it looks
  1251. like this:
  1252.  
  1253.    8B0405300050CB   <-- search string
  1254.       ^
  1255.       5         <-- patch string
  1256.  
  1257. Now we are all set to load the file into the disk editor. We have a string to
  1258. search for and another one to replace it with. Load budget.exe into your disk
  1259. editor, select the search function, and input the search string.
  1260.  
  1261. NOTE: some disk editors default to an ASCII search so you may have to toggle
  1262. this to hex search instead. If your in the wrong mode, the disk editor will
  1263. not find the byte pattern your looking for.
  1264.  
  1265. Once the disk editor finds the byte pattern of the search string, just replace
  1266. the bytes of the old code with the bytes to the new code and save it to disk.
  1267. The program is now permanently cracked.
  1268.  
  1269. Sometimes however, the code you want to patch is generic enough that the
  1270. search string will pop up in several different locations throughout the file.
  1271. It's always a good idea to keep searching for the byte pattern after you've
  1272. found the first match. If the disk editor doesn't find any more matches your
  1273. all set.
  1274.  
  1275. If the string you are searching for is contained in more than one location and
  1276. you patch the wrong one the crack will not work, or you will end up with a
  1277. system crash when you run the program. In this case, you'll have to reload the
  1278. program back into the debugger and create a more unique search string by
  1279. including more instructions around the patch site in the search string.
  1280.  
  1281. One last thing, you cannot include instructions that reference dynamic memory
  1282. locations in the search string. These bytes are not contained in the disk
  1283. file. So keep this in mind when you are creating your search strings...
  1284.  
  1285. And the protection might not be included in the main executable either. If you
  1286. cannot find the search string in the main exe file, load the other program
  1287. files into the disk editor and search them as well, especially overlay files.
  1288. Fortunately for you, I've included a tool to help you do this.
  1289.  
  1290.  
  1291.  
  1292.  
  1293. CHAPTER 6    OTHER CRACKING TOOLS
  1294. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1295.  
  1296.  
  1297. In addtion to UNP, there are several other tools that you can utilize to make
  1298. your job easier. These tools were not designed with the cracker in mind, but
  1299. they can be adapted to serve our purposes rather than the ones which they were
  1300. written for.
  1301.  
  1302. UNP and other programs like it were written to remove the compression
  1303. envelopes from exectables so you would be able to scan those files with a
  1304. virus scanner among other things. If someone were to attach a virus to an exe
  1305. file and then compress it, the file for all intents and purposes would be
  1306. encrypted. Now when you downloaded that file and ran your virus scanner on it,
  1307. it might not find the virus.
  1308.  
  1309. But crackers found a different use for these types of programs. We use them to
  1310. remove the compression envelope so that we can find the byte strings we want
  1311. to search the files for. I'm sure most of the programmers who wrote these
  1312. programs never intended them for this purpose. There are some out there though
  1313. that were written by crackers with this exact purpose in mind.
  1314.  
  1315. Don't just rely on UNP as your only program to do this. No one program will be
  1316. able to remove evrything you come across. It's a good idea to start collecting
  1317. these types of programs so you have more than one alternative if you come
  1318. across a compressed file, and your favorite expander doesn't understand the
  1319. routines. Be aware though that some programs are actually encrypted and not
  1320. compressed. In this case the expander programs will prove useless.
  1321.  
  1322. Your only recourse in this instance is to reverse engineer the decryption
  1323. routine while the program is decrypting to memory, and modify your search
  1324. string to search for the encrypted version of the bytes. Or you could write a
  1325. tsr patcher that impliments your patch after the program is decrypted to
  1326. memory.
  1327.  
  1328. There is another category of programs you can adapt to your use and they work
  1329. in conjunction with the file expanders. These types of programs will scan
  1330. entire directories of files and pop up a window that displays which files are
  1331. compressed and what they are compressed with. They won't remove the
  1332. compression routines from the files themselves, but will only inform you which
  1333. files are compressed and which are not. UNP also includes a command line
  1334. switch to do this...
  1335.  
  1336. Now instead of blindly running UNP on several different program files to see
  1337. if they are compressed or not, you can see at a glance if you even need to run
  1338. it at all. And if you do, you'll know exactly which files to run it on. This
  1339. is another time saving type of program and there are several out there, you
  1340. just have to look for them.
  1341.  
  1342. Another type of program that you will find useful will scan entire
  1343. disks/directories/subdirectories of files for specific hex or ascii byte
  1344. patterns contained within those files, and this is the purpose of the second
  1345. uuencoded cracking tool contained in this guide.
  1346.  
  1347. One method I use to determine if a shareware program is registerable or not
  1348. before actually loading it into the debugger is to use this tool.
  1349.  
  1350. I usually will have it scan all the programs files and input the string REG.
  1351. This will show all files that contain the string unREGistered and REGistered.
  1352. If it returns a string that contains REGistered in a file other than the doc
  1353. files, I know the program can be made into the registered version. This is
  1354. just a quick check I do on programs that have certain features diabled to
  1355. determine if the program does contain the code for the registered version.
  1356.  
  1357. An added feature of this program is that after you've cracked a program and
  1358. have a byte string to search for, you can run this program in hex mode and
  1359. input your search string. Now it will search all of the programs files and
  1360. return the name of the file that contains your search string, then you can
  1361. just load that file into the disk editor and make the patch.
  1362.  
  1363. It will also let you know if your search string is contained in more than one
  1364. location within the file. Remember, if this is the case you'll have to reload
  1365. the program back into the debugger and create a larger search string by
  1366. including more instructions around the patch site.
  1367.  
  1368. The programs name is SS303 and it's very easy to use, just read the docs for
  1369. it...
  1370.  
  1371. These are the programs I use as cracking tools, I'm sure that there are more
  1372. types of programs that can be adapted for cracking purposes out there, I've
  1373. just not found a use for them yet. If you come across anything useful drop me
  1374. a note at an575063@anon.penet.fi.
  1375.  
  1376.  
  1377.  
  1378. CHAPTER 7   SOURCE CODE TO A SIMPLE BYTE PATCHER
  1379. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1380.  
  1381. As I've stated in the overview chapter, if you want to distribute your patches
  1382. you are going to have to write a patcher program. Simply releasing the patched
  1383. version of the program file is not desirable. For one thing it's illegal,
  1384. another consideration is size. Some files you patch will be 300K or more, and
  1385. this is quite a large crack to release. The patcher program included in this
  1386. guide is much much smaller, it will assemble to about 600 bytes or so,
  1387. depending on the size of your logo.
  1388.             
  1389. And what if you want the end user to be able to register the program in their
  1390. own name? A patched .exe or .ovr file will not allow this.
  1391.  
  1392. When you release a patch that you yourself wrote, you are not breaking any
  1393. laws. The program was written by you and is your intellectual property to do
  1394. with as you see fit, including making it available for public use. The person
  1395. breaking the law is the end user who will use it to illegally modify someone
  1396. elses intellectual property contrary to the licencing terms they agreed to
  1397. when they installed the program. Remember, it's not illegal to write and
  1398. distribute a crack, but it is illegal to apply a crack.
  1399.  
  1400. That's why all of the programs I've included in this guide are shareware
  1401. programs in the original archives as released by the authors and have not been
  1402. tampered with in any way. I'm not about to release a modified version of
  1403. someone elses copyrighted property. The only thing I am doing is supplying you
  1404. with the original archive and the information on how to modify it if you wish,
  1405. this is not illegal. If you decide to take the program and modify it that's
  1406. your problem, not mine...
  1407.  
  1408. This patcher routine is very simple, I wrote it about 5 years ago and it was
  1409. my very first patcher program. It is a brute force patcher in that it will not
  1410. do any error checking and blindly patch the program you specify with the byte
  1411. pattern you supply. This method has it's advantages and disavantages.
  1412.  
  1413. The disadvantage to this method is that seeing how the program does not
  1414. perform any error checking it will patch the file specified with the
  1415. replacement string even if it's not the correct version of the program. If the
  1416. filename is the same, the patch will be applied.
  1417.  
  1418. Let's say you crack a program called Ultimate Menu and the version number is
  1419. 1.0, and the file you patch is called menu.exe. Now let's say a little while
  1420. later version 1.5 of the program comes out and someone who has your patch for
  1421. version 1.0 decides to run it on version 1.5 of the program.
  1422.  
  1423. This byte patcher will not check the new menu.exe for any changes before
  1424. making the patch, it will just patch the program in the location you specified
  1425. with the string you supplied even if the code you want to change is no longer
  1426. there. This could very well be the case if the programmer has significantly
  1427. re-written the code between versions, and what will end up happening is the
  1428. file will be corrupted and probably crash the system when it is run.
  1429.  
  1430. But this is also the advantage of my byte patcher. If the code to be replaced
  1431. is still in the same location in the new version, you'll not have to release a
  1432. new crack for each version of the program. Bear in mind that when I wrote this
  1433. program I was just starting out and didn't consider these possibilities. The
  1434. reason I included it in this guide was to give you an idea on how to write
  1435. your own patcher or to modify this one to suit your own purposes.
  1436.  
  1437. The patcher program that I use now is extremely complex and would just confuse
  1438. the hell out of you. Basically what I do is to make a backup of the original
  1439. file I am going to patch and then patch the original file. Then I run my
  1440. patcher program on the two files, it compares the differences between the
  1441. original file and the patched one and saves them to a data file. I then
  1442. assemble a patch using the data file.
  1443.  
  1444. What I end up with is a patch that will check the file you are running it on
  1445. to see if it is indeed the correct version before applying the patch. If it's
  1446. not, the patch won't be made. This method also allows me to make multiple
  1447. patches at different locations throughout the program. The byte patcher
  1448. included in this guide will only allow one string to be patched in one
  1449. location. But if you do a clean crack, that's all you'll need anyway.
  1450.  
  1451. Ok. here is the source code to the patcher program, I've commented as much as
  1452. I could throughout the code to make it more understandable. I also wrote it to
  1453. be generic enough so that you can re-use it over and over simply by plugging
  1454. in certain values and re-assembling it.
  1455.  
  1456. NOTE: the patch offsets are not the segment:offset adresses of the code as it
  1457. resides in memory, but the offset from the beginning of the disk file.
  1458.  
  1459. .model  small
  1460. .code
  1461. ORG     100H
  1462. start:          JMP     begin
  1463.  
  1464. ;******************************************************************************
  1465. ;       these are all the variables you set to crack a file,
  1466. ;       simply change the values and then assemble the program
  1467. ;******************************************************************************
  1468.  
  1469. msb     EQU     0000H                   ;the first part of the patch offset
  1470. lsb     EQU     055AH                   ;the second part of the patch offset
  1471. cnt     EQU     3H                      ;number of bytes in your patch
  1472. patch_data      DB 'EB2E90',0           ;the byte string to be written
  1473. file_name       DB 'go.pdm',0           ;the name of the file to be patched
  1474.  
  1475. logo            DB 'Cracked by Uncle Joe',0AH,0DH
  1476.         DB '  -=W.A.S.P. 92=- ',0AH,0DH
  1477.  
  1478. error1          DB 'FILE NOT FOUND',0AH,0DH
  1479.         DB 'Make sure you have GO_CRACK.COM in the same',0AH,0DH
  1480.         DB 'directory as GO.PDM',0AH,0DH
  1481.         DB '$'
  1482.         
  1483. error2          DB 'A FATAL ERROR HAS OCCURED',0AH,0DH
  1484.         DB 'THE CRACK WAS NOT APPLIED',0AH,0DH
  1485.         DB '$'
  1486.         
  1487. error3          DB 'GO.PDM has the read only attribute set',0AH,0DH
  1488.         DB 'reset it before attempting to make the patch',0AH,0DH
  1489.         DB '$'
  1490.         
  1491. handle          DW 0
  1492.  
  1493. ;******************************************************************************
  1494. ;       this procedure opens the file to be cracked
  1495. ;******************************************************************************
  1496.  
  1497. open_it         PROC    near
  1498.         MOV     DX,offset file_name     ;setup to open file to be
  1499.         MOV     AX,3D02H                ;cracked
  1500.         INT     21H
  1501.         JNC     done                    ;if successful, continue
  1502.  
  1503.         CMP     AX,05H
  1504.         JZ      read_only
  1505.         MOV     AH,09H                  ;else display error message
  1506.         MOV     DX,offset error1        ;and exit
  1507.         INT     21H
  1508.         JMP     exit
  1509. read_only:      MOV     AH,09H
  1510.         MOV     DX,offset error3
  1511.         INT     21H
  1512.         JMP     exit
  1513.         
  1514. done:           MOV     handle,AX               ;store the file handle for
  1515.         RET                             ;use later and return
  1516. open_it         ENDP
  1517.  
  1518. ;******************************************************************************
  1519. ;       this procedure sets the file pointer to the patch location
  1520. ;******************************************************************************
  1521.  
  1522. move_it         PROC    near
  1523.         MOV     AH,42H                  ;setup to move the file
  1524.         MOV     AL,00H                  ;pointer to the patch site
  1525.         MOV     BX,handle               ;load the file handle
  1526.         MOV     CX,msb                  ;the first part of offset
  1527.         MOV     DX,lsb                  ;and the second part
  1528.         INT     21H                     ;move the pointer
  1529.         JNC     ok                      ;if successful, continue
  1530.  
  1531.         MOV     AH,09H
  1532.         MOV     DX,offset error2
  1533.         INT     21H                     ;else print error message and
  1534.         JMP     exit                    ;exit
  1535. ok:             RET
  1536. move_it         ENDP
  1537.  
  1538. ;******************************************************************************
  1539. ;       this procedure writes the crack to the file and closes it
  1540. ;******************************************************************************
  1541.  
  1542. patch_it        PROC    near
  1543.         MOV     AH,40H                  ;setup to write the crack
  1544.         MOV     BX,handle               ;load file handle
  1545.         MOV     CX,cnt                  ;load number of bytes to write
  1546.         MOV     DX,offset patch_data    ;point DX to patch data
  1547.         INT     21H                     ;make the patch
  1548.  
  1549.         JNC     close_it                ;if successful, contintue
  1550.         MOV     AH,3EH
  1551.         INT     21H
  1552.         MOV     AH,09H                  ;if not then something
  1553.         MOV     DX,offset error2        ;is wrong, disk may be write
  1554.         INT     21H                     ;protected. If so, print error
  1555.         JMP     exit                    ;message and exit
  1556.         
  1557. close_it:       MOV     AH,3EH                  ;crack was successful
  1558.         INT     21H                     ;close file and return
  1559.         RET
  1560. patch_it        ENDP
  1561.  
  1562. ;******************************************************************************
  1563. ;       the main program
  1564. ;******************************************************************************
  1565.  
  1566. begin           PROC    near
  1567.         CALL    open_it                 ;open file to be patched
  1568.         CALL    move_it                 ;move pointer to patch site
  1569.         CALL    patch_it                ;make the patch and close file
  1570.         MOV     AH,09H
  1571.         MOV     DX,offset logo          ;display logo
  1572.         INT     21H
  1573.  
  1574. EXIT:           MOV     AX,4C00H                ;and exit
  1575.         INT     21H
  1576. BEGIN           ENDP
  1577.  
  1578.         END     START                
  1579.  
  1580.  
  1581.  
  1582.  
  1583. CHAPTER 8   CONCLUSION
  1584. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1585.  
  1586. Hopefully this guide has been useful in helping you understand the cracking
  1587. process. It is by no means an all inclusive guide, the main goal I had in mind
  1588. when I wrote it was to give beginners a push without confusing the hell out of
  1589. them.
  1590.  
  1591. It is not feasable to try and include all of the tricks of the trade that a
  1592. beginner might find useful into one single guide, nor would I want to do this.
  1593. For one thing, this guide would be ten times the size it is now, and even then
  1594. it would not be an encyclopedia of what to do for every situation. If your
  1595. serious enough about cracking, you will discover enough tricks and develop
  1596. your own methods as you progress. And you have to be creative! What works in
  1597. one situation may not work again in a similar one.
  1598.  
  1599. Instead, I tried to give you a general idea on how a programs code might
  1600. operate and what to look for. A successful cracker is not someone who
  1601. memorizes a specific set of actions to perform on a specific piece of code. A
  1602. successful cracker is someone who understands the flow of the code, and how to
  1603. adapt his methods to successfuly re-write the programs code to behave as he
  1604. wishes and not as the programmer intended it to. There are no set rules for
  1605. this, the very nature of the PC won't allow it.
  1606.  
  1607. If you have any questions about cracking or are stumped by something, drop me
  1608. a note at an575063@anon.penet.fi, I'll be glad to give any advice I can. Or if
  1609. you simply just wish to discuss cracking techniques or anything of that
  1610. nature, I'd love to hear from you.
  1611.  
  1612. NOTE: Do NOT mail me and ask me to crack programs for you! I'm not interested
  1613. in cracking for the masses. If you need something cracked, learn how to crack
  1614. it yourself. If you are unwilling to learn how, then register it.
  1615.  
  1616. Most people who frequent the cracking newsgroups nowadays in my opinion are
  1617. clueless ungrateful fucks, and I'll not supply these losers with cracks. 95%
  1618. of the users in the newsgroups are useless parasites who only take and do not
  1619. give anything in return, all the posts you see now are from losers saying give
  1620. me this, give me that. These people are scum and do not deserve what we as
  1621. crackers have to offer. The only thing they have done is to trash the
  1622. newsgroups I used to love... I do hate them.
  1623.  
  1624. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  1625.  
  1626.  
  1627.  
  1628.