                                Lake Tahoe
                            Underground Digest
                             Volume I Issue 1
                        Friday February 11, 1994

In This Issue Of Lake Tahoe Underground Digest You Will Find A Copy Of A
Review Of The Famous Jeruselem B.

Issues of LTUD can also be found on HeLm'S hOlD bBs under a special access
File area entitled LTUD. Contact Lothor for access. HeLm'S hOlD bBs
(916) 542-HELM. (TeMpOrArIlY dOwN)

LAKE TAHOE UNDERGROUND DIGEST is an open forum dedicated to sharing
information among computerists and to the presentation and debate of
diverse views.  LTUD material may  be reprinted as long as the source
is cited.  Some authors do copyright their material, and they should
be contacted for reprint permission.  It is assumed that non-personal
mail to the moderators may be reprinted unless otherwise specified.
Readers are encouraged to submit reasoned articles relating to
computer culture and communication.  Articles are preferred to short
responses.  Please avoid quoting previous posts unless absolutely
necessary.

DISCLAIMER: The views represented herein do not necessarily represent
            the views of the moderators. Digest contributors assume all
            responsibility for ensuring that articles submitted do not
            violate copyright protections.
______________________________________________________________________________

                  THE JERUSALEM B VIRUS--A PRODUCT REVIEW


     Why in the world would anyone write a product review of a computer

virus?  To start with, I have become disgusted with all the hype and

bullshit I have been hearing about computer viruses.  I hope to deflate

a little of it.

     Secondly, to grab your attention.  This review will segue into a

review of some products I think you will find useful.  I do, after all,

work for a marketing company.

     What is a computer virus, anyway?  It is a program, or section of

code that reproduces itself.  Anything else it does, such as scrambling

a disk or a screen, is incidental to the definition.

     This definition is a bit arbitrary, but it will suffice for the

present.  I am willing to discuss the finer distinctions between viruses,

worms, trojans, mere bugs, etc.--some other time.

     Viruses, as defined above, have been around for a while.  A

disgruntled operator in a mainframe installation that I worked at in

the mid 1970's submitted a job that created and submitted two copies

of itself and then terminated.  It filled the scheduler's queue and

crashed the system.

     In response, the systems people added a bit to the job information

table that indicated whether a job had been submitted from outside the

system or had been submitted by another job.  The scheduler would not

allow a job that had been created by another job to create any jobs.

     I believe that all this happened in 1972, but it may have been

earlier.

     Anyway, on with the review.  The virus arrived in town hiding in

a pirate copy of DR HALO.  One of its victims told me that it was the

JERUSALEM B virus, and gave me the original disk.

     I made sure that my backups were current and that my hard drive

was write disabled, and went to work.  I executed the suspect copy of

DR HALO and watched my available memory shrink by 1808 bytes.  Something

grabbed INT 21 and INT 08.  I watched as something tried to write to

my hard drive every time an executable was loaded from it.

     I created a five byte do nothing .com file, and executed it.  The

virus took the bait and I had an 1818 byte .com file consisting of the

1808 byte virus, my original 5 bytes, and a five byte signature string.

     I disassembled this using ASMGEN and studied the resulting source

code.

     The virus is present at the beginning of .com files with the

original .com image displaced by the length of the virus.  In the case

of .exe files, it is tacked on to the end with the .exe header altered

to point CS:IP and SS:SP to the virus.

     When an infected program is run, the virus gets control first.

It checks for an already resident copy of itself.  If it doesn't find

one, it TSRs and then loads and runs another copy of the infected program.

It uses its copy of the environment to find the name of the disk copy

of the infected program.  DOS 1.x and 2.x do not put this information

in the environment, so the second copy will not run.  It will appear as

if the infected program terminated without doing anything.

     If the virus in an infected .com file finds another copy of itself

already TSR, it asks the resident copy to relocate the original .com

image to its proper place and execute it.  But the AX register is

corrupted in the process, which will cause many old FCB based programs

to incorrectly parse the command line.

     There is code present to provide similar services to infected .exe

files, but it appears to go unused.  The .exe inhabiting virus simply

relocates the CS and SS values saved within itself during the infection

process and loads CS:IP and SS:SP with the values the loader would have

supplied to an uninfected file.  Since the infection process preserved

the original relocation table, nothing else is needed.

     The resident copy does several things.  On Friday the 13ths its

behavior is simple.  It grabs INT 21 and watches for EXEC requests

(AX == 4B00).  When one occurs, it first issues a delete (AH == 41)

with the same parameters, then passes on the original request, which

will then fail, since the requested file will be gone.

     Except on Friday the 13ths, the virus grabs INT 08.  After about

29 minutes, it scrolls a window on the screen and starts wasting CPU

time.  It does not adapt the amount of waste to the type of processor,

so it would be a lot more noticable on a garden variety PC than on a

fast AT type machine.

     The virus uses a REP LODSB instruction to waste the time.  The

386 and 486 are a lot fussier than the 086, 186, and 286 about what

instructions you are allowed to use a REP prefix with, so I suspect

that this would simply crash a 386 or 486.  I don't own one and nobody

would let me use theirs to do the experiment, so I can't say this with

certainty.

     On non Friday the 13ths the virus also grabs INT 21 and watches

for EXEC requests, but its behavior is more complex.

     When an EXEC request occurs, the virus first checks to see if the

requested file is named COMMAND.COM.  If it is, the virus merely passes

the request on to DOS.

     If the file is not named COMMAND.COM, the virus next looks for its

signature in the last five bytes of the requested file.  If it finds the

signature, it also passes the request on to DOS.

     Finally, if the signature is missing, the virus checks to see if

there is enough space on the disk that the requested file is on to hold

another copy of the virus.  If there is not sufficient space, it just

passes the request on to DOS.

     If there is enough space, and the signature is missing, then the

virus takes different courses depending on whether the file name ends

in 'M' or not. (indicating whether it is .com or .exe)

     For a .com file, the virus allocates a 64K buffer, copies itself

into it, copies the .com file into the buffer after itself, and adds

the five byte signature to the end.  It next writes the contents back

out to the original .com file, taking care to preserve the file's date

and time.  It deallocates the buffer and finally passes the original

EXEC request on to DOS.

     For .exe files, it copies itself to the end of the file, using the

length in the header instead of the DOS file size.  This means that any

overlays or other information unaccounted for by that header length

field will be corrupted.  It also neglects to add the signature string

to the end.  This means that superinfection will occur in .exe files.

     Superinfection is multiple copies of some virus becoming attached

to some resource.  If a virus fails to detect that a file is already

infected with itself and infects it again, then superinfection has occured.

If a virus fails to notice that a copy of itself is already TSR in an

MS-DOS machine and TSRs again, then that is also superinfection.

     The actual viral code is interesting.  I think I see the work of

two programmers.

     The bulk of the code is busy and inefficient.  For instance, in

preparation for TSR, the virus relocates itself to just below its PSP,

even if it is in a .com file and is already there.  In another case, during

analysis of the filename passed by the EXEC call, it goes to the trouble

of scanning the filename string each of the three times it needs to find

the end of string instead of saving a pointer to it the first time.

     On the other hand, most of the code that does the actual infecting

of .com and .exe files is straight forward and economically written.

     The virus has a number of bugs in it, in addition to the ones

mentioned in the behavioral summary above.  But, once you have something

that half works, how do you safely test it?

     The virus attempts too many pranks--destruction of files, screen

games, and time wasting.  If it had attempted only one thing, it would

