home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / pc / virus / jb_virus.doc < prev    next >
Encoding:
Text File  |  2003-06-11  |  72.8 KB  |  2,300 lines

  1.  
  2.                   THE JERUSALEM B VIRUS--A PRODUCT REVIEW
  3.  
  4.  
  5.      Why in the world would anyone write a product review of a computer
  6.  
  7. virus?  To start with, I have become disgusted with all the hype and
  8.  
  9. bullshit I have been hearing about computer viruses.  I hope to deflate
  10.  
  11. a little of it.
  12.  
  13.      Secondly, to grab your attention.  This review will segue into a
  14.  
  15. review of some products I think you will find useful.  I do, after all,
  16.  
  17. work for a marketing company.
  18.  
  19.      What is a computer virus, anyway?  It is a program, or section of
  20.  
  21. code that reproduces itself.  Anything else it does, such as scrambling
  22.  
  23. a disk or a screen, is incidental to the definition.
  24.  
  25.      This definition is a bit arbitrary, but it will suffice for the
  26.  
  27. present.  I am willing to discuss the finer distinctions between viruses,
  28.  
  29. worms, trojans, mere bugs, etc.--some other time.
  30.  
  31.      Viruses, as defined above, have been around for a while.  A
  32.  
  33. disgruntled operator in a mainframe installation that I worked at in
  34.  
  35. the mid 1970's submitted a job that created and submitted two copies
  36.  
  37. of itself and then terminated.  It filled the scheduler's queue and
  38.  
  39. crashed the system.
  40.  
  41.      In response, the systems people added a bit to the job information
  42.  
  43. table that indicated whether a job had been submitted from outside the
  44.  
  45. system or had been submitted by another job.  The scheduler would not
  46.  
  47. allow a job that had been created by another job to create any jobs.
  48.  
  49.      I believe that all this happened in 1972, but it may have been
  50.  
  51. earlier.
  52.  
  53.      Anyway, on with the review.  The virus arrived in town hiding in
  54.  
  55. a pirate copy of DR HALO.  One of its victims told me that it was the
  56.  
  57. JERUSALEM B virus, and gave me the original disk.
  58.  
  59.      I made sure that my backups were current and that my hard drive
  60.  
  61. was write disabled, and went to work.  I executed the suspect copy of
  62.  
  63. DR HALO and watched my available memory shrink by 1808 bytes.  Something
  64.  
  65. grabbed INT 21 and INT 08.  I watched as something tried to write to
  66.  
  67. my hard drive every time an executable was loaded from it.
  68.  
  69.      I created a five byte do nothing .com file, and executed it.  The
  70.  
  71. virus took the bait and I had an 1818 byte .com file consisting of the
  72.  
  73. 1808 byte virus, my original 5 bytes, and a five byte signature string.
  74.  
  75.      I disassembled this using ASMGEN and studied the resulting source
  76.  
  77. code.
  78.  
  79.      The virus is present at the beginning of .com files with the
  80.  
  81. original .com image displaced by the length of the virus.  In the case
  82.  
  83. of .exe files, it is tacked on to the end with the .exe header altered
  84.  
  85. to point CS:IP and SS:SP to the virus.
  86.  
  87.      When an infected program is run, the virus gets control first.
  88.  
  89. It checks for an already resident copy of itself.  If it doesn't find
  90.  
  91. one, it TSRs and then loads and runs another copy of the infected program.
  92.  
  93. It uses its copy of the environment to find the name of the disk copy
  94.  
  95. of the infected program.  DOS 1.x and 2.x do not put this information
  96.  
  97. in the environment, so the second copy will not run.  It will appear as
  98.  
  99. if the infected program terminated without doing anything.
  100.  
  101.      If the virus in an infected .com file finds another copy of itself
  102.  
  103. already TSR, it asks the resident copy to relocate the original .com
  104.  
  105. image to its proper place and execute it.  But the AX register is
  106.  
  107. corrupted in the process, which will cause many old FCB based programs
  108.  
  109. to incorrectly parse the command line.
  110.  
  111.      There is code present to provide similar services to infected .exe
  112.  
  113. files, but it appears to go unused.  The .exe inhabiting virus simply
  114.  
  115. relocates the CS and SS values saved within itself during the infection
  116.  
  117. process and loads CS:IP and SS:SP with the values the loader would have
  118.  
  119. supplied to an uninfected file.  Since the infection process preserved
  120.  
  121. the original relocation table, nothing else is needed.
  122.  
  123.      The resident copy does several things.  On Friday the 13ths its
  124.  
  125. behavior is simple.  It grabs INT 21 and watches for EXEC requests
  126.  
  127. (AX == 4B00).  When one occurs, it first issues a delete (AH == 41)
  128.  
  129. with the same parameters, then passes on the original request, which
  130.  
  131. will then fail, since the requested file will be gone.
  132.  
  133.      Except on Friday the 13ths, the virus grabs INT 08.  After about
  134.  
  135. 29 minutes, it scrolls a window on the screen and starts wasting CPU
  136.  
  137. time.  It does not adapt the amount of waste to the type of processor,
  138.  
  139. so it would be a lot more noticable on a garden variety PC than on a
  140.  
  141. fast AT type machine.
  142.  
  143.      The virus uses a REP LODSB instruction to waste the time.  The
  144.  
  145. 386 and 486 are a lot fussier than the 086, 186, and 286 about what
  146.  
  147. instructions you are allowed to use a REP prefix with, so I suspect
  148.  
  149. that this would simply crash a 386 or 486.  I don't own one and nobody
  150.  
  151. would let me use theirs to do the experiment, so I can't say this with
  152.  
  153. certainty.
  154.  
  155.      On non Friday the 13ths the virus also grabs INT 21 and watches
  156.  
  157. for EXEC requests, but its behavior is more complex.
  158.  
  159.      When an EXEC request occurs, the virus first checks to see if the
  160.  
  161. requested file is named COMMAND.COM.  If it is, the virus merely passes
  162.  
  163. the request on to DOS.
  164.  
  165.      If the file is not named COMMAND.COM, the virus next looks for its
  166.  
  167. signature in the last five bytes of the requested file.  If it finds the
  168.  
  169. signature, it also passes the request on to DOS.
  170.  
  171.      Finally, if the signature is missing, the virus checks to see if
  172.  
  173. there is enough space on the disk that the requested file is on to hold
  174.  
  175. another copy of the virus.  If there is not sufficient space, it just
  176.  
  177. passes the request on to DOS.
  178.  
  179.      If there is enough space, and the signature is missing, then the
  180.  
  181. virus takes different courses depending on whether the file name ends
  182.  
  183. in 'M' or not. (indicating whether it is .com or .exe)
  184.  
  185.      For a .com file, the virus allocates a 64K buffer, copies itself
  186.  
  187. into it, copies the .com file into the buffer after itself, and adds
  188.  
  189. the five byte signature to the end.  It next writes the contents back
  190.  
  191. out to the original .com file, taking care to preserve the file's date
  192.  
  193. and time.  It deallocates the buffer and finally passes the original
  194.  
  195. EXEC request on to DOS.
  196.  
  197.      For .exe files, it copies itself to the end of the file, using the
  198.  
  199. length in the header instead of the DOS file size.  This means that any
  200.  
  201. overlays or other information unaccounted for by that header length
  202.  
  203. field will be corrupted.  It also neglects to add the signature string
  204.  
  205. to the end.  This means that superinfection will occur in .exe files.
  206.  
  207.      Superinfection is multiple copies of some virus becoming attached
  208.  
  209. to some resource.  If a virus fails to detect that a file is already
  210.  
  211. infected with itself and infects it again, then superinfection has occured.
  212.  
  213. If a virus fails to notice that a copy of itself is already TSR in an
  214.  
  215. MS-DOS machine and TSRs again, then that is also superinfection.
  216.  
  217.      The actual viral code is interesting.  I think I see the work of
  218.  
  219. two programmers.
  220.  
  221.      The bulk of the code is busy and inefficient.  For instance, in
  222.  
  223. preparation for TSR, the virus relocates itself to just below its PSP,
  224.  
  225. even if it is in a .com file and is already there.  In another case, during
  226.  
  227. analysis of the filename passed by the EXEC call, it goes to the trouble
  228.  
  229. of scanning the filename string each of the three times it needs to find
  230.  
  231. the end of string instead of saving a pointer to it the first time.
  232.  
  233.      On the other hand, most of the code that does the actual infecting
  234.  
  235. of .com and .exe files is straight forward and economically written.
  236.  
  237.      The virus has a number of bugs in it, in addition to the ones
  238.  
  239. mentioned in the behavioral summary above.  But, once you have something
  240.  
  241. that half works, how do you safely test it?
  242.  
  243.      The virus attempts too many pranks--destruction of files, screen
  244.  
  245. games, and time wasting.  If it had attempted only one thing, it would
  246.  
  247. have been more effective.  If it had only played with the screen, I
  248.  
  249. would even have thought it was funny.
  250.  
  251.      It looks to me like the virus author is some adolesent who
  252.  
  253. either disassembled and modified an already existing virus or got a
  254.  
  255. more capable programmer to assist him (or her).
  256.  
  257.      In summary, this is a third generation virus--it tries to avoid
  258.  
  259. superinfection, it infects .com files (easy) and .exe files (not so
  260.  
  261. easy), and it avoids the easy to avoid virus pitfalls, namely file
  262.  
  263. date and time changes and COMMAND.COM attacks.  It is however, bug
  264.  
  265. ridden, and a nuisance, and not worth buying, no matter how low the
  266.  
  267. price.
  268.  
  269.                            HYPE AND BULLSHIT
  270.  
  271.      Humor aside, I think the anti virus authorship rhetoric has gotten
  272.  
  273. a little out of hand.  I hear politicians calling for mandatory prison
  274.  
  275. terms and some of the victims calling for the death penalty and worse.
  276.  
  277.      Virus authorship is simple criminal mischief, the moral equivalent
  278.  
  279. of throwing a rock and breaking a window.  Well, breaking a lot of
  280.  
  281. windows.
  282.  
  283.      The punishment should be proportional to the injury caused.  If a
  284.  
  285. virus crashes a hospital's patient monitoring computer and causes a
  286.  
  287. patient's death, then murder charges seem appropriate.  If a few copies
  288.  
  289. of pirate software are the only casulties, then it is hard to justify
  290.  
  291. punishing the author at all.
  292.  
  293.      Let's take a moment to examine the victim's role in all of this.
  294.  
  295. It seems reasonable to bemoan the loss of innocence caused by the
  296.  
  297. occurance of computer crime, but it was inevitable.  Crying about it
  298.  
  299. instead of taking appropriate measures, is largely a waste of time.
  300.  
  301. People shouldn't steal cars either, but most of us don't bother to cry
  302.  
  303. about it, we take sensible precautions, ie., we lock our cars.
  304.  
  305.      The loss of innocence had already happened anyway.  The story
  306.  
  307. about the bank programmer truncating interest calculations and adding
  308.  
  309. the residue to his own account balance was already old when I first
  310.  
  311. heard it in 1970.
  312.  
  313.      Now, I have no good idea whether the victim of this virus was
  314.  
  315. typical or not.  Let's look at his situation, though.  He was burned
  316.  
  317. by what he thought was a pirate copy of DR HALO.  This means he was
  318.  
  319. knowingly committing a crime at the time of his misfortune.  He had no
  320.  
  321. backups.  Luckily for him, the virus didn't attack data.  It seems he
  322.  
  323. was in the habit of working with his distribution disks, and most of
  324.  
  325. them were infected.  Somehow, I have a hard time feeling sorry for him.
  326.  
  327.      On to a very brief discussion of hype.
  328.  
  329.      The only thing I can say about newspapers and TV is that I worry
  330.  
  331. that their coverage of the rest of the news is as accurate as their
  332.  
  333. coverage of technical issues.
  334.  
  335.      My opinion of the legislature's and other political grandstanders'
  336.  
  337. words and actions is unprintable.
  338.  
  339.      A while back, I read a book on computer viruses.  The book
  340.  
  341. consisted of a discussion of viruses and their properties, aimed at not
  342.  
  343. very technical users.  It concluded with interviews of several computer
  344.  
  345. virus and computer security experts.
  346.  
  347.      The author, who seemed to be a technical writer with no deep
  348.  
  349. understanding of computers, at least had his facts straight.  This is
  350.  
  351. more than can be said for some of the experts.
  352.  
  353.      One expert in particular, hypeing his own antiviral product,
  354.  
  355. said that "sooner or later the virus has to use INT 13 and then we've
  356.  
  357. got it!".  I don't know about you, Mr. Expert, but I am perfectly
  358.  
  359. capable of talking directly to the host adaptor using IN and OUT
  360.  
  361. instructions and DMA transfers.
  362.  
  363.      This doesn't mean that the expert's product was valueless, just
  364.  
  365. not perfect.  He was stupid or dishonest to claim that it was.
  366.  
  367.      The expert's product was valuable in three ways.  First, it
  368.  
  369. raised the level of skill needed to author viruses capable of
  370.  
  371. attacking machines that his product protected.  Second, it made the
  372.  
  373. job of the remaining authors more difficult.  Third, in a few cases,
  374.  
  375. it will have made the job effectively impossible.
  376.  
  377.      The kid who wrote the virus I disassembled is not a careful
  378.  
  379. enough programmer to write the necessary code.  He probably will be
  380.  
  381. someday, but hopefully by then, the thrill of watching the glass break
  382.  
  383. will be gone, and he will find more constructive things to do with his
  384.  
  385. skills and time.
  386.  
  387.      If I rose to the expert's bait, I would have to write seperate
  388.  
  389. subroutines for the floppy controller, the Western Digital 1002, the
  390.  
  391. Western Digital 1003, the XEBEC controller, . . .  My virus would be
  392.  
  393. getting big and hard to hide.
  394.  
  395.      Additionally, my virus would die when it met the Alabama Tool and
  396.  
  397. Die Works floppy controller or the Chinese People's Collective hard
  398.  
  399. disk controller, because I never heard of those products and couldn't
  400.  
  401. prepare my virus for its encounter with them.
  402.  
  403.      The virus/antiviral contest is an arms race just like the one
  404.  
  405. between car thieves and car owners or the one between military aircraft
  406.  
  407. and anti-aircraft missiles.  One side takes a measure, the other takes
  408.  
  409. a countermeasure, the first takes a counter-countermeasure, and so on,
  410.  
  411. until one side or the other runs out of time, money, patience, or some
  412.  
  413. other resource.
  414.  
  415.      Given that there are jerks out there who create viruses, what should
  416.  
  417. we as users, authors, manufacturers, and distributers do about it?
  418.  
  419.      My advice to manufacturers and distributers is to only sell
  420.  
  421. software on born write protected floppies.  I mean, for instance, that
  422.  
  423. 5.25 inch floppies should have no write protect notch at all.
  424.  
  425.      Authors, I recommend that you include some sort of integrity
  426.  
  427. checking code in the software you write.  Some sort of checksumming
  428.  
  429. would go a long way toward making life difficult for virus authors.
  430.  
  431. Use your immagination, if we all use the same technique, then virus
  432.  
  433. authors will have an easy time adapting their "product" to defeat it.
  434.  
  435.      Users, I'll skip all the usual warnings about pirate software and
  436.  
  437. the importance of backups.  My first recommendation is get and use some
  438.  
  439. sort of hardware write protection for your hard drive.  Now it just
  440.  
  441. so happens that the company I work for, Best in Class Software, sells
  442.  
  443. such a device.  I'll be reviewing it below.
  444.  
  445.      Second, you should consider getting or writing some sort of
  446.  
  447. surveillance program to watch for really suspicious events.  I will
  448.  
  449. talk about the issues I think are involved, but I won't actually make
  450.  
  451. any recommendations.
  452.  
  453.                        HARDWARE WRITE PROTECTION
  454.  
  455.      The hard disk write protection is called WRITE-GUARD and is
  456.  
  457. manufactured by Arrick Computer Products in Euless, Texas.  It costs
  458.  
  459. about eighty dollars.  It consists of a control box outside of the
  460.  
  461. computer chassis connected by a cable to a printed circuit board that
  462.  
  463. plugs into the disk control cable and in turn is plugged into by the
  464.  
  465. edge connector on the back of the hard drive.
  466.  
  467.      The control box has a switch that enables and disables writing
  468.  
  469. to the protected drive.  If a write attempt occurs while the switch
  470.  
  471. is set to write protect, a write fault signal is sent back to the host
  472.  
  473. adaptor, the Write-Guard emits a nasty sounding beep, and a red LED
  474.  
  475. lights and stays lit until the reset button on the control box is
  476.  
  477. pressed.
  478.  
  479.      The manual assures the reader a quick, painless installation.
  480.  
  481. Don't you believe it!  Unless you have the skills and tools of the
  482.  
  483. back room technician at your local computer store, get someone who
  484.  
  485. does to help you.
  486.  
  487.      The location and orientation of the edge connectors on the back
  488.  
  489. of hard drives is variable.  The first time I installed a Write-Guard,
  490.  
  491. the connector on the drive was close enough to the side of the drive
  492.  
  493. bay that the Write-Guard wouldn't fit.  Fortunatly the amount of the
  494.  
  495. mismatch was less than the size of the little ears that were left when
  496.  
  497. they broke up the larger board during manufacture.  A file solved the
  498.  
  499. problem.
  500.  
  501.      In the second installation, the orientation of the disk's connector
  502.  
  503. was reversed top-to-bottom with respect to the first.  This caused the
  504.  
  505. edge connector on the Write-Guard to bump against the mother board.
  506.  
  507. Again, I was lucky, there were spare mounting holes on the drive bay
  508.  
  509. sides and I was able to raise the drive to a non-standard position
  510.  
  511. allowing the Write-Guard to clear the motherboard.
  512.  
  513.      The position of the drive's edge connector with respect to the
  514.  
  515. drive's case also caused the jumpers and other components on the
  516.  
  517. Write-Guard's PC board to press up against the drive's metal case.
  518.  
  519. A little electrical tape solved that problem.
  520.  
  521.      Unfortunatly, the second unit was also defective.
  522.  
  523.      As apparently, was the third.
  524.  
  525.      Arrick's technician says that the jumpers were set wrong on both
  526.  
  527. devices, and that the third one was actually ok.
  528.  
  529.      Now the manual shows the jumper setting on page five.  Beside
  530.  
  531. them is penciled the phrase "SEE SHEET!".  There is an errata sheet
  532.  
  533. that shows jumper settings.  All four units are identical in this
  534.  
  535. respect. (unit number four is still offstage)
  536.  
  537.      The first three units arrived with their jumpers set according
  538.  
  539. to the errata sheet.  I always check jumper settings.  The first one
  540.  
  541. worked fine that way.
  542.  
  543.      The fourth unit arrived with its jumpers set according to the
  544.  
  545. original manual and worked fine that way.  It did however, have the
  546.  
  547. same errata sheet as the first three.  It also failed if the jumpers
  548.  
  549. were changed to conform to the errata sheet's specification.
  550.  
  551.      I've encountered products that were more technician hostile than
  552.  
  553. that, but not in the last several years.  I recommend expecting
  554.  
  555. mechanical and electrical problems during installation.  If you have
  556.  
  557. problems with your blood pressure, get someone else to do the installation
  558.  
  559. for you.  Test the device before you close the computer's case.
  560.  
  561.      My recommendation to Arrick is to redo the design, in particular
  562.  
  563. changing three things.
  564.  
  565.      First, replace the on board connector with one on about six inches
  566.  
  567. of ribbon cable.  This will give the user or technician the freedom to
  568.  
  569. deal with all the variations in geometry of drives and chassis out in
  570.  
  571. the field.
  572.  
  573.      Second, encapsulate the PC board so that the user or technician
  574.  
  575. doesn't have to worry about the jumpers or component leads touching
  576.  
  577. anything metal.  You might epoxy the board and move the jumpers'
  578.  
  579. functions into the control box.
  580.  
  581.      Third, make the manual and the hardware consistantly agree.
  582.  
  583. Boy, am I ever full of advice.  I usually only have this much advice
  584.  
  585. for paying clients.
  586.  
  587.      Once you have the Write-Guard in and working, the protection
  588.  
  589. available to you is immense, far greater than software alone can
  590.  
  591. honestly claim to provide.  The protection is not absolute.  You
  592.  
  593. presumably need to write to the hard drive sometime.  Unless you can
  594.  
  595. throw the enable/disable switch with millisecond speed and precision,
  596.  
  597. those times are windows of vulnerability.  I'm not losing any sleep
  598.  
  599. over it yet.
  600.  
  601.      There are compatibility problems, some of which can compromise
  602.  
  603. security.  The problems aren't Arrick's fault, but since the Write-Guard
  604.  
  605. is what you'd be adding to your system, Arrick will end up getting the
  606.  
  607. blame.
  608.  
  609.      The typical problem occurs thus:  The Write-Guard is write disabled.
  610.  
  611. A program, say an editor or compiler, wants to create and use a scratch
  612.  
  613. file.  If the program has installed its own INT 24 handler, you may not
  614.  
  615. even get the chance to tell it to retry the operation.
  616.  
  617.      But it gets worse.  DOS disk writes are usually three part
  618.  
  619. operations, the actual data write, the FAT update, and the directory
  620.  
  621. update.
  622.  
  623.      Some versions of DOS will ask you "Abort, Retry, or Ignore" for
  624.  
  625. each part of the operation.  If you give different answers, or enable
  626.  
  627. writing partway through the sequence, the data, the FAT, and the
  628.  
  629. directory will no longer be in correspondence.  The result:  lost
  630.  
  631. clusters, cross linked FAT chains, files with the wrong data in them,
  632.  
  633. etc.  Oh well, your backups were current, weren't they?
  634.  
  635.      Other DOS versions attempt all three parts of the operation
  636.  
  637. before reporting the problem and asking the user for guidance.  I
  638.  
  639. wonder what happens if the failure is due to some sort of intermittent
  640.  
  641. fault and some of the parts of the operation succeed and other parts
  642.  
  643. fail.  Oh well, my backups are current.
  644.  
  645.      I can think of three and a half work arounds for this class of
  646.  
  647. problem.  The first is simple.  Leave the Write-Guard in the write
  648.  
  649. enabled state except while testing suspected software.  This is
  650.  
  651. adequate for most purposes.  It is only historical accident that this
  652.  
  653. is not the solution I use.
  654.  
  655.      The half work around is to keep the Write-Guard write disabled
  656.  
  657. most of the time, work from floppies, and use the hard drive mainly for
  658.  
  659. program storage.  This defeats most of the purposes for having a hard
  660.  
  661. drive, but you might be in a situation where this is the way to go.
  662.  
  663.      The second work around is to have two hard drives, one protected
  664.  
  665. and containing your programs, and work from the other, which contains
  666.  
  667. your data.
  668.  
  669.      The third work around is to keep the hard drive write disabled
  670.  
  671. most of the time, and work from a large ramdisk.  This, due to once
  672.  
  673. having been paid in sample EMS boards, is the solution I use.
  674.  
  675.      Ramdisks are wonderful.  They have an access time of perhaps a
  676.  
  677. millisecond.  They can be set to a known, although empty, state at the
  678.  
  679. push of a button.  Copy your work to ramdisk and forget about
  680.  
  681. fragmentation or other performance problems of hard drives.
  682.  
  683.      Now a real ramdisk; i.e., one that connects to a host adaptor card
  684.  
  685. and emulates the hardware interface of a hard drive, is frightfully
  686.  
  687. expensive.  An EMS based ramdisk costs about one tenth as much, is just
  688.  
  689. as fast, and is more flexable.  If you have any applications that can
  690.  
  691. use EMS directly, it can be made available to them simply by editing
  692.  
  693. the CONFIG.SYS file and rebooting the machine.
  694.  
  695.      Ramdisks do have their problems.  They cost more than hard drives
  696.  
  697. of equivalent capacity.  They are volatile.  Unless you have an
  698.  
  699. uninterruptable power supply, you are at the mercy of the drunk who is
  700.  
  701. going to knock over a power pole two blocks away as you complete keying
  702.  
  703. in a thousand line program.
  704.  
  705.      Additionally, if you are a hacker like me, when one of your
  706.  
  707. experiments goes awry, and you have to reboot the machine, there won't
  708.  
  709. be any pieces left to examine for clues to what went wrong.
  710.  
  711.                               OLD TROJANS
  712.  
  713.      I didn't get the Write-Guard for virus protection, although
  714.  
  715. having it gave me the nerve to tackle the first virus that came along.
  716.  
  717. There were three situations or incidents that convinced me that I
  718.  
  719. needed something like Write-Guard.
  720.  
  721.      In late 1986, there was a rumor going around that a certain
  722.  
  723. popular database package had a copy protection scheme that would trash
  724.  
  725. a hard drive if it thought it had been tricked.  This was particularly
  726.  
  727. worrisome since the two prior editions of that package had been quite
  728.  
  729. buggy.  I have never tolerated copy protected software on my own
  730.  
  731. machine, but when a client asks for a brand name, what can I do?
  732.  
  733.      Having heard the rumor, I followed the installation instructions
  734.  
  735. to the letter.  The installation went without a hitch.  I executed the
  736.  
  737. package to confirm that it was installed and working.  It came up and
  738.  
  739. gave me its standard prompt.  I quit out of the package and got
  740.  
  741. "General failure reading drive C:" instead of the C> prompt.
  742.  
  743.      To skip over all the unpleasant details, my ex-client's backups
  744.  
  745. were within a couple of days of being current, so the injury was less
  746.  
  747. than a thousand dollars.  She decided that life was too short to bother
  748.  
  749. suing either me or the manufacturer.
  750.  
  751.      The manufacturer dropped his copy protection a few months later,
  752.  
  753. making some statement about consumer wishes.  I think he was up to his
  754.  
  755. hips in lawsuits.
  756.  
  757.      I've still got the distribution disks.  Some year, when I've got
  758.  
  759. nothing else to do, I'm going to disassemble all the hidden and visible
  760.  
  761. files on them and publish what I find.
  762.  
  763.      The second situation occured during early 1987.  I was writing a
  764.  
  765. multitasking, 286 protected mode BIOS for the Western Digital 1003
  766.  
  767. disk controller.
  768.  
  769.      I wanted to use a separate controller for the test disk, so that
  770.  
  771. I would have to get whole port addresses wrong to accidently trash the
  772.  
  773. DOS disk in the testbed system.
  774.  
  775.      Unfortunatly, my client and I were not able to get the two WD1003's
  776.  
  777. to get along with each other and DOS in the testbed system.  We wound up
  778.  
  779. attaching the test hard drive to the same WD1003 as the DOS drive.  This
  780.  
  781. meant that a command sequence to write to the test drive differed by a
  782.  
  783. single bit from one that would write to the DOS disk.
  784.  
  785.      I never actually made the mistake, but I was pretty nervous until
  786.  
  787. I got the low level code debugged.  Some sort of write protection for
  788.  
  789. the DOS disk would have helped my nerves considerably.
  790.  
  791.      The third situation occured in early 1988.  I was evaluating
  792.  
  793. disassemblers, looking for a replacement for ASMGEN.  I ordered a
  794.  
  795. disassembler from company "R".  They sent me copy "R1".
  796.  
  797.      It didn't work, complaining that it was missing its message file.
  798.  
  799. The message file was visible in the directory listing, so I called
  800.  
  801. company R.  After I ran some experiments at R's direction, R decided
  802.  
  803. that the distribution floppy R1 came on was defective. They sent me
  804.  
  805. replacement copy "R2", which worked.
  806.  
  807.      Now, I have never seen a floppy or a hard drive with defective
  808.  
  809. media that didn't cause the controller to report missing address marks
  810.  
  811. or uncorrectable ECC errors, or something else real obvious.  It seems,
  812.  
  813. based on what I know about the way they work, that a misread that
  814.  
  815. doesn't cause a fault is very unlikely.  This excited my already
  816.  
  817. suspicious nature.
  818.  
  819.      I couldn't use DISKCOMP because some of R's experiments had
  820.  
  821. involved writing to R1's disk.  COMP thought all the files were
  822.  
  823. identical.
  824.  
  825.      I ran R1--still no good.  I ran R2--it now failed.  I did a
  826.  
  827. logical format of my hard drive and restored my backups.  R2 still
  828.  
  829. didn't work.  I did a physical format, a logical format, and a restore.
  830.  
  831. R2 now worked.  I ran R1 again. It failed again.  R2 not working.
  832.  
  833. Physical, logical, restore.  R2 works again.
  834.  
  835.      By now I had blown the better part of a day.  I didn't then have
  836.  
  837. the tools needed to find out what was being hidden on my hard disk
  838.  
  839. outside of DOS' file system, and where it was.  I had other things I
  840.  
  841. needed to be doing, so I did the physical, logical, restore process one
  842.  
  843. more time to clean up what ever R2 might have left behind, and RMA'd
  844.  
  845. both copies back to R.
  846.  
  847.      These three situations convinced me that I needed some sort of
  848.  
  849. hardware write protection for my harddrive.  While bungling the design
  850.  
  851. of one (my hardware skills extend to being able to read and sort of
  852.  
  853. understand schematics, but not to actual design), I stumbled over an
  854.  
  855. ad for the Arrick product.  I knew that I couldn't design and build one
  856.  
  857. for less than the eighty dollars that they wanted for theirs.  Except
  858.  
  859. for the installation difficulties, it has given me a couple of years
  860.  
  861. of trouble free service.
  862.  
  863.      I suspect that the sort of nonsense described in the first and
  864.  
  865. third examples above is fairly common.  The source of the rumor about
  866.  
  867. the database package told me a similar story about one of the DOS
  868.  
  869. multitaskers on the market.  This one allegedly only sought out and
  870.  
  871. destroyed copies of itself.
  872.  
  873.      Another incident happened after I had the Write-Guard.  I was
  874.  
  875. evaluating a CADD package that requires the user to supply his name
  876.  
  877. and company name the first time it is run.  While talking to a
  878.  
  879. technician about a peripherally related bug in the package, he
  880.  
  881. volunteered that the package recorded the information that it had
  882.  
  883. been initialized in the boot sector of the distribution disk.
  884.  
  885.      I sympathize with the desire of authors and manufacturers to get
  886.  
  887. paid for their work.  I prefer getting paid for my own work also.
  888.  
  889.      I don't think copy protection is the answer. (Not that I have
  890.  
  891. any idea what the answer is.)  Writing good code is hard enough to do
  892.  
  893. working within the environment provided by the operating system.  An
  894.  
  895. application programmer is asking for trouble by stepping outside of the
  896.  
  897. system, doing things like direct disk I/O, in order to match wits with
  898.  
  899. children who have time on their hands and nothing to lose.
  900.  
  901.                           SOFTWARE ANTIVIRALS
  902.  
  903.      I'm not recommending any of the software antivirals I've examined;
  904.  
  905. they all have what I consider to be fatal flaws.  Examining them, and
  906.  
  907. talking to the authors was interesting, though.  (I didn't tell them
  908.  
  909. that I was a reviewer.)
  910.  
  911.      All but one of the software antiviral packages included a program
  912.  
  913. that attempted to remove the virus from an infected program.  This was
  914.  
  915. surprising to me since a program that reproduces itself is capable of
  916.  
  917. enormous mischief, intentional or not.
  918.  
  919.      If I suspected even a single executable on a disk was infected by
  920.  
  921. a virus, I would do a physical format of the whole disk and fall back
  922.  
  923. to my most recent backup rather than take a chance on the infection
  924.  
  925. spreading inadvertantly.
  926.  
  927.      I asked one of the authors about this and he told me three things.
  928.  
  929. First, most victims don't have recent backups (no surprise there).
  930.  
  931. Second, the backups are usually contaminated.  (mild surprise, how can
  932.  
  933. one not notice a virus as ham handed as the ones I've heard about long
  934.  
  935. enough to take a backup?)  Third, most of the victims have copy protected
  936.  
  937. programs on the infected disk and can neither have taken backups of them,
  938.  
  939. nor restore them from the distribution disks (oh yeah, copy protection).
  940.  
  941.      I mistrust the class of people who get deeply involved in the
  942.  
  943. virus-antiviral contest.  The two camps need each other.  The more
  944.  
  945. varied and higher quality the supply of viruses is, the more demand
  946.  
  947. there is for antivirals.  The more time, energy, and ink spent on
  948.  
  949. antivirals, the more important virus authors are made to seem.
  950.  
  951.      Ross Greenberg, the author of the FLU_SHOT series of antivirals,
  952.  
  953. freely admits that people have occasionally turned FLU_SHOT into
  954.  
  955. trojans.
  956.  
  957.      The author of one antiviral told me that he also wrote viruses for
  958.  
  959. a federal agency that he was not at liberty to identify.
  960.  
  961.      The author of another antiviral told me that he had evidence that
  962.  
  963. yet another antiviral author was paying someone to develop new viruses.
  964.  
  965.      Quis custodiet ipsos custodes.  Who watches the watchmen?
  966.  
  967.      I would never trust someone else's software antiviral without
  968.  
  969. first disassembling and studying it.  I would prefer to write my own.
  970.  
  971.      Computer system integrity and security is a whole branch of
  972.  
  973. computer science by itself.  I'm not very knowledgeable in the subject,
  974.  
  975. but based on what I do know about it and MS-DOS machines, I'll give you
  976.  
  977. my thoughts.
  978.  
  979.      First of all, I doubt that perfect security is possible in any
  980.  
  981. computer system.
  982.  
  983.      The most heavily defended machine I have first hand knowledge of
  984.  
  985. was a Cyber 170 in a university environment back in 1982.  It had what
  986.  
  987. looked to me like unbeatable hardware support for protecting system
  988.  
  989. integrity.  The applications were not in the same address space as the
  990.  
  991. operating system.  In fact, the bulk of the operating system was not
  992.  
  993. even running on the same processor as the user jobs.  It had a staff
  994.  
  995. of full time programmers whose duties included patching the holes
  996.  
  997. discovered by users.  And yet the users knocked it over once or twice
  998.  
  999. a day.
  1000.  
  1001.      Software can never provide complete protection in MS-DOS systems.
  1002.  
  1003. As long as an application can do its own I/O, software can not prevent
  1004.  
  1005. the destruction or modification of files.  As long as applications can
  1006.  
  1007. read and write each other's memory, software can not prevent itself
  1008.  
  1009. from being analyzed or modified.
  1010.  
  1011.      Software can provide some protection and can powerfully assist
  1012.  
  1013. hardware in protecting your system from viruses, trojans, and bugs.
  1014.  
  1015.      Software does have some advantages over hardware.  It is much
  1016.  
  1017. easier to design than hardware of comparable complexity, and can be
  1018.  
  1019. modified quickly to counter new threats.
  1020.  
  1021.      Due to this, it is much harder for an attacker to anticipate the
  1022.  
  1023. nature of the software defenses it is going to encounter, even if there
  1024.  
  1025. will always be a way to overcome those defenses.
  1026.  
  1027.      I would never depend on software alone to protect my system.  I
  1028.  
  1029. would only use it as an adjunct to hardware.
  1030.  
  1031.      Software also can easily tell you more than hardware can.  The
  1032.  
  1033. Write-Guard will prevent a write to the hard disk and will tell you
  1034.  
  1035. that a write was attempted.  Software, if it hasn't been defeated, can
  1036.  
  1037. tell you which area of the disk the write was directed at, and whether
  1038.  
  1039. the attempt passed through DOS or was issued directly by an application.
  1040.  
  1041.      If you want to protect your system from the CIA, the KGB, or even
  1042.  
  1043. a computer science graduate student, then you're playing out of my
  1044.  
  1045. league.  I can't offer you any useful advice.
  1046.  
  1047.      The threats to my system that I consider significant are much
  1048.  
  1049. milder.  They are:  viruses, trojans, and garden variety bugs, both my
  1050.  
  1051. own and others'.  I regard copy protection schemes as a kind of trojan.
  1052.  
  1053.      What are we trying to protect anyway?  Probably not the running
  1054.  
  1055. program, since all we stand to lose is the time involved in rebooting
  1056.  
  1057. the machine and the time already invested in the current run.  Now if
  1058.  
  1059. you have programs that run for days at a time . . .
  1060.  
  1061.      What we probably want to protect is the programs and data on our
  1062.  
  1063. hard disks and floppies.  By successfully protecting our programs, we
  1064.  
  1065. will also hamper the spread of viruses to other machines.  We might also
  1066.  
  1067. inhibit some of the prank playing that goes on.
  1068.  
  1069.      The first line of defense is to prevent unwanted or unexpected
  1070.  
  1071. writes to the disk.  The Write-Guard is great for hard disks and write
  1072.  
  1073. protect tabs work for floppies.
  1074.  
  1075.      To distinguish an unwanted write from a legitimate but unexpected
  1076.  
  1077. write, you could write a little TSR that records each INT 13 request as
  1078.  
  1079. it occurs, and pops up and tells you all about the last one if it fails.
  1080.  
  1081.      You could then decide whether to write enable the Write-Guard and
  1082.  
  1083. choose "retry", or leave the Write-Guard write disabled and choose
  1084.  
  1085. "abort", "fail", "ignore", or even do a cold boot of your machine.
  1086.  
  1087.      The sorts of things that would cause me to reboot my machine are
  1088.  
  1089. attempts to write to the partition table or boot sector, or any write
  1090.  
  1091. attempt that did not pass through INT 13.  (The Write-Guard would sound
  1092.  
  1093. off, but my INT 13 surveilance wouldn't notice the fault.)
  1094.  
  1095.      The TSR could serve as foundation for a whole host of further
  1096.  
  1097. defenses, depending on how paranoid you are and how much trouble you
  1098.  
  1099. want to go to.
  1100.  
  1101.      Your TSR could attempt to authenticate the caller by examining his
  1102.  
  1103. return address on the stack.  Or you could keep track of entry and exit
  1104.  
  1105. from INT 21 and allow INT 13 calls to proceed only if an INT 21 call
  1106.  
  1107. that would plausably produce the current INT 13 call is in progress.
  1108.  
  1109. For example, there is no good reason for a INT 21 RENAME call to write
  1110.  
  1111. to the FAT.
  1112.  
  1113.      Your TSR could watch for any attemps to format the disk.
  1114.  
  1115.      The sector, head, and cylinder of write requests could be checked
  1116.  
  1117. against a table of addresses of the partition table, the boot sector,
  1118.  
  1119. and any files you wanted to protect.
  1120.  
  1121.      Your TSR could analyze the FAT and the directory tree to construct
  1122.  
  1123. the list of protected sectors.  It could then alert you to all attempts
  1124.  
  1125. to write to .exe, .com, or .bat files.
  1126.  
  1127.      You might want to prevent any use of INT 26, which could be used
  1128.  
  1129. to bypass the caller authentication mentioned above.
  1130.  
  1131.      All the software checks described above can be fooled by a program
  1132.  
  1133. that knows about them, or bypassed altogether by a program that talks
  1134.  
  1135. directly to the disk controller.
  1136.  
  1137.      You might want to implement whole second lines of defense.  The
  1138.  
  1139. above is probably plenty for ordinary bugs, and most viruses and trojans.
  1140.  
  1141.      An approach to a second line of defense might be to watch for events
  1142.  
  1143. that might indicate the presence of a virus or trojan without waiting
  1144.  
  1145. for the actual attack to occur.  Besides, the attack might be some blood
  1146.  
  1147. pressure altering prank rather than actual destruction of files.
  1148.  
  1149.      For example, I have heard of viruses that play pranks like
  1150.  
  1151. transposing digits of long numbers displayed on the screen.  The
  1152.  
  1153. seriousness of the threat posed by such games is dependant on your
  1154.  
  1155. personality type.  Assuming I wasn't worried about deadlines at the
  1156.  
  1157. time, I would be amused by my first encounter with such a program.
  1158.  
  1159. Of course, after I had my laugh, I would hunt down and obliterate all
  1160.  
  1161. copies of the offending program that I could find.
  1162.  
  1163.      If you are the kind of person who takes himself too seriously, or
  1164.  
  1165. tends to believe what the computer tells him, then such a program could
  1166.  
  1167. be a threat to your physical or mental health.
  1168.  
  1169.      Things to watch for are unexpected TSR requests and unexpected
  1170.  
  1171. grabbing of interrupts.  But a hostile program can TSR without issuing
  1172.  
  1173. a TSR request and it can intercept interrupts without modifying the
  1174.  
  1175. interrupt vector table.
  1176.  
  1177.      Another second line approach assumes the damage caused by an attack
  1178.  
  1179. or a bug will be partial or will develop slowly.  You could implement
  1180.  
  1181. some sort of integrity checking of key data structures or files on your
  1182.  
  1183. disk(s).
  1184.  
  1185.      The boot sector, the partition table, and most executables should
  1186.  
  1187. never change and could be checksummed.  The checksums could be verified
  1188.  
  1189. periodically or whenever one of these objects is about to be used.
  1190.  
  1191.      This should detect most infections before they have spread very
  1192.  
  1193. far.
  1194.  
  1195.      It would be nice to integrity check the in memory copies of
  1196.  
  1197. programs, especially DOS, but the structure of MS-DOS appears to make
  1198.  
  1199. that impractable.  Perhaps a cleverer programmer than I . . .
  1200.  
  1201.      There is a gaping hole in all of the above defenses.  How do you
  1202.  
  1203. protect the FAT?  There is so much legitimate writing to that small area,
  1204.  
  1205. that it would be easy to slip a joker into all that traffic.
  1206.  
  1207.      That is an argument for multiple defense strategies.  If you
  1208.  
  1209. sufficiently constrain the circumstances available to attack the FAT or
  1210.  
  1211. any other object, perhaps all attacks will trigger some alarm before they
  1212.  
  1213. can be carried out.  Of course, those constraints will hamper legitimate
  1214.  
  1215. activity as well.
  1216.  
  1217.      All of the above defenses, including the Write-Guard, can be
  1218.  
  1219. defeated by a competent, determined opponent.  No matter how hard you
  1220.  
  1221. work at it, you will never be able to rest completely easy.
  1222.  
  1223.      On the other hand, I've only implemented three of my own suggestions
  1224.  
  1225. for defense tactics listed above, only one in response to the viral threat.
  1226.  
  1227. I won't be beefing up my defenses any further, unless the threat becomes
  1228.  
  1229. more severe that I expect, or someone offers me a lot of money to do so.
  1230.  
  1231.      I think that it is important to keep all of this in perspective.
  1232.  
  1233. The threats are not currently severe enough to justify all the defensive
  1234.  
  1235. effort described above.  I do not think that they are going to become
  1236.  
  1237. that severe during the lifetime of MS-DOS.
  1238.  
  1239.      A better written operating system than MS-DOS could be much more
  1240.  
  1241. resistant to challenges to its integrity, even without hardware support.
  1242.  
  1243. When the successor to the MS-DOS machines appears, the virus-antiviral
  1244.  
  1245. contest is going to be a whole new game.
  1246.  
  1247.      It should be remembered that viruses, trojans, and bugs are just
  1248.  
  1249. obstacles in the way of getting useful work done and not something that
  1250.  
  1251. there is any direct benefit in dealing with.  Well ok, except for
  1252.  
  1253. recreation and education, there is no direct benefit.
  1254.  
  1255.      A software antiviral doesn't come free either.  It is going to
  1256.  
  1257. occupy some memory and consume some CPU cycles.
  1258.  
  1259.      For instance, if it checksums executables before they are run,
  1260.  
  1261. the table of checksums will occupy a possibly large block of memory,
  1262.  
  1263. and the execution of a requested program will be delayed by however
  1264.  
  1265. long it takes to compute the checksum.
  1266.  
  1267.      In addition, a resident antiviral is prey to all the conflicts
  1268.  
  1269. and compatibility problems of any other TSR.
  1270.  
  1271.      In summary, I don't think you should blindly put a lot of effort
  1272.  
  1273. into making your system virus proof.  You should take a realistic look
  1274.  
  1275. at the threat level and take cost effective action to protect yourself.
  1276.  
  1277.                              DISASSEMBLERS
  1278.  
  1279.      Disassembly is the translation of machine language to assembly
  1280.  
  1281. language.  In the 80x8x family of chips disassembly is a very tough
  1282.  
  1283. problem.
  1284.  
  1285.      The sources of difficulty are that the instruction formats are
  1286.  
  1287. intricate, the segmentation is confusing, and the same bytes can be
  1288.  
  1289. used as both instructions and data.
  1290.  
  1291.      In the 286 and up, the segment meanings are mode dependant, and
  1292.  
  1293. in protected mode, the segments are likely to be defined outside of
  1294.  
  1295. the program.
  1296.  
  1297.      In the 386 and up, and in some enhanced chips from second sources
  1298.  
  1299. such as the V20 and V30, the instruction formats are also mode dependent.
  1300.  
  1301.      I suspect that the general case of disassembly is equivalent to
  1302.  
  1303. Post's correspondence problem, and is therefore unsolvable.  Perhaps
  1304.  
  1305. one of my readers who likes the math, and whose last encounter with
  1306.  
  1307. theory was less than fifteen years ago, would like to prove or disprove
  1308.  
  1309. that conjecture.
  1310.  
  1311.      Fortunately, most real world programs are intended to run in real
  1312.  
  1313. mode, and are also written to the minimum common instruction set.  It
  1314.  
  1315. is bad programming practice to use the same object as both instructions
  1316.  
  1317. and data, so in the real world, it is done sparingly.  Therefore, most
  1318.  
  1319. real world cases are doable.
  1320.  
  1321.      Why bother to disassemble a program?  Well, that's how I learned
  1322.  
  1323. 8088 assembly language.
  1324.  
  1325.      In 1984, one of my clients, a mail order house, wanted me to take
  1326.  
  1327. the ramdisk and print spooler that came bundled with a Taiwanese
  1328.  
  1329. multifunction board that they sold, fix the bugs, and translate the
  1330.  
  1331. messages into unbroken English.  Source code was not available.
  1332.  
  1333.      A kid I had taught Z80 assembly language gave me a copy of ASMGEN
  1334.  
  1335. that he had found on a bulletin board somewhere.  A hardware engineer
  1336.  
  1337. friend gave me a copy of Rector and Alexy's THE 8086 BOOK.  My client
  1338.  
  1339. gave me an assembler and I went to work.
  1340.  
  1341.      I don't recommend this approach in general.  I'd been programming
  1342.  
  1343. IBM PCs for a year or two already, and knew three other assembly
  1344.  
  1345. languages (or more, depending on how loosely you keep score).  For my
  1346.  
  1347. advice on learning 8088 assembly language, see my review of THE VISIBLE
  1348.  
  1349. COMPUTER, below.
  1350.  
  1351.      The most obvious but least mentioned reason to disassemble
  1352.  
  1353. programs is for purposes of industrial espionage.  Before self-righteous
  1354.  
  1355. people start moralizing at me, I'd like to point out that an anti-viral
  1356.  
  1357. author taking apart a virus and using the knowledge gained to improve
  1358.  
  1359. his product is an example of industrial espionage.  Unfortunatly, a
  1360.  
  1361. virus author taking apart an anti-viral and using the knowledge gained
  1362.  
  1363. to improve his product is also an example.
  1364.  
  1365.      There is no particular moral significance to spying.  The morality
  1366.  
  1367. or immorality springs from the methods, purposes, and effects.
  1368.  
  1369.      Clarification of documentation is a frequently mentioned purpose
  1370.  
  1371. that always sounds like bullshit to me.  I've actually used disassembly
  1372.  
  1373. for that purpose though.  When the Western Digital 1003 documentation
  1374.  
  1375. says "GAP 1 and 3 length determined by Sector Number Register contents
  1376.  
  1377. during formatting,"  and that's the only mention I can find of the use
  1378.  
  1379. of the Sector Number Register during formatting, I start disassembling
  1380.  
  1381. things to see how they actually use it.
  1382.  
  1383.      There can be forensic purposes for disassembly as well.  I know of
  1384.  
  1385. two court cases where what a program actually does is an issue and
  1386.  
  1387. source code is not available.
  1388.  
  1389.      In one of them, the defendant is accused of planting a trojan in a
  1390.  
  1391. program and then attempting to extort money from his (former) client,
  1392.  
  1393. the plaintif.  The plaintif's expert witness tells me that the trojan
  1394.  
  1395. is definitly present in the disassembled program.
  1396.  
  1397.      In the other case, a stock market analysis program is claimed by
  1398.  
  1399. the prosecution to be just a bunch of pretty screens and to not actually
  1400.  
  1401. do the analysis that the defense claims it does.  The issue is a minor
  1402.  
  1403. element in a large fraud case.
  1404.  
  1405.      The prosecution does not care to attempt to prove its claim by
  1406.  
  1407. actually disassembling the program;  that would be a lot of trouble.
  1408.  
  1409. The defense claims that the prosecution lost the source code when they
  1410.  
  1411. seized the defendants' computers.
  1412.  
  1413.      I have no problem believing both sides' stories simultaneously.
  1414.  
  1415. A pox on both their houses!
  1416.  
  1417.      I pull most new software into DEBUG and browse through it before
  1418.  
  1419. I use it.  From this I learn things like what language a package is
  1420.  
  1421. written in and how competent the programmer was.  In about a quarter
  1422.  
  1423. of the cases, I find undocumented commands.
  1424.  
  1425.      I also learn an occasional new coding trick this way.
  1426.  
  1427.      The reason I'm reviewing and recommending three disassemblers
  1428.  
  1429. instead of just one, is that they all have limitations and ranges of
  1430.  
  1431. suitability.  Of course, Murphy guarantees that the one I like the
  1432.  
  1433. best has the narrowest range.
  1434.  
  1435.      The first disassembler is called ASMGEN.  It's the one I use most
  1436.  
  1437. of the time.  It is appropriate for files less than 48K in size, and
  1438.  
  1439. containing only 8086/8087/8088 instructions.  The authors placed it in
  1440.  
  1441. the public domain.  We'll sell you a copy for ten dollars.  (Others
  1442.  
  1443. will sell it to you even cheaper.)
  1444.  
  1445.      Lest you think 48K is a severe limit, 48K of machine language
  1446.  
  1447. will disassemble into about 25,000 lines of assembly language, or
  1448.  
  1449. about 400 pages.  You will still have to analyze it, and that will
  1450.  
  1451. take months to complete.
  1452.  
  1453.      When invoked, ASMGEN looks for a file with the same name as the
  1454.  
  1455. machine language file and with an extension of .seq.  The .seq file
  1456.  
  1457. contains directives to control the disassembly process and to control
  1458.  
  1459. the kind of information included in the disassembly output.
  1460.  
  1461.      ASMGEN uses a simple but fairly effective algorithm to distinguish
  1462.  
  1463. code and data--it's all code unless you tell it otherwise in the .seq
  1464.  
  1465. file.  That is the purpose of the .seq file.  You run ASMGEN on the
  1466.  
  1467. machine language file, examine the output, edit the .seq file to
  1468.  
  1469. reflect what you've learned, and then repeat the process.
  1470.  
  1471.      ASMGEN only understands .com and .exe file formats, but the .seq
  1472.  
  1473. file directives are flexible enough that you can easily analyze device
  1474.  
  1475. drivers and ROM code as well.
  1476.  
  1477.      ASMGEN includes labels and cross references in the generated source
  1478.  
  1479. code.  This feature alone makes it better than half the disassemblers
  1480.  
  1481. I've examined.
  1482.  
  1483.      ASMGEN also includes the actual machine language code bytes as
  1484.  
  1485. comments in the generated listing, which I find usefull for checking
  1486.  
  1487. the generated code.
  1488.  
  1489.      While ASMGEN understands .exe file formats, it is sometimes
  1490.  
  1491. confused by the relocation table in the header.  A work around would
  1492.  
  1493. be to load the .exe file into DEBUG and write it back out as a .com
  1494.  
  1495. file.  The DOS loader will take care of the relocation for you.  You
  1496.  
  1497. would need to keep track of the segmentation yourself, and edit the
  1498.  
  1499. .seq file to get the labels right.
  1500.  
  1501.      I was only dimly aware of the problem until I started this review.
  1502.  
  1503. Most of the code I've seriously tried to disassemble has been less than
  1504.  
  1505. 20K in size, and it's an odd .exe file that is that small and needs
  1506.  
  1507. much relocation.  In fact, on my hard drive, there are only two .exe
  1508.  
  1509. files less than 64K in size with more than two relocation table entries.
  1510.  
  1511. Besides, I'm mostly intrested in ROM code and device drivers.
  1512.  
  1513.      ASMGEN also has several minor bugs.  Things like substituting
  1514.  
  1515. eight bit register names for the destination operand in the LES
  1516.  
  1517. instruction.  Or leading zero suppressing the constant zero to the
  1518.  
  1519. empty string.
  1520.  
  1521.      Support for ASMGEN is nonexistant.  I can't even find the authors,
  1522.  
  1523. and I've been trying off and on for five years.
  1524.  
  1525.      By the way, I've used ASMGEN so much, I'd give the authors $100,
  1526.  
  1527. if I knew how to contact them.  J Gersbach BTVVMLAB(U6081) and J Damke
  1528.  
  1529. BOEVM1(DAMKE) please call me at 1-800-777-9752.  Ask for David.
  1530.  
  1531.      The on disk documentation assumes you already sort of understand
  1532.  
  1533. the assembly process, but otherwise, it is clear and reasonably complete.
  1534.  
  1535. Between it and experimentation, ASMGEN is easy to learn and use.
  1536.  
  1537.      The maximum memory requirement is 128K.  The output file is about
  1538.  
  1539. twenty times the size of the input file.
  1540.  
  1541.      For the range of problems that it is suitable for, ASMGEN is the
  1542.  
  1543. best in its class, and for ten dollars, you can hardly beat it.
  1544.  
  1545.      CODEGEN is the disassembler I turn to when ASMGEN fails me.  It
  1546.  
  1547. understands the 8088 through 80286.  It does not understand the
  1548.  
  1549. 8087/80287, and produces ESC instructions instead.  It is appropriate
  1550.  
  1551. for files consisting of only one code segment and only one data segment,
  1552.  
  1553. which are supprisingly common.
  1554.  
  1555.      It requires 384K of free memory and produces an output file that
  1556.  
  1557. is about thirty times the size of the input file.
  1558.  
  1559.      CODEGEN comes from Digital Dispatch of Lakeland, Minnesota.  It
  1560.  
  1561. comes with a fifty page manual.  The price is thirty dollars.   Except
  1562.  
  1563. for bug fixes, it is unsupported.
  1564.  
  1565.      The best feature of CODEGEN is that it is interactive.  It does
  1566.  
  1567. very conservative code tracing and assumes that everything that it
  1568.  
  1569. doesn't reach is data.  After it has done this, it pops up a menu that
  1570.  
  1571. lets you browse through the file, allowing you to tell it that here is
  1572.  
  1573. a jump table, there is another entry point, and this isn't code at all,
  1574.  
  1575. but data.
  1576.  
  1577.      The browse facility is a little bit primitive.  The user is only
  1578.  
  1579. able to preview the disassembly starting at some hexadecimal address
  1580.  
  1581. that he keys in, or to get a list of lines that would contain some
  1582.  
  1583. string.  This latter feature can be used for such things as locating
  1584.  
  1585. all CALL or JMP instructions, in order to resolve all indirect code
  1586.  
  1587. references.
  1588.  
  1589.      The user can specify the names that he wants to give to up to 511
  1590.  
  1591. locations in the assembly language listing and CODEGEN will substitute
  1592.  
  1593. those names for the hex number based names it would have generated.
  1594.  
  1595.      You can save the state of the disassembly process into a map file
  1596.  
  1597. at any time.  This allows you to quit and pick up where you left off at
  1598.  
  1599. a later time.  Or you can make a speculative guess at what something is
  1600.  
  1601. and fall back to your last map if you discover that your guess was wrong.
  1602.  
  1603.      CODEGEN will optionally add comments to system calls, telling what
  1604.  
  1605. they do.  This saves me a lot of thumbing through reference books.
  1606.  
  1607.      The manual assumes the reader knows a lot, which is a reasonable
  1608.  
  1609. assumption to make about someone who is disassembling a machine language
  1610.  
  1611. program.  Some of the explanations are obscure enough to confuse me,
  1612.  
  1613. though.  The manual does spend some time explaining the disassembly
  1614.  
  1615. process and CODEGEN's approach to it, which is helpful in getting it to
  1616.  
  1617. do what you want.
  1618.  
  1619.      The worst feature of CODEGEN is that the cross reference information
  1620.  
  1621. is at the end of the listing rather than being embedded at the point of
  1622.  
  1623. reference, and is completely unavailable during the interactive browsing
  1624.  
  1625. process.
  1626.  
  1627.      I've found two bugs in my copy of CODEGEN.  The first bites if you
  1628.  
  1629. specify an uppercase search string in the browsing process described
  1630.  
  1631. above.  The author does all of his string compares in lower case in an
  1632.  
  1633. attempt to make the searches case insensitive.  Unfortunatly, he forgot
  1634.  
  1635. to force the user supplied string to lower case, so any uppercase
  1636.  
  1637. characters in the search string will cause the search to fail.
  1638.  
  1639.      The second bug has unknown causes.  When you press CTL-S to pause
  1640.  
  1641. the display output, CODEGEN sometimes looses the CTL-S and keeps on
  1642.  
  1643. scrolling the display.  The work around is to be prepared to press
  1644.  
  1645. CTL-S more than once to stop the display.
  1646.  
  1647.      CODEGEN's author wrote it for his own use and is constantly
  1648.  
  1649. tinkering with it.  By the time you read this, he will have fixed the
  1650.  
  1651. string search bug, and if he figures out what's causing it, the CTL-S
  1652.  
  1653. bug as well.
  1654.  
  1655.      If CODEGEN supported more elaborate segmentation, embeded the
  1656.  
  1657. cross references at the referenced point, and made the cross references
  1658.  
  1659. available during the browse session, I would junk ASMGEN and use CODEGEN
  1660.  
  1661. almost exclusively.
  1662.  
  1663.      SOURCER, from V Communications of San Jose, California, bats
  1664.  
  1665. cleanup for me.  It understands the entire 80x8x family through the 486,
  1666.  
  1667. including the math coprocessor instructions and the V20 and V30.  We'll
  1668.  
  1669. sell you a copy for one hundred dollars.
  1670.  
  1671.      SOURCER requires at least 448K, would like more, and will use up
  1672.  
  1673. to 2 MEG of EMS if it can get it.  With 2 MEG of EMS, SOURCER can
  1674.  
  1675. disassemble an executable of perhaps 400K.  Of course, it will take all
  1676.  
  1677. night to do it, the output file will be greater than 6 MEG in size, and
  1678.  
  1679. you'll spend several years analyzing the result.
  1680.  
  1681.      SOURCER's opening screen shows you a sample of how your listing
  1682.  
  1683. will be formated.  The various option switches can be altered and the
  1684.  
  1685. effect observed immediatly.  Mostly superficial gloss, but it is a nice
  1686.  
  1687. touch.
  1688.  
  1689.      Most of the listing options control things like the case of the
  1690.  
  1691. output and whether tabs or spaces are used to align columns.
  1692.  
  1693.      SOURCER optionally puts three types of comments in the output
  1694.  
  1695. file, each of which can be controlled separatly.  The first type of
  1696.  
  1697. comment explains what each instruction does--almost useless.  The second
  1698.  
  1699. type tells what the system calls and I/O port accesses do--very handy.
  1700.  
  1701. The third tells you what is at a referenced memory location--seems really
  1702.  
  1703. usefull, but somehow, I hardly ever use the information.
  1704.  
  1705.      The listing formats fall into two broad paradigms.  One paradigm
  1706.  
  1707. is that of a source file--pure assembly language, ready to be input to
  1708.  
  1709. an assembler.  It's not very useful if one is the least bit mistrustful
  1710.  
  1711. of the code vs data decisions of the disassembler.
  1712.  
  1713.      What with self modifying code and other obstacles to analysis, I'm
  1714.  
  1715. very mistrustful of any automated analysis of machine language.
  1716.  
  1717.      The other paradigm is of a listing file produced by an assembler.
  1718.  
  1719. The offsets, actual code bytes, and optionally the segment are placed
  1720.  
  1721. at the start of a line, followed by the assembly language source.
  1722.  
  1723.      This is sort of awkward when using an editor to browse through the
  1724.  
  1725. output.  Most disassemblers put the source code first and the machine
  1726.  
  1727. language at the end of a line, where it is easy to ignore unless it is
  1728.  
  1729. neeeded.
  1730.  
  1731.      SOURCER's output can't be trusted either.  SOURCER does a partial
  1732.  
  1733. simulation of the machine language to be analyzed.  Apparently system
  1734.  
  1735. calls and most stores into memory are not actually performed.  Stores
  1736.  
  1737. of segment registers are actually performed so that their contents can
  1738.  
  1739. be more accurately tracked.
  1740.  
  1741.      If some of the loads and stores of segment registers are indirect,
  1742.  
  1743. SOURCER can become confused about their contents.  When an uncertain
  1744.  
  1745. segment register is used in the address of another segment register
  1746.  
  1747. store, the store can land anywhere, including on top of code.  This
  1748.  
  1749. stepped on code then will be erroneously disassembled and the displayed
  1750.  
  1751. machine language will agree with the incorrect disassembly.
  1752.  
  1753.      The three times I talked to V Communications' tech support people,
  1754.  
  1755. I got astonishingly prompt satisfaction.  The first time I only had
  1756.  
  1757. questions and got immediate, clear answers.  The second time I called
  1758.  
  1759. about an apparent bug.  Although the explaination I got of the cause of
  1760.  
  1761. the bug was incoherent, the bug fix arrived by UPS Next Day Air.  The
  1762.  
  1763. third call was also about an apparent bug.  It took them less an hour
  1764.  
  1765. to locate the cause of the anomaly and to call me back with an
  1766.  
  1767. explaination and a work around.
  1768.  
  1769.      SOURCER uses a .def file to allow the user to control the disassembly
  1770.  
  1771. process.  Its format and options are so elaborate that I haven't been
  1772.  
  1773. tempted to fool with it.  From version 1.87 to version 3.04, the portion
  1774.  
  1775. of the manual that describes the .def file has tripled in size.
  1776.  
  1777.      The latest version of SOURCER emits a file in the .def format that
  1778.  
  1779. contains the information that it has deduced, rightly or wrongly, about
  1780.  
  1781. the input file.  The user can modify this file rather than try to create
  1782.  
  1783. one of the correct format from scratch.
  1784.  
  1785.      This leads me to think that I'm not the only user that thinks that
  1786.  
  1787. the .def file is too much trouble.
  1788.  
  1789.      I suspect that all the BIOS Preprocessor option to SOURCER does is
  1790.  
  1791. analyze the interrupt vector table and the DOS data area and use the
  1792.  
  1793. information to produce a .def file for the requested ROM.
  1794.  
  1795.      In summary, SOURCER is a heavy hitter, but should only be purchased
  1796.  
  1797. and used if CODEGEN and ASMGEN are both inadequate for the disassembly
  1798.  
  1799. task at hand.
  1800.  
  1801.      The most likely way that would happen is if the machine language
  1802.  
  1803. file is greater than about 100K.  In that case, it would take you a year
  1804.  
  1805. to do the analysis, and you should pause and wonder if what you stand
  1806.  
  1807. to gain is worth the effort.
  1808.  
  1809.      If the failure of CODEGEN and ASMGEN is due to elaborate
  1810.  
  1811. segmentation and its attendant relocation table, then SOURCER is the
  1812.  
  1813. proper tool, but it should be used with suspicion.
  1814.  
  1815.                        LEARNING ASSEMBLY LANGUAGE
  1816.  
  1817.      The VISIBLE COMPUTER: 8088 is an assembly language tutorial
  1818.  
  1819. intended for people who know some high level programming language.
  1820.  
  1821. It consists of a 350 page book and a companion disk containing a
  1822.  
  1823. simulator/debugger and a lot of demonstration programs used in the
  1824.  
  1825. book.  It is manufactured by Software Masters of Bryan, Texas.  It
  1826.  
  1827. costs seventy-five dollars.
  1828.  
  1829.      While the book lists BASIC as a prerequisite, acquaintance with
  1830.  
  1831. any high level procedural language will do.  (FORTRAN, PASCAL, COBOL,
  1832.  
  1833. C, even DBASE, etc.)
  1834.  
  1835.      The book is excellent.  I have never seen as clear an introduction
  1836.  
  1837. to the subject of assembly language.  I wish the books I had to learn
  1838.  
  1839. from had been as lucid.
  1840.  
  1841.      The book does have one systematic flaw, however.  The author is
  1842.  
  1843. a user of the principle that "a little inaccuracy saves a world of
  1844.  
  1845. explanation."  I frequently encountered statements that were only
  1846.  
  1847. true most of the time or only true in the particular context.
  1848.  
  1849. Sometimes the author expands and corrects himself later, and sometimes
  1850.  
  1851. he doesn't.
  1852.  
  1853.      The best(worst?) example of this is his discussion of signed
  1854.  
  1855. arithmetic.  He starts to introduce sign and magnitude notation.  He
  1856.  
  1857. then anounces that it doesn't work and proceeds to demonstrate this
  1858.  
  1859. by doing unsigned arithmetic on a pair of sign and magnitude numbers.
  1860.  
  1861. Hardly a fair test.
  1862.  
  1863.      The choice of number systems is made by a machine designer on the
  1864.  
  1865. basis of what he thinks is the most cost effective way to implement
  1866.  
  1867. the needed functions.  The hardware types tell me that sign and
  1868.  
  1869. magnitude tends not to be used because designing the arithmetic unit
  1870.  
  1871. is a real hassle.  There are other representions possible and some,
  1872.  
  1873. such as one's complement, are often used.
  1874.  
  1875.      The designers of micro processors tend to chose two's complement
  1876.  
  1877. because they can implement it and unsigned arithmetic with a single
  1878.  
  1879. adder, thus using fewer gates on a very small piece of silicon.  The
  1880.  
  1881. arithimetic produces exactly the same bit patterns in both cases.  The
  1882.  
  1883. only difference is in the meaning of the sign bit and the overflow and
  1884.  
  1885. carry flags.  The needed status information for both systems is produced
  1886.  
  1887. and the programmer simply tests the flags that are meaningful for
  1888.  
  1889. whichever system he is using.
  1890.  
  1891.      So, you should keep in mind that everything you learn from the
  1892.  
  1893. VISIBLE COMPUTER may only be an approximation of the real situation.
  1894.  
  1895. But then that is true of everything you learn in life, also.  The
  1896.  
  1897. approximations won't betray you badly, if you stick to machines based
  1898.  
  1899. on the 80x8x family of chips.
  1900.  
  1901.      The program on the disk, TVC.EXE, is a combination simulator/
  1902.  
  1903. debugger.  The simulator features a nifty animation of an 8088.
  1904.  
  1905.      The upper part of the animation displays the contents of all the
  1906.  
  1907. 8088 registers that are visible to an assembly language programmer.
  1908.  
  1909. The lower part displays the registers that are invisible to the
  1910.  
  1911. programmer and that perform such functions as buffering the data and
  1912.  
  1913. addresses going to and from memory.
  1914.  
  1915.      The animation shows the various steps of instruction fetch,
  1916.  
  1917. instruction decode, operand fetch, et cetra.  It is good demonstration
  1918.  
  1919. tool for the examples included with the book.
  1920.  
  1921.      The animation, unfortunatly, is another example of the half truth
  1922.  
  1923. telling that I was complaining about.  The programmer visible registers
  1924.  
  1925. are exactly as described.  They have to be, they are part of the
  1926.  
  1927. definition of an 8088.  The programmer invisible registers must exist
  1928.  
  1929. and must have something like the arrangement and properties shown.
  1930.  
  1931.      While the author volunteers that the names he gave the programmer
  1932.  
  1933. invisible registers are bogus, he doesn't make clear that the arrangement
  1934.  
  1935. and properties of those registers are also only educated guesses on his
  1936.  
  1937. part.
  1938.  
  1939.      Chip (and mainframe) manufacturers don't like to publish internal
  1940.  
  1941. details of their machines' workings, in part because they want the
  1942.  
  1943. freedom to change those details.  How did the author know the exact
  1944.  
  1945. arrangement of those registers?
  1946.  
  1947.      Let's suppose that he somehow obtained exact information about the
  1948.  
  1949. invisible register set and accurately incorporated it into his animation.
  1950.  
  1951. The manufacturer still has the freedom to change the internal workings
  1952.  
  1953. of his chip, for improvements, special variations, or because he just
  1954.  
  1955. feels like it.  In particular, such changes are part of the basis of new
  1956.  
  1957. members of the 80x8x family.
  1958.  
  1959.      There are a number of tests that a program can perform, involving
  1960.  
  1961. various meaningless operations, that allow a program to uniquely
  1962.  
  1963. identify which chip it is running on, sometimes down to the revision
  1964.  
  1965. level of the microcode.  These tests are implicitly relying on the
  1966.  
  1967. details of the invisible registers and their properties that the test
  1968.  
  1969. authors think are fixed for particular chips in the family.
  1970.  
  1971.      As an example of such a meaningless operation, what happens if
  1972.  
  1973. you shift a sixteen bit register by 33 bits?  In the 8088 and the 8086
  1974.  
  1975. the register is cleared to zeros.  In the higher members of the family
  1976.  
  1977. the result is the same as shifting by one bit.  The designers wanted to
  1978.  
  1979. minimize the maximum time an instruction could take to execute.  Since
  1980.  
  1981. each bit shifted takes time (or hardware), and no one should ever want
  1982.  
  1983. to shift a sixteen bit register by more than sixteen bits, the higher
  1984.  
  1985. chips in the family only look at the bottom five bits of the shift count.
  1986.  
  1987.      I have seen such tests make erroneous identifications of chips.
  1988.  
  1989. Were we dealing with counterfeit parts?  Changes in the microcode that
  1990.  
  1991. Intel managed to keep secret?  Who knows?  Who cares?
  1992.  
  1993.      Anyway, the point of all this is:  Only the part of the simulation
  1994.  
  1995. that involves the programmer visible registers (the upper half of the
  1996.  
  1997. simulation) can be relied on to be accurate.
  1998.  
  1999.      TVC.EXE does not get along with Fansi Console.  If you use Fansi
  2000.  
  2001. Console, you will need to edit it out of CONFIG.SYS and reboot your
  2002.  
  2003. machine for your sessions with The Visible Computer.
  2004.  
  2005.      The program, TVC.EXE is touted as a programmer's tool in addition
  2006.  
  2007. to its pedigologic uses.  While it is more capable than the debugger
  2008.  
  2009. that comes bundled with DOS, it also occupies 77K, five times as much.
  2010.  
  2011. The improvement doesn't seem worth the extra RAM used or spending any
  2012.  
  2013. money at all for.
  2014.  
  2015.      If you need an assembler or a debugger, go with Turbo Assembler/
  2016.  
  2017. Debugger.  I'll be reviewing it next time.
  2018.  
  2019.      If you don't know assembly language, and want to learn, The
  2020.  
  2021. Visible Computer is the way to go.  It's the best tutorial on the
  2022.  
  2023. subject I've ever seen.
  2024.  
  2025.      Next time, I'll also be reviewing some books that I think are
  2026.  
  2027. useful.  If I don't run out of time or space, I'll also cover some
  2028.  
  2029. source code libraries and a couple of C compilers.
  2030.  
  2031.  
  2032.  
  2033.  
  2034.  
  2035.  
  2036.  
  2037.  
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.  
  2045.  
  2046.  
  2047.  
  2048.  
  2049.  
  2050.  
  2051.  
  2052.  
  2053.  
  2054.  
  2055.      This file COPYRIGHT 1990 BEST IN CLASS SOFTWARE.  Permission is
  2056.  
  2057. granted to copy and distribute this file subject to the condition that
  2058.  
  2059. it remain unaltered.
  2060.  
  2061.                          REVIEWER'S PHILOSOPHY
  2062.  
  2063.  
  2064.      I am an impatient old man.  I have been programming since the late
  2065.  
  2066. 1960's and made the switch to micros in the late 1970's.  I still wonder
  2067.  
  2068. why mainframe users tolerated the hostile user interfaces in that
  2069.  
  2070. environment, or why micro users tolerate the software bugs they are so
  2071.  
  2072. liberally supplied with.
  2073.  
  2074.      I am assuming my audience is fairly computer literate, knowing
  2075.  
  2076. what DOS is, what a TSR is, and at least the rudiments of some
  2077.  
  2078. programming language.  The business people tell me that their target
  2079.  
  2080. market is hackers and programmers.  They may change their minds at some
  2081.  
  2082. future time, and since they write my paychecks, I'll go along with that,
  2083.  
  2084. if it happens.
  2085.  
  2086.      The business people won't be telling me what to say, however.  My
  2087.  
  2088. agreement with them is that I get to say what I think, short of getting
  2089.  
  2090. them into serious legal difficulties.  If they don't like what I think,
  2091.  
  2092. they can only fire me.  Now, I've been fired or quit from more jobs than
  2093.  
  2094. most people have ever had, and I'm not afraid of being unemployed.  In
  2095.  
  2096. fact, except for minor worries like starvation, I like being unemployed.
  2097.  
  2098.      I'll give you the facts as I know them, but I've been known to
  2099.  
  2100. make mistakes.  If you catch me in an error or omission, please let me
  2101.  
  2102. know about it.  I can be reached at 1-800-777-9752
  2103.  
  2104.      My knowledge is limited.  It is likely that I'll miss some product
  2105.  
  2106. that should be included in a review. If you are aware of an ommission,
  2107.  
  2108. please inform me, including where I can obtain a copy and who the
  2109.  
  2110. business people can talk to about buying for resale.
  2111.  
  2112.      Anyway, the criteria I use to judge a package, in decreasing
  2113.  
  2114. order of importance, are:
  2115.  
  2116. 1)  UTILITY - How well does it serve its purpose?
  2117.  
  2118. 2)  CORRECTNESS - How many bugs, how serious?  What kind of
  2119.  
  2120.     compatibility problems are there?
  2121.  
  2122. 3)  INTERFACE - How easy is the user interface to learn and use?
  2123.  
  2124.     How clear and complete is the documentation?
  2125.  
  2126. 4)  PERFORMANCE - How fast is it?  How much disk space does it use?
  2127.  
  2128.     How much memory does it use?  What other resources does it require?
  2129.  
  2130. 5)  PRICE - What does it cost?  How much hassle is the copy protection,
  2131.  
  2132.     if any?
  2133.  
  2134. 6)  SUPPORT - How helpful are the tech support people?  How do you
  2135.  
  2136.     obtain bug fixes?  How about upgrades?
  2137.  
  2138.                BEST IN CLASS SOFTWARE COMPANY PHILOSOPHY
  2139.  
  2140.      Some dealers choose products to offer according to profit margins
  2141.  
  2142. regardless of quality or suitability.  While we don't intend to sell at
  2143.  
  2144. a loss, OUR GOAL IS TO OFFER ONLY THE BEST PRODUCTS FOR EACH PURPOSE.
  2145.  
  2146. In cases where there is no one best, we will offer the acceptable
  2147.  
  2148. products with an explanation of the pros and cons of each, allowing
  2149.  
  2150. the purchaser to pick that which best serves his needs.  If we are not
  2151.  
  2152. aware of any products in an area that we consider acceptable, we will
  2153.  
  2154. not offer any.
  2155.  
  2156.      We intend to focus on the negatives of each product more than
  2157.  
  2158. most dealers do.  We believe that a prospective buyer needs to be
  2159.  
  2160. aware of the weaknesses as well as the strengths of a product if he
  2161.  
  2162. is going to make an informed decision and most dealers and reviewers
  2163.  
  2164. gloss over the weakness of a product more than they should.
  2165.  
  2166.      We will be constantly reviewing our choices to see if they have
  2167.  
  2168. been superceeded by other products.  If you know of a product that we
  2169.  
  2170. should be carrying, or if you know of some bug or problem with our
  2171.  
  2172. recommended product that we missed, feel free to call David L Williams
  2173.  
  2174. at 1-800-777-9752.
  2175.  
  2176.                           BEST IN CLASS SOFTWARE                ORDER FORM
  2177.                               1-800-777-9752                  SEP 24, 1990
  2178.  
  2179. Your name:                              Your shipping address:
  2180.  
  2181. ___________________________________     __________________________________
  2182.  
  2183. Your daytime phone number:              __________________________________
  2184.  
  2185. ___________________________________     __________________________________
  2186.  
  2187.                                         __________________________________
  2188.  
  2189.  
  2190.  
  2191. QUANTITY                PRODUCT                         PRICE    TOTALS
  2192.  
  2193. ____    WRITE-GUARD   .  .  .  .  .  .  .  .  .  .  .   $75.00  __________
  2194.  
  2195. ____    ASMGEN  .  .  .  .  .  .  .  .  .  .  .  .  .   $10.00  __________
  2196.  
  2197. ____    CODEGEN .  .  .  .  .  .  .  .  .  .  .  .  .   $30.00  __________
  2198.  
  2199. ____    SOURCER .  .  .  .  .  .  .  .  .  .  .  .  .  $100.00  __________
  2200.  
  2201. ____    SOURCER with BIOS PREPROCESSOR  .  .  .  .  .  $140.00  __________
  2202.  
  2203. ____    VISIBLE COMPUTER 8088  .  .  .  .  .  .  .  .   $75.00  __________
  2204.  
  2205. ____    VISIBLE COMPUTER 80286 .  .  .  .  .  .  .  .   $85.00  __________
  2206.  
  2207. ____    FANSI CONSOLE .  .  .  .  .  .  .  .  .  .  .   $70.00  __________
  2208.  
  2209. ____    FANSI CONSOLE with TECHNICAL REFERENCE   .  .  $110.00  __________
  2210.  
  2211. ____    OPT-TECH SORT/MERGE .  .  .  .  .  .  .  .  .  $130.00  __________
  2212.  
  2213. ____    POWER C COMPILER .  .  .  .  .  .  .  .  .  .   $20.00  __________
  2214.  
  2215. ____    POWER C LIBRARY SOURCE .  .  .  .  .  .  .  .   $10.00  __________
  2216.  
  2217. ____    POWER C BCD BUSINESS MATH .  .  .  .  .  .  .   $10.00  __________
  2218.  
  2219. ____    POWER CTRACE DEBUGGER  .  .  .  .  .  .  .  .   $20.00  __________
  2220.  
  2221. ____    C/DATABASE TOOLCHEST.  .  .  .  .  .  .  .  .   $20.00  __________
  2222.  
  2223. ____    C/DATABASE LIBRARY SOURCE .  .  .  .  .  .  .   $10.00  __________
  2224.  
  2225. ____    C/UTILITIES TOOLCHEST  .  .  .  .  .  .  .  .   $20.00  __________
  2226.  
  2227. ____    C/UTILITIES TEXT PROCESSING UTILITIES SOURCE    $10.00  __________
  2228.  
  2229. ____    C/UTILITIES FILE MANAGEMENT UTILITIES SOURCE    $10.00  __________
  2230.  
  2231. ____    C/UTILITIES BORNE SHELL SOURCE  .  .  .  .  .   $10.00  __________
  2232.  
  2233.                                                     Sub total   __________
  2234.  
  2235.                    Less 4% if not paying with a credit card.    __________
  2236.  
  2237.                                                                 __________
  2238.  
  2239.                  Texas residents please add 7.75% sales tax     __________
  2240.  
  2241.                                                                 __________
  2242.  
  2243.                                         Shipping and handling       2. 0 0
  2244.  
  2245.                                                         Total   __________
  2246.  
  2247. If you are paying by VISA or MASTERCARD, we need more information:
  2248.  
  2249. Card holder's name:  ___________________________________
  2250.  
  2251. Card number:         ___________________________________
  2252.  
  2253. Expiration date:     ___________________________________
  2254.  
  2255. Your signature:      ___________________________________
  2256.  
  2257.  
  2258.                             FINE PRINT DEPARTMENT
  2259.  
  2260.    We usually ship UPS ground unless you specify otherwise, in which
  2261.    case we'll want to charge you more for shipping and handling.
  2262.  
  2263.    If your shipping address is a P O Box, we have no choice but to
  2264.    ship via the post office, at your risk, of course.
  2265.  
  2266.    Prices change.  If this order form is dated more than a month or
  2267.    two ago, you should call us at 1-800-777-9752 to confirm our
  2268.    prices and other policies.
  2269.  
  2270.  
  2271.                     Please send this order form to:
  2272.  
  2273.                        BEST IN CLASS SOFTWARE
  2274.                        142 1/2 W. San Antonio St
  2275.                        New Braunfels, TX  78130
  2276.  
  2277.                            1-800-777-9752
  2278.  
  2279.  
  2280.  
  2281.  
  2282.   Another file downloaded from:   
  2283.  
  2284.          !
  2285.         -$-             & the Temple of the Screaming Electron
  2286.          !    *                    Walnut Creek, CA
  2287.    +    /^\   |
  2288.    !    | |/\/^\  _^_     2400/1200/300 baud  (415) 935-5845  
  2289.   /^\  /   @ |  \/_-_\            Jeff Hunter, Sysop
  2290.   |@ \_| @     @|- - -|                                  \   
  2291.   |  | |    /^\ |  _  |                  - - - - - - - - - * 
  2292.   |___/_\___|_|_|_(_)_|       Aaaaaeeeeeeeeeeeeeeeeee!   /   
  2293.  
  2294.        Specializing in conversations, E-Mail, obscure information,
  2295.    entertainment, the arts, politics, futurism, thoughtful discussion, 
  2296.           insane speculation, and wild rumours. An ALL-TEXT BBS.
  2297.  
  2298.                          "Raw Data for Raw Nerves." 
  2299.  
  2300.