2003.04.01

Printers, Proxies and Pranksters

An April Fool’s Recipe for Fun

by: kellegous
Ingredients:
1 – Shared Network Canon ImageRunner 330 Printer
1 tbsp – Java Sockets Code
1 jigger – Printer Command Language Reference
April Fools @ kellegous.com
[2002].
[2003].
April Fool’s Day is probably my favorite holiday. What other day of the year could you fudge up the company’s main printer and receive only amusement and laughs rather than a pink sheet and a half-hour lecture on productivity. Of course, anonymity is still recommended even on this sacred day of amnesty but I am royally foolish and boastful so I type up such adventures on my personal site to see what April 2nd will bring. So, while I am employed and can afford web hosting, let us get started:
  First, take the network shared printer. If you are lucky, it will be a virtual Windows printer over on some central domain server. I was lucky or else I would have found another appliance to terrorize, the coffee maker for instance. Our Canon printer/copier has its own little print server occupying port 515, but for convenience in matters of system administration all print jobs spool on the domain server before the job is even sent to the printer. Point of convergence = place to put a man-in-the-middle = increase in April Fool’s potential. Now, dig out old proxy sockets code that you wrote to get around some make shift firewall rules that forgot the NTP port some months ago and insert it in between the domain server and the printer. Not only have you just made the company printing queue absurdly inefficient, but you are about to make it equally unreliable, so keep reading.
proxy in the middle config
PCL (Printer Command Language)
[hp.com].

PCL Addendum For Canon imageRUNNER 330-400
[pdf].
Next you will need to take up the Printer Command Language Reference for the Canon ImageRunner printer and a dump of data that is passing through your cute little proxy server. The reference document I easily found on Canon’s developer support site. Obviously, you will want to add a logging mode to the proxy server code. You probably didn’t have it in the original version of the proxy because it wasn’t supposed to be running on that machine at the firewall edge anyway and there was no need to leave evidence of running services by leaving log files all over the system drive. I opted for simplicity, since the argument against log files would apply again when I was ready to unleash whatever might be born from this little project, and simply chose a large random number for my file names. With everything compiled and running, I typed “Kellegous” into Word and fired off a print job keeping my ear raised so that I could hear the printer start doing its collator dance with the coming print job. Opening the log file proved interesting. I could clearly see all the headers that the printer used to display a print queue on the control panel LCD. But most importantly, I saw a smattering of 0x1b’s littered in the data portion of the dump. That, my friends, is what we call an escape code. Sure enough, a more close examination aligned the codes in the dump file with those on the Reference Sheet. There were some potentially entertaining codes that you might consider altering on the fly to produce some interesting results, like •&l1X, which controls the number of copies the printer produces, or •&l0O the code to control page orientation. Those don’t produce a result that screams hoax though, so I encourage you to dig deeper. I was determined to find that “Kellegous” text in the data dump, because I was aiming to alter the text. It took a few minutes before I saw it, but there it was as plain as crossed eyes can see.
•*p1070x1326YK•*p1103x1326Ye•*p1153x1326Yl
•*p1203x1326Yl•*p1231x1326Ye•*p1281x1326Yg
•*p1325x1326Yo•*p1350x1326Yu•*p1428x1326Ys
(obviously I’ve substituted 0x1b with • to make this readable)
  My don’t those look like x,y coordinates…better check the reference. Yup, as a matter of fact, *p#x#Y will position the cursor for you. I think that gives us exactly what we need to make this a cute little April 1st prank. I quickly wrote a filter to raise all the K’s up 20 units, to prove the concept. That might be sufficient for many of you but I know that particular prank was done once before down at Georgia Tech on a postscript printer. You can get as fancy as time allows, but my time was limited by piles of real work. I needed something simple yet effective. Ah, a periodic function…simple and aesthetically pleasing. Turns out to be really cute, actually…especially when the text is dense. I played with the frequency and amplitude a little. Taking the amplitude too high would often result in invalidating the print job, so I kept it modest. Frequency was just trial-and-error until I had something that looked nice. At the end of the process, it really all boiled down to one little line:
nc += (int)(40*Math.sin(x/100.0));
Of course, there is some parsing that must occur to rescue that accompanying x value from the sea of escape codes, but it’s all there if you look at the code. And here’s a sample of what came out:
sample of printer output
Nice!
  While it may seem obvious that wavy text coming from the printer on April 1st is a hoax, it would be a shame if someone called the printer repair guy to come saw the face off of the thing before you could revel in your handiwork. I encourage an additional step that says very clearly and loudly, “I 0wn j00”. I opted for something that sounded easy enough but turned out to be harder than I expected. I printed a splash page carrying the caption in 48pt font: “Is it April 01 already?” and saved the dump file for replication. Now, a couple of problems surfaced here: 1) The handshaking that must be done with printer that prevented me from just writing the dump file blindly to the printer port and 2) the content length headers made it hard to erase my identity from the username and machine name headers. The second one was solved by replacing text without changing the overall length. That was easy enough. The first one though, took some more session snooping, but after some really screwy printer output I finally got the timing right. The real problem was that this sucker had to be put in place in a really short time as it was already April 1st and people were wondering around the office, printing their email and fixing morning coffee. I was just about to give up when I got the final read in the right place. For those blessed with time, I would suggest finding a way to make the printer beep out the tune to the A-Team as the job prints. That was clearly beyond my time constraints though.
  With everything ironed out, I set the filter up to alter text on about 35% of the incoming print jobs (so that it would be harder to identify and so that productivity would not come to a crashing halt) and set the little demon loose. Nothing to do for the remainder of the day but play dumb, which nobody ever buys, because I’m clearly the only person with a love for these type of practical jokes. At a few points in the day, I had to crank the percentage from 35% to 50% to ensure that most everyone got in on the April 1st fun. You may wish to target specific users by parsing the headers, I was after equal opportunity annoyance.
Curious about the code: [20030401.zip]. And now that you have successfully harassed your entire office, perhaps you can help me work this project into my resume as I suspect we will both want to leverage whatever will set us apart from all the other unemployed programmers out there.
←kellegous→