have been more effective.  If it had only played with the screen, I

would even have thought it was funny.

     It looks to me like the virus author is some adolesent who

either disassembled and modified an already existing virus or got a

more capable programmer to assist him (or her).

     In summary, this is a third generation virus--it tries to avoid

superinfection, it infects .com files (easy) and .exe files (not so

easy), and it avoids the easy to avoid virus pitfalls, namely file

date and time changes and COMMAND.COM attacks.  It is however, bug

ridden, and a nuisance, and not worth buying, no matter how low the

price.

                           HYPE AND BULLSHIT

     Humor aside, I think the anti virus authorship rhetoric has gotten

a little out of hand.  I hear politicians calling for mandatory prison

terms and some of the victims calling for the death penalty and worse.

     Virus authorship is simple criminal mischief, the moral equivalent

of throwing a rock and breaking a window.  Well, breaking a lot of

windows.

     The punishment should be proportional to the injury caused.  If a

virus crashes a hospital's patient monitoring computer and causes a

patient's death, then murder charges seem appropriate.  If a few copies

of pirate software are the only casulties, then it is hard to justify

punishing the author at all.

     Let's take a moment to examine the victim's role in all of this.

It seems reasonable to bemoan the loss of innocence caused by the

occurance of computer crime, but it was inevitable.  Crying about it

instead of taking appropriate measures, is largely a waste of time.

People shouldn't steal cars either, but most of us don't bother to cry

about it, we take sensible precautions, ie., we lock our cars.

     The loss of innocence had already happened anyway.  The story

about the bank programmer truncating interest calculations and adding

the residue to his own account balance was already old when I first

heard it in 1970.

     Now, I have no good idea whether the victim of this virus was

typical or not.  Let's look at his situation, though.  He was burned

by what he thought was a pirate copy of DR HALO.  This means he was

knowingly committing a crime at the time of his misfortune.  He had no

backups.  Luckily for him, the virus didn't attack data.  It seems he

was in the habit of working with his distribution disks, and most of

them were infected.  Somehow, I have a hard time feeling sorry for him.

     On to a very brief discussion of hype.

     The only thing I can say about newspapers and TV is that I worry

that their coverage of the rest of the news is as accurate as their

coverage of technical issues.

     My opinion of the legislature's and other political grandstanders'

words and actions is unprintable.

     A while back, I read a book on computer viruses.  The book

consisted of a discussion of viruses and their properties, aimed at not

very technical users.  It concluded with interviews of several computer

virus and computer security experts.

     The author, who seemed to be a technical writer with no deep

understanding of computers, at least had his facts straight.  This is

more than can be said for some of the experts.

     One expert in particular, hypeing his own antiviral product,

said that "sooner or later the virus has to use INT 13 and then we've

got it!".  I don't know about you, Mr. Expert, but I am perfectly

capable of talking directly to the host adaptor using IN and OUT

instructions and DMA transfers.

     This doesn't mean that the expert's product was valueless, just

not perfect.  He was stupid or dishonest to claim that it was.

     The expert's product was valuable in three ways.  First, it

raised the level of skill needed to author viruses capable of

attacking machines that his product protected.  Second, it made the

job of the remaining authors more difficult.  Third, in a few cases,

it will have made the job effectively impossible.

     The kid who wrote the virus I disassembled is not a careful

enough programmer to write the necessary code.  He probably will be

someday, but hopefully by then, the thrill of watching the glass break

will be gone, and he will find more constructive things to do with his

skills and time.

     If I rose to the expert's bait, I would have to write seperate

subroutines for the floppy controller, the Western Digital 1002, the

Western Digital 1003, the XEBEC controller, . . .  My virus would be

getting big and hard to hide.

     Additionally, my virus would die when it met the Alabama Tool and

Die Works floppy controller or the Chinese People's Collective hard

disk controller, because I never heard of those products and couldn't

prepare my virus for its encounter with them.

     The virus/antiviral contest is an arms race just like the one

between car thieves and car owners or the one between military aircraft

and anti-aircraft missiles.  One side takes a measure, the other takes

a countermeasure, the first takes a counter-countermeasure, and so on,

until one side or the other runs out of time, money, patience, or some

other resource.

     Given that there are jerks out there who create viruses, what should

we as users, authors, manufacturers, and distributers do about it?

     My advice to manufacturers and distributers is to only sell

software on born write protected floppies.  I mean, for instance, that

5.25 inch floppies should have no write protect notch at all.

     Authors, I recommend that you include some sort of integrity

checking code in the software you write.  Some sort of checksumming

would go a long way toward making life difficult for virus authors.

Use your immagination, if we all use the same technique, then virus

authors will have an easy time adapting their "product" to defeat it.

     Users, I'll skip all the usual warnings about pirate software and

the importance of backups.  My first recommendation is get and use some

sort of hardware write protection for your hard drive.  Now it just

so happens that the company I work for, Best in Class Software, sells

such a device.  I'll be reviewing it below.

     Second, you should consider getting or writing some sort of

surveillance program to watch for really suspicious events.  I will

talk about the issues I think are involved, but I won't actually make

any recommendations.

                       HARDWARE WRITE PROTECTION

     The hard disk write protection is called WRITE-GUARD and is

manufactured by Arrick Computer Products in Euless, Texas.  It costs

about eighty dollars.  It consists of a control box outside of the

computer chassis connected by a cable to a printed circuit board that

plugs into the disk control cable and in turn is plugged into by the

edge connector on the back of the hard drive.

     The control box has a switch that enables and disables writing

to the protected drive.  If a write attempt occurs while the switch

is set to write protect, a write fault signal is sent back to the host

adaptor, the Write-Guard emits a nasty sounding beep, and a red LED

lights and stays lit until the reset button on the control box is

pressed.

     The manual assures the reader a quick, painless installation.

Don't you believe it!  Unless you have the skills and tools of the

back room technician at your local computer store, get someone who

does to help you.

     The location and orientation of the edge connectors on the back

of hard drives is variable.  The first time I installed a Write-Guard,

the connector on the drive was close enough to the side of the drive

bay that the Write-Guard wouldn't fit.  Fortunatly the amount of the

mismatch was less than the size of the little ears that were left when

they broke up the larger board during manufacture.  A file solved the

problem.

     In the second installation, the orientation of the disk's connector

was reversed top-to-bottom with respect to the first.  This caused the

edge connector on the Write-Guard to bump against the mother board.

Again, I was lucky, there were spare mounting holes on the drive bay

sides and I was able to raise the drive to a non-standard position

allowing the Write-Guard to clear the motherboard.

     The position of the drive's edge connector with respect to the

drive's case also caused the jumpers and other components on the

Write-Guard's PC board to press up against the drive's metal case.

A little electrical tape solved that problem.

     Unfortunatly, the second unit was also defective.

     As apparently, was the third.

     Arrick's technician says that the jumpers were set wrong on both

devices, and that the third one was actually ok.

     Now the manual shows the jumper setting on page five.  Beside

them is penciled the phrase "SEE SHEET!".  There is an errata sheet

that shows jumper settings.  All four units are identical in this

respect. (unit number four is still offstage)

     The first three units arrived with their jumpers set according

to the errata sheet.  I always check jumper settings.  The first one

worked fine that way.

     The fourth unit arrived with its jumpers set according to the

original manual and worked fine that way.  It did however, have the

same errata sheet as the first three.  It also failed if the jumpers

