2013.07.28

Recently I came across an old recovery disk for my parents’ old 486 from 1993 (the first machine I really seriously programmed — the Tandy before it got some QBasic time, but nothing as crazy as a C compiler. Some real mode assembly though once or twice). I managed to cobble things together to get it booting in VirtualBox (you see, in those days booting from CD didn’t exist, so the CD itself isn’t bootable, it just has a bunch of zips that were written to floppies by an operational system — getting that up and running is a post for another day, but it required hexediting the virtual harddrive to lay down IO.SYS and MSDOS.SYS properly in FAT16, whee).

Anyway, after it was up and running, I figured it might be fun to start tearing it apart (since the entire machine state fits in RAM (4MB RAM, 512MB harddrive, 527MB restore CD, a couple 1.4MB boot floppies) it’s easy to blow it away and restore it very rapidly.

So, let’s start from the beginning, the Master Boot Record. This the MBR laid down by DOS 6. Before this there’s the BIOS, but unfortunately I don’t have access to that (otherwise, it’d be a fun but much more complex piece of software to explore), and the MBR’s really tiny (just 512 bytes, of which only like 446 or so are executable code).

Here’s the Hex for a DOS 6 MBR on a ~512MB harddrive with just 1 “primary DOS partition”.

55AA at the end indicates a “valid” boot sector (sort of). The long stream of zeros mid-way through starts the unused bit, and the stuff just before the end is the Partition Table (we’ll ignore that for now — look it up on wikipedia if you’re curious).

So we see a couple strings in there: “Invalid partition table” and “Error loading operating system” and “Missing operating system”. Those three cover about a third of the bytes. Now let’s look at the disassembly.

For reference, the first string starts at 0x8C (140) bytes, and after the strings it looks like it’s just zeros until the partition table, so we’ll focus our disassembly efforts on the first 0x8B (139) bytes. Also, the BIOS loads the MBR at 0x7C00, so we’ll tell the disassembler to pretend like the code is at that location in memory. It also starts in Real Mode (1MB addressable, segmented, no virtual memory, dark ages stuff). Here we go.

Ok, so just a few instructions in, we’ve got some basic but useful stuff going on. Initially it zeros out all the segment registers (ss, es, ds, and cs) because the BIOS could leave them weird, it sets up the stack at 0x7c00 (just under the MBR), and then it copies 256 words (512 bytes) from 0x7c00 to 0x600 (this copies the MBR from 0x7c00 to 0x600). Then we jump to 0x61d (notice how the next instruction is at address 0x7C1D — that’s 0x1D bytes after the beginning of the MBR. 0x61d is 0x1d bytes beyond the start of the copied MBR, so basically that jump jumps to the next instruction, but at a different location in memory). It’s common for MBRs to copy themselves elsewhere, and then load stuff at 0x7c00 (this is why they move themselves out of the way). So now let’s disassemble it again, but with the assembler thinking it’s at 0x600 (since that’s where the remainder of the code will be executing).

This time, there’s a lot of flow control, so I’ve interjected a lot of commentary in-line

So there we have it. 139 bytes of code, and it relocates itself to 0x600, checks the partition table, if it’s good it loads the first sector of the active partition to 0x7c00, and then jumps to it, otherwise it prints error messages. It has some retries and some sanity checks, but otherwise it’s pretty straightforward. Next time we’ll check out the sector it loads and see what that does.

2010.07.31

A few days ago I was chatting with some friends, and the topic of caching came up. I mentioned MESI, which is the basis for modern multicore cache coherence (There are variants like MOESI and MERSI, but the general idea is the same). It then occurred to me that I’ve never actually made a test to see the effects of MESI in action. (more…)

2010.06.28

NX, or the No eXecute bit, is an interesting technology that prevents instructions on the stack from getting executed. The reason for this is security (stack smashing becomes a bit more difficult for a would-be attacker), and the implications are typically few and far between. (more…)

2009.07.02

(apologies in advance — this will be a rather technical post. It’s eventually intended for fdiv.net, but while it’s getting migrated I figured I’d plop it down here.)

Instance Variables (or, more briefly, ivars) are a pretty simple trend in Object Oriented Languages. They’re data that get carried along inside an object, helping to define its state. While it would be fun to elaborate more on this, this particular article isn’t intended to teach the basics of OOP. So if you’re unsure of what an ivar is, this article probably isn’t for you. (more…)

2009.05.15

A lot of lists have popped up where I frequent (digitally, at least) lately. Intended schedules, self-diagnostics, recipes, time-lapse accomplishments, etc. You know the drill. At one point in the not-so-distant past, I was probably pretty good maintaining such things as well. I suppose I need to refine my time management skills (or lack thereof) to keep things fresh. (more…)

2008.06.19

From time to time I accumulate cute little hacks that help debug/reverse engineer stuff in Objective-C. Typically, these are gdb macros that help introspect data from within a live program, though sometimes it’s a blob of ObjC code that does something fun when injected into the runtime. Today, I’ve discovered something extraordinarily helpful that falls into neither of those categories. (more…)

2008.06.02

The past few weeks have been largely under the radar, with a lot going on with software, finance, and Alias. I always find it funny when people start approaching me in real life to ask whether or not things are going ok since I haven’t written anything in N weeks (where N is an integer greater than 0). Fear not, I am ok 🙂 (more…)

2008.05.13

In computer science, there is a technique called “Lazy Evaluation” that finds use in performance saving and error avoidance. It works by holding off on performing calculations until it is known for certain that the results are needed. (more…)