Microsoft needs taken down a peg or two (thousand)

Remember when you installed Windows 7 and you saw this shit?

https://assets.pup.cloud/media/2023/06/image.png Image attribution: WindowsCentral

When the EU stopped looking at Microsoft, they removed it. "Microsoft finally ditches the Browser Choice menu for Windows in Europe" was the headline on WindowsCentral.

Stepping back, the Browser Choice popup was specifically part of the agreement Microsoft reached (and then broke) with the EU to actively give users the choice of what browser to use. Microsoft also, finally, allowed people to uninstall Internet Explorer around this time too (although because modern internet search is terrible, it's impossible to find articles giving an exact date or inciting reason, so I can only go off of my own memories of "The EU did this").

Remember all that? So anyway, it's 2023 and Microsoft won't let you uninstall its browser and actively hounds you to use it. Microsoft has made it harder for other browsers to automatically set themselves as your default browser (the double edged sword - this does have legitimate value for security, but is very much beneficial to Microsoft more than anyone else). If you do try to use a different browser, you get a pop-up on the download page for the browser you're trying to download, telling you to use Edge.

https://assets.pup.cloud/media/2023/06/image-2.png

Even going into the Settings app to change unrelated settings, Microsoft tries to convince you that your choices are wrong, that your system security is at risk because you're not using their browser, that you've done something and Windows needs to fix it.

https://assets.pup.cloud/media/2023/06/image-3.png

From the point at which your default browser changes to not be Edge, this constant reminder that Microsoft disagrees with you is always present in the Settings app. You have no way to turn this off, other than to click it and let Windows set your default browser to Edge, pin Edge to the taskbar, put a shortcut to it on your desktop, and make Bing your default search engine.

If you open the start menu and you type in the name of an application, not realising it isn't installed, sometimes the start menu will suggest the website of that application instead. Helpful! Legitimately! However, if you hit enter, the website will be opened in Edge instead of your default browser, because the start menu uses Bing search.

https://assets.pup.cloud/media/2023/06/image-1.png Image attribution: Neowin

I got a new laptop last week, the Framework 13 (you can read my thoughts about it on Cohost), and I went through a whole thing of installing Windows 10 because 11 is just too user-hostile for my liking (I mean, come on, you can't even move the taskbar any more). At some point I wanted to see my desktop wallpaper, I minimised all my windows and saw this piece of shit on the desktop. Even choosing to simply ignore Edge, it sits on the desktop and demands you use it. My existing Windows machines seem to have escaped this atrocity on the desktop (for now), but it seems like a new installation will receive the Mark of the Beast.

Microsoft somewhat recently made waves with its launch of "Bing Chat"/"The New Bing", which is Microsoft Bing Search but with ChatGPT, and you can't even use it unless you're using Microsoft Edge (or a browser which pretends to be Edge in order to specifically circumvent the requirement that you use Edge).

Even if you acquiesce and use Microsoft Edge, the aggression and hostility does not stop. There's a Bing button at the top-right corner of every Edge window, which was completely impossible to remove for a while (I believe there's a way to remove it now, but because I stopped using Edge, I don't want to check myself. It was not possible at all to remove it when I last used Edge).

Let's not mince words here; if Microsoft were being this aggressive and hostile to other browsers during the EU antitrust case, Steve Ballmer would have extremely been publicly executed. Yet in 2023, there aren't even any open antitrust cases against Microsoft in relation to its monopolistic practices on Windows?

Yes, I know Google made a whole thing where ChromeOS is a lightweight Linux distribution and everything's supposed to run inside Chrome, there's no disagreement that that's also shit, but ChromeOS has nowhere near the market share and general-purpose use that Windows does. ChromeOS bad, Microsoft Edge somehow worse.

Bypassing a bone-headed battery block

Note: This article discusses mechanisms for updating the BIOS and Embedded Controller of computers that haven't been made in almost 20 years. Exercise an abundance of caution when attempting to follow, reproduce or build off of my findings. These computers only get more rare over time, and while a bad BIOS flash may be recoverable, I have no idea whether a bad EC flash can be recovered.

Introduction: Enter the ThinkPad

Some time ago, I picked up an IBM ThinkPad X40 for a pretty decent price. It's a nice machine, came in relatively good condition (some cosmetic wear, but nothing actually broken), and doesn't have the worst specs. It has an amber ThinkLight, which I find quite charming.

This was a fairly good machine when it came out, featuring (in my case) WiFi, Bluetooth, IrDA, Gigabit Ethernet and 56k fax modem connectivity. It also has one (1) single CardBus slot, and an SD slot that supports SDIO.

The battery it came with was, predictably for a machine of its age, dead. I didn't really intend on this being a machine I'd carry about, and the battery casing was cracked enough that I was able to just open it up and remove all the cells and circuitry, leaving a nice blank. This, however, would be a problem when doing any firmware updates.

It also came with its original 1.8" IDE hard drive (blessedly, this used the standard 2.5" interface rather than the other 1.8" interface I've seen, which used ribbon connectors instead and are vastly easier to plug in the wrong way..), and the drive even still worked. For a bit of fun, I wanted to start off with as close to factory configuration as possible for this machine.

This unit originally shipped with Windows XP, and some kind soul has made all seven (7!) recovery CDs available on archive.org. This is especially lucky because the only alternatives are to either attempt to order a set of recovery discs from Lenovo directly, or to appeal to the hoarders on the ThinkPad forum who think it's completely okay to hoard recovery media and provide access only on request by individuals who have met their bizarre criteria. No thanks.

Google dot com how do I upgrade BIOS

Sometimes I'd observe that the X40 doesn't boot without manually selecting an option (ie. setup). My initial suspicion was that the HDD was failing, and I wanted to replace it with an mSATA SSD anyway, so I switched out the HDD (temporarily) for an mSATA to IDE 2.5" adapter to get the OS reinstalled, but I discovered the drive simply wasn't being detected. I'd been informed by my friends over at the Vintage Tech Nerds telegram group that IBM was famous for locking their firmware down to only accept their own HDDs, so my first port of call was upgrading the BIOS to the latest version and then looking for a modified version (or modifying it myself) to permit other drives to be used.

ThinkWiki's matrix of BIOS and Embedded Controller versions for all ThinkPads noted that the final version was BIOS 2.08 and Embedded Controller firmware 1.62 - my device had BIOS 2.06 and EC 1.61, so an update was my first step. I downloaded the updates from the links on ThinkWiki (funnily, there's a bold notice on ThinkWiki noting that all the download links are broken and have been since 2015, but none of the ones I needed were broken).

The advice on ThinkWiki was to upgrade the Embedded Controller first, then upgrade the BIOS, so I ran the update program. It advised to keep the laptop undocked, connected to AC power, and have a fully-charged battery connected. I didn't have a working battery at all, so I went ahead with the understanding that this was simply an advisory. The update program rebooted the computer, and a lovely text-mode IBM logo came up, followed by a menu with options to view a README or initiate the firmware upgrade. The problem began when I tried to initiate the firmware upgrade.

It came up with confirmation messages stating that the laptop must be undocked (fine), connected to AC power (also fine), and have a fully charged battery connected (not fine). I continued, thinking this was just a second advisory, but woe betide, the upgrade program actually checks that you have a fully-charged battery connected, and refuses to continue without it.

Initial google searches indicated I could pass the command-line argument -sp to the update program to have it ignore the battery requirements, but this must have been added in firmware update programs newer than the X40, because it had no effect, and later analysis of the program showed that there was no such functionality in the program.

Searches also indicated I could use a program called WinPhlash (which I downloaded from the apparently legitimate website "wim's bios") to flash the EC and BIOS firmwares. I was able to take a full backup of the BIOS before doing anything, but was unable to use it to flash the Embedded Controller firmware, so it seems I -have- to use the official software for the EC part.

Put your balaclava on, it's time for crime

At this point it was obvious I'd need to work out how the firmware update process worked, and then hack it in some way to remove the battery check. The downloaded update files from Lenovo were standard InstallShield programs, and the actual update programs were extracted and run from %temp% - the currently-logged in user's temporary files directory. Both the BIOS and the Embedded Controller updates had the same file structure for the most part. I found it interesting that there was an IMG file, so I inspected that first using 7-Zip (because hey, did you know that 7-Zip can open pretty much anything? You can even open raw disks with it.)

Opening the IMG file revealed that it was.. a floppy image. A regular 3.5" high-density 1.44MB floppy diskette image.

What was in the image was pretty interesting. The biggest file was $019B000.FL2, which was obviously the Embedded Controller firmware itself. At a later date I might inspect it and see what fun crimes can be done with it, but for now I just wanna grill for god's sake. There were some interesting other things in the image, though: A minimal copy of IBM PC-DOS 5.00, with some additional software specific to flashing the Embedded Controller firmware.

I verified what this was by running ibmdos.com through IDA Free 5.0 (the last version to support 16-bit binaries, blessedly preserved by the ScummVM folks) and confirming that it was, in fact, IBM DOS 5.00. To double-check, I opened up command.com as well, but found that it was actually the program responsible for the text-mode IBM logo and the menu that's presented afterwards.

I spent a while in IDA trying to work out if I could simply patch out the battery check in updtflsh.exe - the program called by the menu when initiating the EC flash procedure - but I couldn't locate where this was actually happening, and I have very little experience with reverse-engineering 16-bit software. IDA Free 5.0's interface is also..quite a bit harder to get to grips with than the more modern software I'm used to.

It occurred to me, however, that I knew what the startup program was, and I knew what version of IBM DOS was being used. Could I simply replace the custom command.com with the equivalent from a retail copy of IBM PC-DOS 5.00? As it turns out, yes! I swapped the files in the floppy image, ran the EC firmware update program, it rebooted Windows and warm-booted into the floppy image, and I was immediately presented with the current date and time, and a prompt to change them should I wish.

Finally, I was able to update the Embedded Controller's firmware by running the command QKFLASH.EXE $019B000.FL2 - as documented in the "extremely last resort" section of ThinkWiki's article on updating the BIOS, qkflash.exe is the program that actually performs the flashing.

After this completed, the laptop completely shut down. I left it for a few seconds, then powered up, and it booted right back up. I then used WinPhlash to flash the BIOS itself, and when I rebooted into the BIOS setup, it confirmed I was now running BIOS 2.08 and EC 1.62. Success!

Where now?

I stopped here, because it was a small victory and I was tired, but I want to do more with this. It brought up some interesting questions, namely:

  • Can I fiddle with the Embedded Controller firmware, and perhaps enable some new functionality or fiddle with the keyboard mappings?
  • Can I modify the BIOS to disable the hard drive DRM? Existing modifications are only available for the X41 and newer.
  • How does the firmware update program manage to load a floppy disk image into memory and warm-reboot the computer directly into it?
  • Can I wholesale replace this with a different floppy image? What state is the computer actually in? What could you do with this?
  • Are there any other limitations IBM placed on this machine that I could perhaps lift?

Taking a ride on the Universal Serial Bus

Hello! I'd like to take a minute here to talk about some fun I've been having with the USB interface for the Paperang P1 and P2 portable thermal printers.

I discovered recently that these devices had a USB interface (I'd previously thought the USB port was only for charging the internal battery) when I stumbled onto the (Chinese-only) download page for the Paperang software, which contains something omitted from the English variant of the page; Mac and Windows software, and mentions of using USB to print.

Unfortunately the official Paperang software is very sparse in its featureset, and doesn't appear to properly communicate with the P2 model (It'll produce incorrect print results), so I was motivated to try and reverse-engineer the communications protocol used (a fantastic series of blog posts made by a good friend of mine on the subject of hacking a cheap chinese USB mouse provided added inspiration, and I sincerely recommend you read them).

When first plugged into a Windows machine, it's recognised as a USBPRINT device (USB class 0x07) with vendor 0x4348 (WinChipHead) and product 0x5584 (CH34x printer adapter cable). The host will, as part of device initialisation, send a URB_CONTROL request type 0xA1 (device-to-host class 0x1, interface 0x1), to which the printer responds with 0x0060 followed by MANUFACTURER:;COMMAND SET:ESC/POS;MODEL:MiaoMiaoJi;COMMENT:Impact Printer;ACTIVE COMMAND:ESC/POS;. However, the printer doesn't actually contain a CH34x-type chip, and the USB data lines are directly connected to the main MCU (an STM32-type chip). Further, the URB_CONTROL response states that the printer uses the ESC/POS method of communication, however this doesn't appear to actually be the case. It's very unclear why they'd put this in, however both the P1 and P2 models report this. I did test whether they supported ESC/POS communications, however the messages were ignored by the printer.

When the Paperang Windows application first detects the printer, it'll begin sending messages to the printer via URB_BULK output. These messages are formed of a distinct structure:

--------------------------------------------------------------
| Frame Begin | CMD/OpCode | Data   | CRC        | Frame End |
--------------------------------------------------------------
| 0x02        | 0x00000000 | 0x0..0 | 0x00000000 | 0x03      |
--------------------------------------------------------------

The Data block is of variable length, and from my observations may be as small as 2 bytes, and may be as large as 1008 bytes. The CMD/OpCode block is always 4 bytes, and I have identified the following OpCodes:

0x06000200 - Appears to be something of a "session" start indicator (Data block has only ever been observed to be 0x0000 for this OpCode) 0x1a000200 - Feed command (doubles as a no-op) - Data block for this is simply the hex representation of an integer, corresponding to the number of milliseconds the printer should feed the paper for 0x18010401 - CRC data transmission (Data block will be 4 bytes in length). This is an interesting one, in that the Data block consists of an initial value for the CRC32 algorithm, and the CRC block will be the initial value's checksum calculated using the magic value 0x35769521 as the "initial" initial value. Once this OpCode has been used, the initial value will be XORed by the magic value and will then be used for future CRC calculations. The official Paperang software has an internal table of "initial values" which it picks from at random, however as it uses the C standard library's random number function, the value it ultimately uses is almost always the same. 0x0001FFFF - Print data transmission OpCode - this one is somewhat special in that the latter 2 bytes (denoted here as 0xFFFF) are dynamic, and correspond to an integer of the length of the Data block. The Data block will be a variable-length (up to 1008 bytes) block of data to be printed. The first message sent to the printer is the CRC data transmission message. An example is:

------------------------------------------------------------------
| Frame Begin | CMD/OpCode | Data       | CRC        | Frame End |
------------------------------------------------------------------
| 0x02        | 0x18010400 | 0x4d0dc477 | 0x699295ed | 0x03      |
------------------------------------------------------------------

And the CRC result for all further messages where the Data block was 0x0000, was 0x906f4576

From this point, the printer can be used normally. There may be other functionality available through the USB interface, but the first thing I looked at implementing was actually printing data. Upon printing some sample data using the official software, it very much looked like there was no special encoding - if I printed a single dash (-), the bytes sent to the printer appeared to match up with the physical dots printed on the paper.

Although I could've then spent a while printing some test images on the paper and looking at the transmitted bytes in Wireshark, I figured I may as well just start bit-fiddling and see what happens. I'd already determined that the OpCode for printing data contained the length of the transmitted data in its latter two bytes, so I figured I'd start with the maximum length for a single packet - 1008 bytes - and set segments at 8-byte intervals to determine roughly what was going on:

byte[] Data = new byte[1008];
for(int i=0;i<Data.Length;i+=8)
	Data[i]=0xFF;

I sent this along to the printer, and was pleased to see it printed 6 vertical lines. Based on the fact that the lines were not skewed, it seemed like the line length in bytes was divisible by 8, and based on there being six vertical lines, it seemed like the line length was 48 bytes. To test this theory, I adjusted my code to the following:

byte[] Data = new byte[1008];
for(int i=0;i<Data.Length;i+=48)
	Data[i]=0xFF;

And was pleased to find that it now only printed one vertical line. Cool, we've now worked out the line length, and we've confirmed that 0xFF prints a line..now how do we get a single dot? I tweaked my code again, this time setting every 48th byte to an alternating pattern of 0x0F and 0xF0:

byte[] Data = new byte[960];
for(int i=0;i<Data.Length;i+=96) {
	Data[i]=0x0F;
	Data[i+48]=0xF0;
}

It printed something resembling a zig-zag! Awesome. It seems like every byte can be controlled 4 bits at a time, at least, for controlling what gets printed. Can we go deeper? Let's try alternating byte patterns! We'll make every 48th byte an alternating pattern of 0x33 and 0xCC. This should produce two narrow zig-zags:

byte[] Data = new byte[960];
for(int i=0;i<Data.Length;i+=96) {
	Data[i]=0x33;
	Data[i+48]=0xCC;
}

Print..and hey presto! Right on the money! Can we go even deeper? Let's try an alternating pattern of 0x55 and 0xAA, which in binary is 0b01010101 and 0b10101010:

byte[] Data = new byte[960];
for(int i=0;i<Data.Length;i+=96) {
	Data[i]=0x55;
	Data[i+48]=0xAA;
}

Just like that, we've got what looks visually to be a dithered (50% dark) vertical line! Radical. From this we can deduce that every bit in the byte corresponds to an individual "dot" produced by the thermal print head. Thus, given that we know every 48-byte block is one line, we also know now that each line is 384 "dots" wide.

Awesome, we know everything we need to in order to print an image!

From here, the process of printing an image is pretty obvious - resize the image to 384 pixels wide, and convert it to a 1-bit bitmap. This presents a problem though; if the image is even slightly large, it'll exceed the maximum packet size for a message sent to the printer (1008 bytes). Luckily for us, however, C# does present a fairly nice way of splitting at specific lengths, using LINQ:

using System.Linq;
using System.Collections.Generic;
List<byte[]> segments =
	Data
		.Select( (onebyte, index) => new {Index=index,Value=onebyte} )
		.GroupBy( onebyte => onebyte.Index / 1008)
		.Select( onebyte => onebyte.Select( bytevalue => bytevalue.Value )
			.ToArray()
		).ToList();

We can then iterate over the resulting segments variable! Very cool.

Where's all this leading to? Well, the long and short is that I've written a C# library for interfacing with P1 and P2 model Paperang printers over USB, as well as a basic Windows front-end for it. You can find it on my GitHub!

Bad at this “blogging” thing

Whoops.

Continued

On encryption and jails

It was [reported recently][1] that [Let's Encrypt][2] had recently launched their private beta. As someone who does their best to ensure encryption is as widely-available as possible, I was excited.

Continued

New site, fantastically perl-y, because why not

Oops, and then I didn't have a blog for a few months. I pulled down my old blog (formerly located at blog.maff.me.uk), partially the .scot TLD launched and I wanted to move to maff.scot as soon as possible, and partially because I wanted a blog system I was happier working with (The old blog was dotClear-based, and hosted at [Gandi][1] because it was a free addon and I was lazy. I'd looked around for a while to see what blogging systems I could try out, but I didn't want to go near Wordpress and none of the other systems really appealed to me. Some friends suggested I try Jekyll, but I couldn't really grok that; I also found Dapper online, but as far as static-site platforms go it wasn't the best for a blog. So I wrote my own.

Continued

Gone, but not forgotten

Just a short post today.

Continued

Why I never (or rarely) place phone calls

If I want or need to contact someone, typically the first thing I check is my instant messenger. I use [Trillian][1], which keeps me logged into every IM service I use regularly (AIM, MSN and Gtalk). I also log into Skype on it if I need to. If the person I want to talk to isn't online or available there, I check Steam. If they're not available there, I text them. If I don't have their number or something, I message them on Facebook.

Continued

Why I love lighttpd

It's a well-known fact that I absolutely adore lighttpd. Why, you ask?

Continued

UnrealIRCd and SANICK

Note: This post is from many years ago, and I no longer operate an IRC network. No support is offered for this module.

Continued