were changed to conform to the errata sheet's specification.

     I've encountered products that were more technician hostile than

that, but not in the last several years.  I recommend expecting

mechanical and electrical problems during installation.  If you have

problems with your blood pressure, get someone else to do the installation

for you.  Test the device before you close the computer's case.

     My recommendation to Arrick is to redo the design, in particular

changing three things.

     First, replace the on board connector with one on about six inches

of ribbon cable.  This will give the user or technician the freedom to

deal with all the variations in geometry of drives and chassis out in

the field.

     Second, encapsulate the PC board so that the user or technician

doesn't have to worry about the jumpers or component leads touching

anything metal.  You might epoxy the board and move the jumpers'

functions into the control box.

     Third, make the manual and the hardware consistantly agree.

Boy, am I ever full of advice.  I usually only have this much advice

for paying clients.

     Once you have the Write-Guard in and working, the protection

available to you is immense, far greater than software alone can

honestly claim to provide.  The protection is not absolute.  You

presumably need to write to the hard drive sometime.  Unless you can

throw the enable/disable switch with millisecond speed and precision,

those times are windows of vulnerability.  I'm not losing any sleep

over it yet.

     There are compatibility problems, some of which can compromise

security.  The problems aren't Arrick's fault, but since the Write-Guard

is what you'd be adding to your system, Arrick will end up getting the

blame.

     The typical problem occurs thus:  The Write-Guard is write disabled.

A program, say an editor or compiler, wants to create and use a scratch

file.  If the program has installed its own INT 24 handler, you may not

even get the chance to tell it to retry the operation.

     But it gets worse.  DOS disk writes are usually three part

operations, the actual data write, the FAT update, and the directory

update.

     Some versions of DOS will ask you "Abort, Retry, or Ignore" for

each part of the operation.  If you give different answers, or enable

writing partway through the sequence, the data, the FAT, and the

directory will no longer be in correspondence.  The result:  lost

clusters, cross linked FAT chains, files with the wrong data in them,

etc.  Oh well, your backups were current, weren't they?

     Other DOS versions attempt all three parts of the operation

before reporting the problem and asking the user for guidance.  I

wonder what happens if the failure is due to some sort of intermittent

fault and some of the parts of the operation succeed and other parts

fail.  Oh well, my backups are current.

     I can think of three and a half work arounds for this class of

problem.  The first is simple.  Leave the Write-Guard in the write

enabled state except while testing suspected software.  This is

adequate for most purposes.  It is only historical accident that this

is not the solution I use.

     The half work around is to keep the Write-Guard write disabled

most of the time, work from floppies, and use the hard drive mainly for

program storage.  This defeats most of the purposes for having a hard

drive, but you might be in a situation where this is the way to go.

     The second work around is to have two hard drives, one protected

and containing your programs, and work from the other, which contains

your data.

     The third work around is to keep the hard drive write disabled

most of the time, and work from a large ramdisk.  This, due to once

having been paid in sample EMS boards, is the solution I use.

     Ramdisks are wonderful.  They have an access time of perhaps a

millisecond.  They can be set to a known, although empty, state at the

push of a button.  Copy your work to ramdisk and forget about

fragmentation or other performance problems of hard drives.

     Now a real ramdisk; i.e., one that connects to a host adaptor card

and emulates the hardware interface of a hard drive, is frightfully

expensive.  An EMS based ramdisk costs about one tenth as much, is just

as fast, and is more flexable.  If you have any applications that can

use EMS directly, it can be made available to them simply by editing

the CONFIG.SYS file and rebooting the machine.

     Ramdisks do have their problems.  They cost more than hard drives

of equivalent capacity.  They are volatile.  Unless you have an

uninterruptable power supply, you are at the mercy of the drunk who is

going to knock over a power pole two blocks away as you complete keying

in a thousand line program.

     Additionally, if you are a hacker like me, when one of your

experiments goes awry, and you have to reboot the machine, there won't

be any pieces left to examine for clues to what went wrong.

                              OLD TROJANS

     I didn't get the Write-Guard for virus protection, although

having it gave me the nerve to tackle the first virus that came along.

There were three situations or incidents that convinced me that I

needed something like Write-Guard.

     In late 1986, there was a rumor going around that a certain

popular database package had a copy protection scheme that would trash

a hard drive if it thought it had been tricked.  This was particularly

worrisome since the two prior editions of that package had been quite

buggy.  I have never tolerated copy protected software on my own

machine, but when a client asks for a brand name, what can I do?

     Having heard the rumor, I followed the installation instructions

to the letter.  The installation went without a hitch.  I executed the

package to confirm that it was installed and working.  It came up and

gave me its standard prompt.  I quit out of the package and got

"General failure reading drive C:" instead of the C> prompt.

     To skip over all the unpleasant details, my ex-client's backups

were within a couple of days of being current, so the injury was less

than a thousand dollars.  She decided that life was too short to bother

suing either me or the manufacturer.

     The manufacturer dropped his copy protection a few months later,

making some statement about consumer wishes.  I think he was up to his

hips in lawsuits.

     I've still got the distribution disks.  Some year, when I've got

nothing else to do, I'm going to disassemble all the hidden and visible

files on them and publish what I find.

     The second situation occured during early 1987.  I was writing a

multitasking, 286 protected mode BIOS for the Western Digital 1003

disk controller.

     I wanted to use a separate controller for the test disk, so that

I would have to get whole port addresses wrong to accidently trash the

DOS disk in the testbed system.

     Unfortunatly, my client and I were not able to get the two WD1003's

to get along with each other and DOS in the testbed system.  We wound up

attaching the test hard drive to the same WD1003 as the DOS drive.  This

meant that a command sequence to write to the test drive differed by a

single bit from one that would write to the DOS disk.

     I never actually made the mistake, but I was pretty nervous until

I got the low level code debugged.  Some sort of write protection for

the DOS disk would have helped my nerves considerably.

     The third situation occured in early 1988.  I was evaluating

disassemblers, looking for a replacement for ASMGEN.  I ordered a

disassembler from company "R".  They sent me copy "R1".

     It didn't work, complaining that it was missing its message file.

The message file was visible in the directory listing, so I called

company R.  After I ran some experiments at R's direction, R decided

that the distribution floppy R1 came on was defective. They sent me

replacement copy "R2", which worked.

     Now, I have never seen a floppy or a hard drive with defective

media that didn't cause the controller to report missing address marks

or uncorrectable ECC errors, or something else real obvious.  It seems,

based on what I know about the way they work, that a misread that

doesn't cause a fault is very unlikely.  This excited my already

suspicious nature.

     I couldn't use DISKCOMP because some of R's experiments had

involved writing to R1's disk.  COMP thought all the files were

identical.

     I ran R1--still no good.  I ran R2--it now failed.  I did a

logical format of my hard drive and restored my backups.  R2 still

didn't work.  I did a physical format, a logical format, and a restore.

R2 now worked.  I ran R1 again. It failed again.  R2 not working.

Physical, logical, restore.  R2 works again.

     By now I had blown the better part of a day.  I didn't then have

the tools needed to find out what was being hidden on my hard disk

outside of DOS' file system, and where it was.  I had other things I

needed to be doing, so I did the physical, logical, restore process one

more time to clean up what ever R2 might have left behind, and RMA'd

both copies back to R.

     These three situations convinced me that I needed some sort of

hardware write protection for my harddrive.  While bungling the design

of one (my hardware skills extend to being able to read and sort of

understand schematics, but not to actual design), I stumbled over an

