Sunday, November 19, 2023

The Salesman's Tale


As far as stories about one’s life go, everyone has a few that all their friends and acquaintances have heard ad nauseum, and a few that they love to tell and may or may not be a hit, and, if they’re very lucky, a few that they only tell occasionally, but are always entertaining when they do.  This is one of those for me.

Now, I’ve alluded to this story before, most particularly in my discussion of fate (or whatever you wish to call it).  In that story, I talked about how it was I came to work in a restaurant, even though I had been a professional programmer for several years at that point.  That restaurant was a small joint about a mile off the campus of George Mason University called the Mason Jar Pub.  We served sodas in Mason jars (get it?), but also beers and pizza and all the stuff that college students require.  This place was run by a snotty punk named Brian whose dad was in “construction” (air quotes used very advisedly) and had obviously been gifted the pub as baby’s first business.  He ran it with his girlfriend and a friend of theirs named Dana.  They ran it very poorly, and eventually the business ran out of money and Brian and friends ran out of town and none of us got to cash our final paychecks, which led to a number of uncomfortable days in court as we tried to get paid by the father.  Lessons were learned all around.  But, in the run-up to this inevitable debacle, the following thing happened which ended up changing the course of my life far more than my one missed paycheck.

Now, because I had gone to college previously, then dropped out (during which time I did the aforementioned professional programming), and was now back for a second tour, I was a bit older than most of my peers.  I was, in fact, just a wee bit older than Brian himself, and this was the point in my life when I learned that most people really can’t handle managing employees who have more age and experience than they themselves do.  The prime example of this was the reaction I got when I pointed out to Brian that I had some experience with computers, and I could give him a hand if he ever needed any help.  Said reaction was basically just a sneer.  I was one of the dumb college kids he had hired; obviously I was not to be allowed in the club with him and his girlfriend and Dana, who was the only one trusted with “the books.” I shrugged and went back to making calzones: no skin off my nose if he wanted to struggle with his new computer.

You see, there was this fellow named Tom Cooney was working for Sharp and had sold the Mason Jar Pub its first cash register.  He then sold them a computer to which you could download all the data from the cash register and then load that all into QuickBooks.  Provided you knew what you were doing, of course—this type of process was still a bit fiddly back in the early 90s.  And Brian and company most certainly did not know what they were doing.  They struggled with that damn computer constantly, and Dana was constantly calling Tom asking for help.1  So I knew they could use my expertise.  But, if they were too proud to accept it, it was none of my concern.  I had been hired to sling pizzas and clean up the joint, and I was perfectly willing to do just that.

Now, the three twitbags couldn’t be around all the time.  Especially on the night shifts, there were often times when none of the three of them were available (or just didn’t want to be bothered).  For these occasions, there were two “assistant managers,” who happened to be senior ROTC students, as well as roommates and very good friends.  One was a pale, freckled redhead whose name I think was Lou; the other was a confident black man with glasses named Wayne.2  These were both big, burly men who were training to be Marines, older than most of my coworkers (still a bit younger than I was, of course).  I think that Brian thought that they were going to be “on his side” in the imaginary divide in his mind that existed between “management” and the rank-and-file.  But, the thing about middle managers is, if you treat them (and pay them) as badly as you do the low-level employees, they tend to side with the majority rather than the upper echelon.

So, one slow night I was working with Wayne and a couple of other people, and Wayne was bitching about how badly all us employees were being treated and how little we got paid compared to Brian and his coterie, who seemed to be pocketing all the money.  At some point, the discussion turned to sneaking a peek at the books.  After all, it was all on the computer, and the computer was right there in the office.  The office was locked from us paeons, of course, but Wayne, as the manager-in-charge, had the keys.  For emergency use only, theoretically, but ... perhaps finding out what was going on was an emergency, dammit!  (Had we known what was coming, we would have felt even more justified.)  The problem was, only Dana had the password to QuickBooks.  So Wayne turned to me.  “You know computers, right?” he asked me.  “You could hack in!”

I was not surprised at this misconception: that all us programmers know how to hack things.  I was a bit surprised to hear this future Marine lieutenant suggest something so morally ambiguous.  But, then again, Wayne himself often told us that his Marine instructors taught them to make a decision and stand by it: making a poor decision in the heat of battle can be bad, but hesitating and making no decisiono at all is often disastrous.3  So, after my initial shock, I set about explaining that I was never much of a hacker—in fact, the only thing I had ever successfully hacked was a copy-protected videogame on my Commodore 64, which tried to tell me it couldn’t run after X times because my trial period had ended.  I did in fact show that snarky videogame message who was the boss, but breaking a QuickBooks password was a whole different animal.  Computer security had advanced by about a decade at that point and I had spent zero of that intervening time keeping up with it.  “Well, take a look,” Wayne encouraged.  So I said I would.