ad for the Arrick product.  I knew that I couldn't design and build one

for less than the eighty dollars that they wanted for theirs.  Except

for the installation difficulties, it has given me a couple of years

of trouble free service.

     I suspect that the sort of nonsense described in the first and

third examples above is fairly common.  The source of the rumor about

the database package told me a similar story about one of the DOS

multitaskers on the market.  This one allegedly only sought out and

destroyed copies of itself.

     Another incident happened after I had the Write-Guard.  I was

evaluating a CADD package that requires the user to supply his name

and company name the first time it is run.  While talking to a

technician about a peripherally related bug in the package, he

volunteered that the package recorded the information that it had

been initialized in the boot sector of the distribution disk.

     I sympathize with the desire of authors and manufacturers to get

paid for their work.  I prefer getting paid for my own work also.

     I don't think copy protection is the answer. (Not that I have

any idea what the answer is.)  Writing good code is hard enough to do

working within the environment provided by the operating system.  An

application programmer is asking for trouble by stepping outside of the

system, doing things like direct disk I/O, in order to match wits with

children who have time on their hands and nothing to lose.

                          SOFTWARE ANTIVIRALS

     I'm not recommending any of the software antivirals I've examined;

they all have what I consider to be fatal flaws.  Examining them, and

talking to the authors was interesting, though.  (I didn't tell them

that I was a reviewer.)

     All but one of the software antiviral packages included a program

that attempted to remove the virus from an infected program.  This was

surprising to me since a program that reproduces itself is capable of

enormous mischief, intentional or not.

     If I suspected even a single executable on a disk was infected by

a virus, I would do a physical format of the whole disk and fall back

to my most recent backup rather than take a chance on the infection

spreading inadvertantly.

     I asked one of the authors about this and he told me three things.

First, most victims don't have recent backups (no surprise there).

Second, the backups are usually contaminated.  (mild surprise, how can

one not notice a virus as ham handed as the ones I've heard about long

enough to take a backup?)  Third, most of the victims have copy protected

programs on the infected disk and can neither have taken backups of them,

nor restore them from the distribution disks (oh yeah, copy protection).

     I mistrust the class of people who get deeply involved in the

virus-antiviral contest.  The two camps need each other.  The more

varied and higher quality the supply of viruses is, the more demand

there is for antivirals.  The more time, energy, and ink spent on

antivirals, the more important virus authors are made to seem.

     Ross Greenberg, the author of the FLU_SHOT series of antivirals,

freely admits that people have occasionally turned FLU_SHOT into

trojans.

     The author of one antiviral told me that he also wrote viruses for

a federal agency that he was not at liberty to identify.

     The author of another antiviral told me that he had evidence that

yet another antiviral author was paying someone to develop new viruses.

     Quis custodiet ipsos custodes.  Who watches the watchmen?

     I would never trust someone else's software antiviral without

first disassembling and studying it.  I would prefer to write my own.

     Computer system integrity and security is a whole branch of

computer science by itself.  I'm not very knowledgeable in the subject,

but based on what I do know about it and MS-DOS machines, I'll give you

my thoughts.

     First of all, I doubt that perfect security is possible in any

computer system.

     The most heavily defended machine I have first hand knowledge of

was a Cyber 170 in a university environment back in 1982.  It had what

looked to me like unbeatable hardware support for protecting system

integrity.  The applications were not in the same address space as the

operating system.  In fact, the bulk of the operating system was not

even running on the same processor as the user jobs.  It had a staff

of full time programmers whose duties included patching the holes

discovered by users.  And yet the users knocked it over once or twice

a day.

     Software can never provide complete protection in MS-DOS systems.

As long as an application can do its own I/O, software can not prevent

the destruction or modification of files.  As long as applications can

read and write each other's memory, software can not prevent itself

from being analyzed or modified.

     Software can provide some protection and can powerfully assist

hardware in protecting your system from viruses, trojans, and bugs.

     Software does have some advantages over hardware.  It is much

easier to design than hardware of comparable complexity, and can be

modified quickly to counter new threats.

     Due to this, it is much harder for an attacker to anticipate the

nature of the software defenses it is going to encounter, even if there

will always be a way to overcome those defenses.

     I would never depend on software alone to protect my system.  I

would only use it as an adjunct to hardware.

     Software also can easily tell you more than hardware can.  The

Write-Guard will prevent a write to the hard disk and will tell you

that a write was attempted.  Software, if it hasn't been defeated, can

tell you which area of the disk the write was directed at, and whether

the attempt passed through DOS or was issued directly by an application.

     If you want to protect your system from the CIA, the KGB, or even

a computer science graduate student, then you're playing out of my

league.  I can't offer you any useful advice.

     The threats to my system that I consider significant are much

milder.  They are:  viruses, trojans, and garden variety bugs, both my

own and others'.  I regard copy protection schemes as a kind of trojan.

     What are we trying to protect anyway?  Probably not the running

program, since all we stand to lose is the time involved in rebooting

the machine and the time already invested in the current run.  Now if

you have programs that run for days at a time . . .

     What we probably want to protect is the programs and data on our

hard disks and floppies.  By successfully protecting our programs, we

will also hamper the spread of viruses to other machines.  We might also

inhibit some of the prank playing that goes on.

     The first line of defense is to prevent unwanted or unexpected

writes to the disk.  The Write-Guard is great for hard disks and write

protect tabs work for floppies.

     To distinguish an unwanted write from a legitimate but unexpected

write, you could write a little TSR that records each INT 13 request as

it occurs, and pops up and tells you all about the last one if it fails.

     You could then decide whether to write enable the Write-Guard and

choose "retry", or leave the Write-Guard write disabled and choose

"abort", "fail", "ignore", or even do a cold boot of your machine.

     The sorts of things that would cause me to reboot my machine are

attempts to write to the partition table or boot sector, or any write

attempt that did not pass through INT 13.  (The Write-Guard would sound

off, but my INT 13 surveilance wouldn't notice the fault.)

     The TSR could serve as foundation for a whole host of further

defenses, depending on how paranoid you are and how much trouble you

want to go to.

     Your TSR could attempt to authenticate the caller by examining his

return address on the stack.  Or you could keep track of entry and exit

from INT 21 and allow INT 13 calls to proceed only if an INT 21 call

that would plausably produce the current INT 13 call is in progress.

For example, there is no good reason for a INT 21 RENAME call to write

to the FAT.

     Your TSR could watch for any attemps to format the disk.

     The sector, head, and cylinder of write requests could be checked

against a table of addresses of the partition table, the boot sector,

and any files you wanted to protect.

     Your TSR could analyze the FAT and the directory tree to construct

the list of protected sectors.  It could then alert you to all attempts

to write to .exe, .com, or .bat files.

     You might want to prevent any use of INT 26, which could be used

to bypass the caller authentication mentioned above.

     All the software checks described above can be fooled by a program

that knows about them, or bypassed altogether by a program that talks

directly to the disk controller.

     You might want to implement whole second lines of defense.  The

above is probably plenty for ordinary bugs, and most viruses and trojans.

     An approach to a second line of defense might be to watch for events

that might indicate the presence of a virus or trojan without waiting

for the actual attack to occur.  Besides, the attack might be some blood

pressure altering prank rather than actual destruction of files.

     For example, I have heard of viruses that play pranks like

transposing digits of long numbers displayed on the screen.  The

seriousness of the threat posed by such games is dependant on your

personality type.  Assuming I wasn't worried about deadlines at the

time, I would be amused by my first encounter with such a program.

Of course, after I had my laugh, I would hunt down and obliterate all

copies of the offending program that I could find.

     If you are the kind of person who takes himself too seriously, or

tends to believe what the computer tells him, then such a program could

be a threat to your physical or mental health.

     Things to watch for are unexpected TSR requests and unexpected

grabbing of interrupts.  But a hostile program can TSR without issuing

a TSR request and it can intercept interrupts without modifying the

interrupt vector table.

     Another second line approach assumes the damage caused by an attack

or a bug will be partial or will develop slowly.  You could implement

some sort of integrity checking of key data structures or files on your

disk(s).

     The boot sector, the partition table, and most executables should

never change and could be checksummed.  The checksums could be verified

periodically or whenever one of these objects is about to be used.

     This should detect most infections before they have spread very

far.

     It would be nice to integrity check the in memory copies of

programs, especially DOS, but the structure of MS-DOS appears to make

that impractable.  Perhaps a cleverer programmer than I . . .

     There is a gaping hole in all of the above defenses.  How do you

protect the FAT?  There is so much legitimate writing to that small area,

that it would be easy to slip a joker into all that traffic.

     That is an argument for multiple defense strategies.  If you

sufficiently constrain the circumstances available to attack the FAT or

any other object, perhaps all attacks will trigger some alarm before they

can be carried out.  Of course, those constraints will hamper legitimate

activity as well.

     All of the above defenses, including the Write-Guard, can be

defeated by a competent, determined opponent.  No matter how hard you

work at it, you will never be able to rest completely easy.

     On the other hand, I've only implemented three of my own suggestions

for defense tactics listed above, only one in response to the viral threat.

I won't be beefing up my defenses any further, unless the threat becomes

more severe that I expect, or someone offers me a lot of money to do so.

     I think that it is important to keep all of this in perspective.

The threats are not currently severe enough to justify all the defensive

effort described above.  I do not think that they are going to become

that severe during the lifetime of MS-DOS.

     A better written operating system than MS-DOS could be much more

resistant to challenges to its integrity, even without hardware support.

When the successor to the MS-DOS machines appears, the virus-antiviral

contest is going to be a whole new game.

     It should be remembered that viruses, trojans, and bugs are just

obstacles in the way of getting useful work done and not something that

there is any direct benefit in dealing with.  Well ok, except for

recreation and education, there is no direct benefit.

     A software antiviral doesn't come free either.  It is going to

occupy some memory and consume some CPU cycles.

     For instance, if it checksums executables before they are run,

the table of checksums will occupy a possibly large block of memory,

and the execution of a requested program will be delayed by however

long it takes to compute the checksum.

     In addition, a resident antiviral is prey to all the conflicts

and compatibility problems of any other TSR.

     In summary, I don't think you should blindly put a lot of effort

into making your system virus proof.  You should take a realistic look

at the threat level and take cost effective action to protect yourself.

                             DISASSEMBLERS

     Disassembly is the translation of machine language to assembly

language.  In the 80x8x family of chips disassembly is a very tough

problem.

     The sources of difficulty are that the instruction formats are

intricate, the segmentation is confusing, and the same bytes can be

used as both instructions and data.

     In the 286 and up, the segment meanings are mode dependant, and

in protected mode, the segments are likely to be defined outside of

the program.

     In the 386 and up, and in some enhanced chips from second sources

such as the V20 and V30, the instruction formats are also mode dependent.

     I suspect that the general case of disassembly is equivalent to

Post's correspondence problem, and is therefore unsolvable.  Perhaps

one of my readers who likes the math, and whose last encounter with

theory was less than fifteen years ago, would like to prove or disprove

that conjecture.

     Fortunately, most real world programs are intended to run in real

mode, and are also written to the minimum common instruction set.  It

is bad programming practice to use the same object as both instructions

and data, so in the real world, it is done sparingly.  Therefore, most

real world cases are doable.

     Why bother to disassemble a program?  Well, that's how I learned

8088 assembly language.

     In 1984, one of my clients, a mail order house, wanted me to take

the ramdisk and print spooler that came bundled with a Taiwanese

multifunction board that they sold, fix the bugs, and translate the

messages into unbroken English.  Source code was not available.

     A kid I had taught Z80 assembly language gave me a copy of ASMGEN

that he had found on a bulletin board somewhere.  A hardware engineer

friend gave me a copy of Rector and Alexy's THE 8086 BOOK.  My client

gave me an assembler and I went to work.

     I don't recommend this approach in general.  I'd been programming

IBM PCs for a year or two already, and knew three other assembly

languages (or more, depending on how loosely you keep score).  For my

advice on learning 8088 assembly language, see my review of THE VISIBLE

COMPUTER, below.

     The most obvious but least mentioned reason to disassemble

programs is for purposes of industrial espionage.  Before self-righteous

people start moralizing at me, I'd like to point out that an anti-viral

author taking apart a virus and using the knowledge gained to improve

his product is an example of industrial espionage.  Unfortunatly, a

virus author taking apart an anti-viral and using the knowledge gained

to improve his product is also an example.

     There is no particular moral significance to spying.  The morality

or immorality springs from the methods, purposes, and effects.

     Clarification of documentation is a frequently mentioned purpose

that always sounds like bullshit to me.  I've actually used disassembly

for that purpose though.  When the Western Digital 1003 documentation

says "GAP 1 and 3 length determined by Sector Number Register contents

during formatting,"  and that's the only mention I can find of the use

of the Sector Number Register during formatting, I start disassembling

things to see how they actually use it.

     There can be forensic purposes for disassembly as well.  I know of

two court cases where what a program actually does is an issue and

source code is not available.

     In one of them, the defendant is accused of planting a trojan in a

program and then attempting to extort money from his (former) client,

the plaintif.  The plaintif's expert witness tells me that the trojan

is definitly present in the disassembled program.

     In the other case, a stock market analysis program is claimed by

the prosecution to be just a bunch of pretty screens and to not actually

do the analysis that the defense claims it does.  The issue is a minor

element in a large fraud case.

     The prosecution does not care to attempt to prove its claim by

actually disassembling the program;  that would be a lot of trouble.

The defense claims that the prosecution lost the source code when they

seized the defendants' computers.

     I have no problem believing both sides' stories simultaneously.

A pox on both their houses!

     I pull most new software into DEBUG and browse through it before

I use it.  From this I learn things like what language a package is

written in and how competent the programmer was.  In about a quarter

of the cases, I find undocumented commands.

     I also learn an occasional new coding trick this way.

     The reason I'm reviewing and recommending three disassemblers

instead of just one, is that they all have limitations and ranges of

suitability.  Of course, Murphy guarantees that the one I like the

best has the narrowest range.

     The first disassembler is called ASMGEN.  It's the one I use most

of the time.  It is appropriate for files less than 48K in size, and

containing only 8086/8087/8088 instructions.  The authors placed it in

the public domain.  We'll sell you a copy for ten dollars.  (Others

will sell it to you even cheaper.)

     Lest you think 48K is a severe limit, 48K of machine language

will disassemble into about 25,000 lines of assembly language, or

about 400 pages.  You will still have to analyze it, and that will

take months to complete.

     When invoked, ASMGEN looks for a file with the same name as the

machine language file and with an extension of .seq.  The .seq file

contains directives to control the disassembly process and to control

the kind of information included in the disassembly output.

     ASMGEN uses a simple but fairly effective algorithm to distinguish