And, perhaps 15 minutes later, I was ready to admit that there was literally no chance that I was smart enough to break into a password-protected QuickBooks account.  “Sorry,” I said, not all that sorry.  But Wayne was not deterred.

“Okay, but there’s got to be something you can do to fuck with them, right?” he suggested.  Well, okay, I was not bothered by being unable to hack, but this now felt like a challenge.  Surely any programmer worth their salt could do something to fuck with people, given free access to the physical machine.  I had certainly engaged in a few juvenile pranks with coworkers—both as the fucker and the fuckee—but a lot of those things were only effective against other programmers.  What I needed was something that would get under the skin of a normie.  So I started poking around to see what tools I had available to me.

And what I found was a hex editor.  Now, if you’re not a technogeek like myself, you might not know what this is.  It’s a program that will let you edit anything on the computer: data, commands, even the operating system itself.  It was exactly the thing I had used in my one and only successful hack.  You see, a videogame that keeps track of how many times it’s been played and then refuses to run necessarily has to store that count somewhere, and that means you can find that place and edit it, and change it to zero.  But there are two problems with this approach: first of all, you’d have to constantly change it back to zero every time the count got too high again, and secondly the people who programmed the videogame have obviously thought of this.  They don’t store the count as a raw value; it’s encoded somehow, so that even if you could find it and change the value to zero, that wouldn’t be read as “zero” by the program itself.  So I quickly realized that my “brilliant” plan could never work.  But I realized that, in my attempt to find where the data for the count was stored, I had stumbled across something even better: the place where the code to compare the count and show the snarky message was stored.

You see, on the one hand, figuring out exactly how a given piece of software works should be easy: it’s all just numbers, and the software authors can’t keep you from being able to read those numbers without also making it impossible for the computer to read them.  So, theoretically, you can just look at all the numbers in the software and see what it’s doing.  But, the tricky part is, the same number can be interpreted differently depending on context.  For instance, say you look at one byte in a piece of software and it happens to be hex 49.  Now, that might represent the number 73, which is just the hexadecimal number converted to decimal.  Then again, it might be a capital “I,” because that’s what hex 49 is on the ASCII chart.  Or it might be the lower byte of a two-byte number, or the upper byte, or the middle byte of a four-byte number.  Or it might actually represent an instruction: say, an immediate exclusive-or of the next byte with the “accumulator,” which is assembly-speak for “the current number we’re working with.”4  Which of those many things it actually is depends entirely on context: the only number that you’re 100% sure of is the very first one, and, after that, you have to deciper every number, in order, to figure out what the next one means.  If you lose your place, or if you miscount how long something is, then all of a sudden you’re interpeting numbers as letters and letters as instructions and instructions as numbers and you’re just fucked.  So, while it should be simple, in practice it’s very much not.

In the case of my videogame, the code which checked how many times it had been run and then conditionally displayed the annoying message was not near the beginning of the code, but it was jumped to near the beginning of the code, because that check was one of the very first things it did.  So I was able to find it and trace through it and eventually I found the “branch” instruction: the part that said, if the value is no good, jump to the code which displays the message and terminates the program.  And I replaced the “branch” instruction with hex EA, which is what we technogeeks call a “NOP”: a no-op.  So then, instead of branching when the number was too big, it just ... did nothing.  And, after the nothing, it proceeded with the regular videogame code.

And I could do all that because I had a hex editor, and that allowed me to search for certain byte sequences, identify them, and replace them with different sequences.  And then save the file, overwriting the old program with a new version which was almost identical to the old, but with one slight tweak.  Once you know how to do this type of thing, it’s pretty easy to extend that to other changes.  And one of the simplest edits of all is to replace one string with another.

See, your hex editor knows perfectly well that sometimes numbers represent letters, so you can tell it to search for a string, and it can do that fairly easily.  The longer the string, the more likely it is that a given set of sequential numbers will represent those letters and not just be a stunning coincidence.  And, once you find the string, you can easily overwrite it with a different string, as long as the new string is exactly the same length as the old one.  Now, if you happen to know something about the way the program was written, you can pretty easily replace a longer string with a shorter one: anything written in C, or a language that derives from C, will use a zero byte as a marker to mean “the string ends here.” So a 10-character string will actually be eleven bytes long: one byte per character and the zero byte at the end.  You could easily replace that with a 5-character string and just fill in the last 5 bytes with zeroes and Bob’s yer uncle.  What you can’t do (or can’t do safely at any rate) is replace a 10-character string with a 20-character one, because those last 10 bytes are going to overwrite something entirely different: if it’s another string, the program will end up displaying the latter half of your replacement string intead, which is maybe not too bad, but if it’s code, then the program will likely do very bad things as it starts interpreting your characters as instructions.  But, as long as the string is equal or shorter, you’re golden.

And, the thing is, it’s very rare to find a hex editor on a random computer.  The vast majority of users have no need for one.  Finding a hex editor on the accounting PC for a small college-town restaurant was just weird ... surreal, even.  I would eventually discover that our salesman friend Tom needed the services of an engineer-type, and the one he was using at that point was a bit sloppy.  He had been using the hex editor when he set up the computer, and just never bothered to delete it.  But, at the time, it felt almost like destiny: there wasn’t a whole lot I could do to this computer, but the presence of a hex editor opened up my possibilities quite a bit.

Now, back in those days, we didn’t have Windows.  Well, technically speaking we did, but its use wasn’t prevalent yet.  Most programs, including QuickBooks, just ran on the primitive system underlying Windows: DOS.  When you booted up a DOS computer, you were faced with what we called a “C prompt”: C:\> .  And you just typed the name of whatever program you wanted to run—perhaps qb for QuickBooks—and it ran.  Now, if you mistyped something (say, you accidentally fat-fingered a key and typed wb or qv instead of qb) you would get an error message.  Specifically, it would say “Bad command or filename.” Not that you’d be likely to mistype a two-letter command, but something longer, you might.  And the thing is, “Bad command or filename” is a really excellent string to search for in a piece of software, if you happen to know which piece of software is responsible for printing that “C prompt” and running whatever commands you enter.  Which I did.  So it was fairly trivial, given the hex editor, to find “Bad command or filename” and just replace it with a shorter string.  Like, say, “What the fuck?!?” Which is exactly what I did.

Needless to say, Wayne was tickled pink at the thought of poor Dana mistyping something and getting cursed out by her own computer.  I was a bit proud of myself: it was basically trivial for me, but it could seem like magic to the uninitiated.  And I thought nothing more about it.

Until ...

You see, what happened was that, sometime in the next few days, Dana was having some troubles with getting data downloaded from the cash register system and, naturally, she called Tom for tech support.  Not that tech support was really Tom’s thing—he was the salesman, recall—but the whole computer thing was, strictly speaking, on the side from his job at Sharp.  So he was tech support that day.  And, when you do tech support over the phone, you get into a sort of rhythm: “Okay, type this.  And what does it say?  Okay, then, type this next.  Now what does it say?” And so on and so forth, back and forth, until eventually poor Dana flubbed whatever she was supposed to have typed.

“Okay, type this command; now what does it say?”

“Ummm ...”

“Just tell me what it says on the screen.”

“Well ... it says ...”

“Yes? what does it say?”

“Well, it says ... ‘what the fuck’.”

Without missing a beat, Tom responded: “Somebody there knows computers.”

Or at least that’s the way he recounted the story when he told me about it later.  Because he started dropping by the Mason Jar Pub quite regularly after that, hoping to ferret out which employee had the secret computer knowledge.  And, eventually, he stumbled onto me.  And that’s how Tom Cooney became my first business partner: I became his new, not so sloppy, engineer, and I was introduced into the weird world of running your own business.  It’s part accountant, part movie producer, part one-man-band (even when you have partners or employees), part having the weight of the world on your shoulders, and part ultimate freedom from being told what to do by idiots with no vision.  I owe Tom a lot, but I think maybe I owe Wayne even more.  Without that juvenile prank, my life would have turned out very differently.  And maybe not better.



__________

1 This led to Tom and Dana actually dating briefly, if I recall correctly.

2 I mentioned Wayne—and this very story—in passing when discussing how much I owe to Bernice Pierce.

3 I stress this is all second-hand information from a single source, diluted by decades of intervening time and degrading memory.  I apologize to any of my readers with military experience if I’m misrepresenting the advice.

4 Note: I’m not stating categorically that 0x49 is an immediate XOR for a 6502 CPU; I’m about 4 decades out from even being able to follow the reference docs for that particular flavor of assembly, much less actually remembering it.  But I did look it up, and I’m pretty sure that’s right.