code and data--it's all code unless you tell it otherwise in the .seq

file.  That is the purpose of the .seq file.  You run ASMGEN on the

machine language file, examine the output, edit the .seq file to

reflect what you've learned, and then repeat the process.

     ASMGEN only understands .com and .exe file formats, but the .seq

file directives are flexible enough that you can easily analyze device

drivers and ROM code as well.

     ASMGEN includes labels and cross references in the generated source

code.  This feature alone makes it better than half the disassemblers

I've examined.

     ASMGEN also includes the actual machine language code bytes as

comments in the generated listing, which I find usefull for checking

the generated code.

     While ASMGEN understands .exe file formats, it is sometimes

confused by the relocation table in the header.  A work around would

be to load the .exe file into DEBUG and write it back out as a .com

file.  The DOS loader will take care of the relocation for you.  You

would need to keep track of the segmentation yourself, and edit the

.seq file to get the labels right.

     I was only dimly aware of the problem until I started this review.

Most of the code I've seriously tried to disassemble has been less than

20K in size, and it's an odd .exe file that is that small and needs

much relocation.  In fact, on my hard drive, there are only two .exe

files less than 64K in size with more than two relocation table entries.

Besides, I'm mostly intrested in ROM code and device drivers.

     ASMGEN also has several minor bugs.  Things like substituting

eight bit register names for the destination operand in the LES

instruction.  Or leading zero suppressing the constant zero to the

empty string.

     Support for ASMGEN is nonexistant.  I can't even find the authors,

and I've been trying off and on for five years.

     By the way, I've used ASMGEN so much, I'd give the authors $100,

if I knew how to contact them.  J Gersbach BTVVMLAB(U6081) and J Damke

BOEVM1(DAMKE) please call me at 1-800-777-9752.  Ask for David.

     The on disk documentation assumes you already sort of understand

the assembly process, but otherwise, it is clear and reasonably complete.

Between it and experimentation, ASMGEN is easy to learn and use.

     The maximum memory requirement is 128K.  The output file is about

twenty times the size of the input file.

     For the range of problems that it is suitable for, ASMGEN is the

best in its class, and for ten dollars, you can hardly beat it.

     CODEGEN is the disassembler I turn to when ASMGEN fails me.  It

understands the 8088 through 80286.  It does not understand the

8087/80287, and produces ESC instructions instead.  It is appropriate

for files consisting of only one code segment and only one data segment,

which are supprisingly common.

     It requires 384K of free memory and produces an output file that

is about thirty times the size of the input file.

     CODEGEN comes from Digital Dispatch of Lakeland, Minnesota.  It

comes with a fifty page manual.  The price is thirty dollars.   Except

for bug fixes, it is unsupported.

     The best feature of CODEGEN is that it is interactive.  It does

very conservative code tracing and assumes that everything that it

doesn't reach is data.  After it has done this, it pops up a menu that

lets you browse through the file, allowing you to tell it that here is

a jump table, there is another entry point, and this isn't code at all,

but data.

     The browse facility is a little bit primitive.  The user is only

able to preview the disassembly starting at some hexadecimal address

that he keys in, or to get a list of lines that would contain some

string.  This latter feature can be used for such things as locating

all CALL or JMP instructions, in order to resolve all indirect code

references.

     The user can specify the names that he wants to give to up to 511

locations in the assembly language listing and CODEGEN will substitute

those names for the hex number based names it would have generated.

     You can save the state of the disassembly process into a map file

at any time.  This allows you to quit and pick up where you left off at

a later time.  Or you can make a speculative guess at what something is

and fall back to your last map if you discover that your guess was wrong.

     CODEGEN will optionally add comments to system calls, telling what

they do.  This saves me a lot of thumbing through reference books.

     The manual assumes the reader knows a lot, which is a reasonable

assumption to make about someone who is disassembling a machine language

program.  Some of the explanations are obscure enough to confuse me,

though.  The manual does spend some time explaining the disassembly

process and CODEGEN's approach to it, which is helpful in getting it to

do what you want.

     The worst feature of CODEGEN is that the cross reference information

is at the end of the listing rather than being embedded at the point of

reference, and is completely unavailable during the interactive browsing

process.

     I've found two bugs in my copy of CODEGEN.  The first bites if you

specify an uppercase search string in the browsing process described

above.  The author does all of his string compares in lower case in an

attempt to make the searches case insensitive.  Unfortunatly, he forgot

to force the user supplied string to lower case, so any uppercase

characters in the search string will cause the search to fail.

     The second bug has unknown causes.  When you press CTL-S to pause

the display output, CODEGEN sometimes looses the CTL-S and keeps on

scrolling the display.  The work around is to be prepared to press

CTL-S more than once to stop the display.

     CODEGEN's author wrote it for his own use and is constantly

tinkering with it.  By the time you read this, he will have fixed the

string search bug, and if he figures out what's causing it, the CTL-S

bug as well.

     If CODEGEN supported more elaborate segmentation, embeded the

cross references at the referenced point, and made the cross references

available during the browse session, I would junk ASMGEN and use CODEGEN

almost exclusively.

     SOURCER, from V Communications of San Jose, California, bats

cleanup for me.  It understands the entire 80x8x family through the 486,

including the math coprocessor instructions and the V20 and V30.  We'll

sell you a copy for one hundred dollars.

     SOURCER requires at least 448K, would like more, and will use up

to 2 MEG of EMS if it can get it.  With 2 MEG of EMS, SOURCER can

disassemble an executable of perhaps 400K.  Of course, it will take all

night to do it, the output file will be greater than 6 MEG in size, and

you'll spend several years analyzing the result.

     SOURCER's opening screen shows you a sample of how your listing

will be formated.  The various option switches can be altered and the

effect observed immediatly.  Mostly superficial gloss, but it is a nice

touch.

     Most of the listing options control things like the case of the

output and whether tabs or spaces are used to align columns.

     SOURCER optionally puts three types of comments in the output

file, each of which can be controlled separatly.  The first type of

comment explains what each instruction does--almost useless.  The second

type tells what the system calls and I/O port accesses do--very handy.

The third tells you what is at a referenced memory location--seems really

usefull, but somehow, I hardly ever use the information.

     The listing formats fall into two broad paradigms.  One paradigm

is that of a source file--pure assembly language, ready to be input to

an assembler.  It's not very useful if one is the least bit mistrustful

of the code vs data decisions of the disassembler.

     What with self modifying code and other obstacles to analysis, I'm

very mistrustful of any automated analysis of machine language.

     The other paradigm is of a listing file produced by an assembler.

The offsets, actual code bytes, and optionally the segment are placed

at the start of a line, followed by the assembly language source.

     This is sort of awkward when using an editor to browse through the

output.  Most disassemblers put the source code first and the machine

language at the end of a line, where it is easy to ignore unless it is

neeeded.

     SOURCER's output can't be trusted either.  SOURCER does a partial

simulation of the machine language to be analyzed.  Apparently system

calls and most stores into memory are not actually performed.  Stores

of segment registers are actually performed so that their contents can

be more accurately tracked.

     If some of the loads and stores of segment registers are indirect,

SOURCER can become confused about their contents.  When an uncertain

segment register is used in the address of another segment register

store, the store can land anywhere, including on top of code.  This

stepped on code then will be erroneously disassembled and the displayed

machine language will agree with the incorrect disassembly.

     The three times I talked to V Communications' tech support people,

I got astonishingly prompt satisfaction.  The first time I only had

questions and got immediate, clear answers.  The second time I called

about an apparent bug.  Although the explaination I got of the cause of

the bug was incoherent, the bug fix arrived by UPS Next Day Air.  The

third call was also about an apparent bug.  It took them less an hour

to locate the cause of the anomaly and to call me back with an

explaination and a work around.

     SOURCER uses a .def file to allow the user to control the disassembly

process.  Its format and options are so elaborate that I haven't been

tempted to fool with it.  From version 1.87 to version 3.04, the portion

of the manual that describes the .def file has tripled in size.

     The latest version of SOURCER emits a file in the .def format that

contains the information that it has deduced, rightly or wrongly, about

the input file.  The user can modify this file rather than try to create

one of the correct format from scratch.

     This leads me to think that I'm not the only user that thinks that

the .def file is too much trouble.

     I suspect that all the BIOS Preprocessor option to SOURCER does is

analyze the interrupt vector table and the DOS data area and use the

information to produce a .def file for the requested ROM.

     In summary, SOURCER is a heavy hitter, but should only be purchased

and used if CODEGEN and ASMGEN are both inadequate for the disassembly

task at hand.

     The most likely way that would happen is if the machine language

file is greater than about 100K.  In that case, it would take you a year

to do the analysis, and you should pause and wonder if what you stand

to gain is worth the effort.

     If the failure of CODEGEN and ASMGEN is due to elaborate

segmentation and its attendant relocation table, then SOURCER is the

proper tool, but it should be used with suspicion.

                       LEARNING ASSEMBLY LANGUAGE

     The VISIBLE COMPUTER: 8088 is an assembly language tutorial

intended for people who know some high level programming language.

It consists of a 350 page book and a companion disk containing a

simulator/debugger and a lot of demonstration programs used in the

book.  It is manufactured by Software Masters of Bryan, Texas.  It

costs seventy-five dollars.

     While the book lists BASIC as a prerequisite, acquaintance with

any high level procedural language will do.  (FORTRAN, PASCAL, COBOL,

C, even DBASE, etc.)

     The book is excellent.  I have never seen as clear an introduction

to the subject of assembly language.  I wish the books I had to learn

from had been as lucid.

     The book does have one systematic flaw, however.  The author is

a user of the principle that "a little inaccuracy saves a world of

explanation."  I frequently encountered statements that were only

true most of the time or only true in the particular context.

Sometimes the author expands and corrects himself later, and sometimes

he doesn't.

     The best(worst?) example of this is his discussion of signed

arithmetic.  He starts to introduce sign and magnitude notation.  He

then anounces that it doesn't work and proceeds to demonstrate this

by doing unsigned arithmetic on a pair of sign and magnitude numbers.

Hardly a fair test.

     The choice of number systems is made by a machine designer on the

basis of what he thinks is the most cost effective way to implement

the needed functions.  The hardware types tell me that sign and

magnitude tends not to be used because designing the arithmetic unit

is a real hassle.  There are other representions possible and some,

such as one's complement, are often used.

     The designers of micro processors tend to chose two's complement

because they can implement it and unsigned arithmetic with a single

adder, thus using fewer gates on a very small piece of silicon.  The

arithimetic produces exactly the same bit patterns in both cases.  The

only difference is in the meaning of the sign bit and the overflow and

carry flags.  The needed status information for both systems is produced

and the programmer simply tests the flags that are meaningful for

whichever system he is using.

     So, you should keep in mind that everything you learn from the

VISIBLE COMPUTER may only be an approximation of the real situation.

But then that is true of everything you learn in life, also.  The

approximations won't betray you badly, if you stick to machines based

on the 80x8x family of chips.

     The program on the disk, TVC.EXE, is a combination simulator/

debugger.  The simulator features a nifty animation of an 8088.

     The upper part of the animation displays the contents of all the

8088 registers that are visible to an assembly language programmer.

The lower part displays the registers that are invisible to the

programmer and that perform such functions as buffering the data and

addresses going to and from memory.

     The animation shows the various steps of instruction fetch,

instruction decode, operand fetch, et cetra.  It is good demonstration

tool for the examples included with the book.

     The animation, unfortunatly, is another example of the half truth

telling that I was complaining about.  The programmer visible registers

are exactly as described.  They have to be, they are part of the

definition of an 8088.  The programmer invisible registers must exist

and must have something like the arrangement and properties shown.

     While the author volunteers that the names he gave the programmer

invisible registers are bogus, he doesn't make clear that the arrangement

and properties of those registers are also only educated guesses on his

part.

     Chip (and mainframe) manufacturers don't like to publish internal

details of their machines' workings, in part because they want the

freedom to change those details.  How did the author know the exact

arrangement of those registers?

     Let's suppose that he somehow obtained exact information about the

invisible register set and accurately incorporated it into his animation.

The manufacturer still has the freedom to change the internal workings

of his chip, for improvements, special variations, or because he just

feels like it.  In particular, such changes are part of the basis of new

members of the 80x8x family.

     There are a number of tests that a program can perform, involving

various meaningless operations, that allow a program to uniquely

identify which chip it is running on, sometimes down to the revision

level of the microcode.  These tests are implicitly relying on the

details of the invisible registers and their properties that the test

authors think are fixed for particular chips in the family.

     As an example of such a meaningless operation, what happens if

you shift a sixteen bit register by 33 bits?  In the 8088 and the 8086

the register is cleared to zeros.  In the higher members of the family

the result is the same as shifting by one bit.  The designers wanted to

minimize the maximum time an instruction could take to execute.  Since

each bit shifted takes time (or hardware), and no one should ever want

to shift a sixteen bit register by more than sixteen bits, the higher

chips in the family only look at the bottom five bits of the shift count.

     I have seen such tests make erroneous identifications of chips.

Were we dealing with counterfeit parts?  Changes in the microcode that

Intel managed to keep secret?  Who knows?  Who cares?

     Anyway, the point of all this is:  Only the part of the simulation

that involves the programmer visible registers (the upper half of the

simulation) can be relied on to be accurate.

     TVC.EXE does not get along with Fansi Console.  If you use Fansi

Console, you will need to edit it out of CONFIG.SYS and reboot your

machine for your sessions with The Visible Computer.

     The program, TVC.EXE is touted as a programmer's tool in addition

to its pedigologic uses.  While it is more capable than the debugger

that comes bundled with DOS, it also occupies 77K, five times as much.

The improvement doesn't seem worth the extra RAM used or spending any

money at all for.

     If you need an assembler or a debugger, go with Turbo Assembler/

Debugger.  I'll be reviewing it next time.

     If you don't know assembly language, and want to learn, The

Visible Computer is the way to go.  It's the best tutorial on the

subject I've ever seen.

     Next time, I'll also be reviewing some books that I think are

useful.  If I don't run out of time or space, I'll also cover some

source code libraries and a couple of C compilers.

























     This file COPYRIGHT 1990 BEST IN CLASS SOFTWARE.  Permission is

granted to copy and distribute this file subject to the condition that

it remain unaltered.

                         REVIEWER'S PHILOSOPHY


     I am an impatient old man.  I have been programming since the late

1960's and made the switch to micros in the late 1970's.  I still wonder

why mainframe users tolerated the hostile user interfaces in that

environment, or why micro users tolerate the software bugs they are so

liberally supplied with.

     I am assuming my audience is fairly computer literate, knowing

what DOS is, what a TSR is, and at least the rudiments of some

programming language.  The business people tell me that their target

market is hackers and programmers.  They may change their minds at some

future time, and since they write my paychecks, I'll go along with that,

if it happens.

     The business people won't be telling me what to say, however.  My

agreement with them is that I get to say what I think, short of getting

them into serious legal difficulties.  If they don't like what I think,

they can only fire me.  Now, I've been fired or quit from more jobs than

most people have ever had, and I'm not afraid of being unemployed.  In

fact, except for minor worries like starvation, I like being unemployed.

     I'll give you the facts as I know them, but I've been known to

make mistakes.  If you catch me in an error or omission, please let me

know about it.  I can be reached at 1-800-777-9752

     My knowledge is limited.  It is likely that I'll miss some product

that should be included in a review. If you are aware of an ommission,

please inform me, including where I can obtain a copy and who the

business people can talk to about buying for resale.

     Anyway, the criteria I use to judge a package, in decreasing

order of importance, are:

1)  UTILITY - How well does it serve its purpose?

2)  CORRECTNESS - How many bugs, how serious?  What kind of

    compatibility problems are there?

3)  INTERFACE - How easy is the user interface to learn and use?

    How clear and complete is the documentation?

4)  PERFORMANCE - How fast is it?  How much disk space does it use?

    How much memory does it use?  What other resources does it require?

5)  PRICE - What does it cost?  How much hassle is the copy protection,

    if any?

6)  SUPPORT - How helpful are the tech support people?  How do you

    obtain bug fixes?  How about upgrades?

               BEST IN CLASS SOFTWARE COMPANY PHILOSOPHY

     Some dealers choose products to offer according to profit margins

regardless of quality or suitability.  While we don't intend to sell at

a loss, OUR GOAL IS TO OFFER ONLY THE BEST PRODUCTS FOR EACH PURPOSE.

In cases where there is no one best, we will offer the acceptable

products with an explanation of the pros and cons of each, allowing

the purchaser to pick that which best serves his needs.  If we are not

aware of any products in an area that we consider acceptable, we will

not offer any.

     We intend to focus on the negatives of each product more than

most dealers do.  We believe that a prospective buyer needs to be

aware of the weaknesses as well as the strengths of a product if he

is going to make an informed decision and most dealers and reviewers

gloss over the weakness of a product more than they should.

     We will be constantly reviewing our choices to see if they have

been superceeded by other products.  If you know of a product that we

should be carrying, or if you know of some bug or problem with our

recommended product that we missed, feel free to call David L Williams

at 1-800-777-9752.

                          BEST IN CLASS SOFTWARE                ORDER FORM
                              1-800-777-9752                  SEP 24, 1990

Your name:                              Your shipping address:

___________________________________     __________________________________

Your daytime phone number:              __________________________________

___________________________________     __________________________________

                                        __________________________________



QUANTITY                PRODUCT                         PRICE    TOTALS

____    WRITE-GUARD   .  .  .  .  .  .  .  .  .  .  .   $75.00  __________

____    ASMGEN  .  .  .  .  .  .  .  .  .  .  .  .  .   $10.00  __________

____    CODEGEN .  .  .  .  .  .  .  .  .  .  .  .  .   $30.00  __________

____    SOURCER .  .  .  .  .  .  .  .  .  .  .  .  .  $100.00  __________

____    SOURCER with BIOS PREPROCESSOR  .  .  .  .  .  $140.00  __________

____    VISIBLE COMPUTER 8088  .  .  .  .  .  .  .  .   $75.00  __________

____    VISIBLE COMPUTER 80286 .  .  .  .  .  .  .  .   $85.00  __________

____    FANSI CONSOLE .  .  .  .  .  .  .  .  .  .  .   $70.00  __________

____    FANSI CONSOLE with TECHNICAL REFERENCE   .  .  $110.00  __________

____    OPT-TECH SORT/MERGE .  .  .  .  .  .  .  .  .  $130.00  __________

____    POWER C COMPILER .  .  .  .  .  .  .  .  .  .   $20.00  __________

____    POWER C LIBRARY SOURCE .  .  .  .  .  .  .  .   $10.00  __________

____    POWER C BCD BUSINESS MATH .  .  .  .  .  .  .   $10.00  __________

____    POWER CTRACE DEBUGGER  .  .  .  .  .  .  .  .   $20.00  __________

____    C/DATABASE TOOLCHEST.  .  .  .  .  .  .  .  .   $20.00  __________

____    C/DATABASE LIBRARY SOURCE .  .  .  .  .  .  .   $10.00  __________

____    C/UTILITIES TOOLCHEST  .  .  .  .  .  .  .  .   $20.00  __________

____    C/UTILITIES TEXT PROCESSING UTILITIES SOURCE    $10.00  __________

____    C/UTILITIES FILE MANAGEMENT UTILITIES SOURCE    $10.00  __________

____    C/UTILITIES BORNE SHELL SOURCE  .  .  .  .  .   $10.00  __________

                                                    Sub total   __________

                   Less 4% if not paying with a credit card.    __________

                                                                __________

                 Texas residents please add 7.75% sales tax     __________

                                                                __________

                                        Shipping and handling       2. 0 0

                                                        Total   __________

If you are paying by VISA or MASTERCARD, we need more information:

Card holder's name:  ___________________________________

Card number:         ___________________________________

Expiration date:     ___________________________________

Your signature:      ___________________________________


                            FINE PRINT DEPARTMENT

   We usually ship UPS ground unless you specify otherwise, in which
   case we'll want to charge you more for shipping and handling.

   If your shipping address is a P O Box, we have no choice but to
   ship via the post office, at your risk, of course.

   Prices change.  If this order form is dated more than a month or
   two ago, you should call us at 1-800-777-9752 to confirm our
   prices and other policies.


                    Please send this order form to:

                       BEST IN CLASS SOFTWARE
                       142 1/2 W. San Antonio St
                       New Braunfels, TX  78130

                           1-800-777-9752

 
 
 


X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X
 Another file downloaded from:                                NIRVANAnet(tm)

 &TOTSE                510/935-5845   Walnut Creek, CA         Taipan Enigma
 Burn This Flag        408/363-9766       San Jose, CA                Zardoz
 realitycheck          415/666-0339  San Francisco, CA    Poindexter Fortran
 Governed Anarchy      510/226-6656        Fremont, CA             Eightball
 New Dork Sublime      805/823-1346      Tehachapi, CA               Biffnix
 Lies Unlimited        801/278-2699 Salt Lake City, UT            Mick Freen
 Atomic Books          410/669-4179      Baltimore, MD               Baywolf
 Sea of Noise          203/886-1441        Norwich, CT             Mr. Noise
 The Dojo              713/997-6351       Pearland, TX               Yojimbo
 Frayed Ends of Sanity 503/965-6747     Cloverdale, OR              Flatline
 The Ether Room        510/228-1146       Martinez, CA Tiny Little Super Guy
 Hacker Heaven         860/456-9266        Lebanon, CT         The Visionary
 The Shaven Yak        510/672-6570        Clayton, CA             Magic Man
 El Observador         408/372-9054        Salinas, CA         El Observador
 Cool Beans!           415/648-7865  San Francisco, CA        G.A. Ellsworth
 DUSK Til Dawn         604/746-5383   Cowichan Bay, BC         Cyber Trollis
 The Great Abyss       510/482-5813        Oakland, CA             Keymaster

                          "Raw Data for Raw Nerves"
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X
