09: Acquisition, Volumes, MBRs
DRAFT
Announcements
Facepalm.
SFS https://infosec.cs.umass.edu/content/umass-amherst-scholarship-service-program
Introduction
In previous lectures, we dealt with problems of parsing and carving individual files or portions of files. Now, we’ll turn our attention to one of the major tasks of digital forensics: disk drive imaging (“acquisition”) and analysis of the data so acquired.
So what does it mean to “image” a drive? It means we make a bit-for-bit copy of the raw data stored on that drive and save it as a file on another computer. This is usually referred to as a “raw image” of the drive.
We’ll restrict our attention to the use of OS-level acquisition tools, though there are (in older machines) tools that access drives through the BIOS, and there are hardware-based acquisition tools as well. Carrier provides an (older) summary; the Forensics Wiki is more up to date.
Drives on computers
Depending upon your OS, you might have graphical tools and/or command-line tools built into the system to view drives on your computer. For example, on OS X I can use “Disk Utility” to examine the drives that are mountable on a system (demo w/ laptop and USB drive). But it doesn’t show me everything; “System Information” shows a more comprehensive view. (Note “BSD Name:”, more on this in a bit.)
On a Linux system, there are various ways to see what drives are available. mount
shows which drives (partitions, actually) are mounted. (OS X supports this command too.) During boot, the kernel shows a list of hardware as it’s detected. You can use dmesg
to view this log after-the-fact. (Demo on virtual machine and/or elnux.)
PCs generally often have some sort of “boot menu” that lets you see what drives are attached, too, using the BIOS (or these days, UEFI running on built-in firmware that runs on the computer’s motherboard) but I can’t demo that on my Mac.
And of course, we can turn to the sleuthkit to interrogate a drive, like my Mac’s HD, and a USB:
sudo mmls /dev/rdisk0
GUID Partition Table (EFI)
Offset Sector: 0
Units are in 512-byte sectors
Slot Start End Length Description
000: Meta 0000000000 0000000000 0000000001 Safety Table
001: ------- 0000000000 0000000039 0000000040 Unallocated
002: Meta 0000000001 0000000001 0000000001 GPT Header
003: Meta 0000000002 0000000033 0000000032 Partition Table
004: 000 0000000040 0000409639 0000409600 EFI system partition
005: 001 0000409640 0585210495 0584800856 Iron
006: 002 0585210496 0586480031 0001269536 Recovery HD
007: ------- 0586480032 0586481663 0000001632 Unallocated
008: 003 0586481664 0976842879 0390361216 Apple_HFS_Untitled_2
009: ------- 0976842880 0977105059 0000262180 Unallocated
sudo mmls /dev/rdisk2
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors
Slot Start End Length Description
000: Meta 0000000000 0000000000 0000000001 Primary Table (#0)
001: ------- 0000000000 0000000031 0000000032 Unallocated
002: 000:000 0000000032 0003913727 0003913696 DOS FAT16 (0x06)
(More on /dev/rdisk[n]
in a moment)
You can think of hard disk drives (old-style spinning metal or newer SSDs) as a giant array of bytes. This obviously isn’t the most useful view all the time (where did I put my program? At byte 3D7A149F?) but it is the most fundamental way to view the drive.
Unix-like OSes (including OS X) expose disk drives as a file, stored in a special location. Most devices that can be exposed as files are in the /dev
directory, and disks are no exception.
For example, on OS X, the raw bytes of my disk drives are accessible /dev/rdisk* (and the block-buffered bytes at /dev/disk* – these are the “BSD Names”). Linux has similar devices at /dev/sda*. You can directly access these if you like. Here’s the first 512 bytes of my Mac’s hard disk:
sudo hexdump -Cv -n 512 /dev/rdisk0
00000000 33 c0 8e d0 bc 00 7c 8e c0 8e d8 be 00 7c bf 00 |3.....|......|..|
00000010 06 b9 00 02 fc f3 a4 50 68 1c 06 cb fb b9 04 00 |.......Ph.......|
00000020 bd be 07 80 7e 00 00 7c 0b 0f 85 0e 01 83 c5 10 |....~..|........|
00000030 e2 f1 cd 18 88 56 00 55 c6 46 11 05 c6 46 10 00 |.....V.U.F...F..|
00000040 b4 41 bb aa 55 cd 13 5d 72 0f 81 fb 55 aa 75 09 |.A..U..]r...U.u.|
00000050 f7 c1 01 00 74 03 fe 46 10 66 60 80 7e 10 00 74 |....t..F.f`.~..t|
00000060 26 66 68 00 00 00 00 66 ff 76 08 68 00 00 68 00 |&fh....f.v.h..h.|
00000070 7c 68 01 00 68 10 00 b4 42 8a 56 00 8b f4 cd 13 ||h..h...B.V.....|
00000080 9f 83 c4 10 9e eb 14 b8 01 02 bb 00 7c 8a 56 00 |............|.V.|
00000090 8a 76 01 8a 4e 02 8a 6e 03 cd 13 66 61 73 1c fe |.v..N..n...fas..|
000000a0 4e 11 75 0c 80 7e 00 80 0f 84 8a 00 b2 80 eb 84 |N.u..~..........|
000000b0 55 32 e4 8a 56 00 cd 13 5d eb 9e 81 3e fe 7d 55 |U2..V...]...>.}U|
000000c0 aa 75 6e ff 76 00 e8 8d 00 75 17 fa b0 d1 e6 64 |.un.v....u.....d|
000000d0 e8 83 00 b0 df e6 60 e8 7c 00 b0 ff e6 64 e8 75 |......`.|....d.u|
000000e0 00 fb b8 00 bb cd 1a 66 23 c0 75 3b 66 81 fb 54 |.......f#.u;f..T|
000000f0 43 50 41 75 32 81 f9 02 01 72 2c 66 68 07 bb 00 |CPAu2....r,fh...|
00000100 00 66 68 00 02 00 00 66 68 08 00 00 00 66 53 66 |.fh....fh....fSf|
00000110 53 66 55 66 68 00 00 00 00 66 68 00 7c 00 00 66 |SfUfh....fh.|..f|
00000120 61 68 00 00 07 cd 1a 5a 32 f6 ea 00 7c 00 00 cd |ah.....Z2...|...|
00000130 18 a0 b7 07 eb 08 a0 b6 07 eb 03 a0 b5 07 32 e4 |..............2.|
00000140 05 00 07 8b f0 ac 3c 00 74 09 bb 07 00 b4 0e cd |......<.t.......|
00000150 10 eb f2 f4 eb fd 2b c9 e4 64 eb 00 24 02 e0 f8 |......+..d..$...|
00000160 24 02 c3 49 6e 76 61 6c 69 64 20 70 61 72 74 69 |$..Invalid parti|
00000170 74 69 6f 6e 20 74 61 62 6c 65 00 45 72 72 6f 72 |tion table.Error|
00000180 20 6c 6f 61 64 69 6e 67 20 6f 70 65 72 61 74 69 | loading operati|
00000190 6e 67 20 73 79 73 74 65 6d 00 4d 69 73 73 69 6e |ng system.Missin|
000001a0 67 20 6f 70 65 72 61 74 69 6e 67 20 73 79 73 74 |g operating syst|
000001b0 65 6d 00 00 00 63 7b 9a 7d 6e 00 00 00 00 00 fe |em...c{.}n......|
000001c0 ff ff ee fe ff ff 01 00 00 00 a3 70 3d 3a 00 00 |...........p=:..|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
and of my virtual machine’s hard disk:
00000000 eb 63 90 10 8e d0 bc 00 b0 b8 00 00 8e d8 8e c0 |.c..............|
00000010 fb be 00 7c bf 00 06 b9 00 02 f3 a4 ea 21 06 00 |...|.........!..|
00000020 00 be be 07 38 04 75 0b 83 c6 10 81 fe fe 07 75 |....8.u........u|
00000030 f3 eb 16 b4 02 b0 01 bb 00 7c b2 80 8a 74 01 8b |.........|...t..|
00000040 4c 02 cd 13 ea 00 7c 00 00 eb fe 00 00 00 00 00 |L.....|.........|
00000050 00 00 00 00 00 00 00 00 00 00 00 80 01 00 00 00 |................|
00000060 00 00 00 00 ff fa 90 90 f6 c2 80 74 05 f6 c2 70 |...........t...p|
00000070 74 02 b2 80 ea 79 7c 00 00 31 c0 8e d8 8e d0 bc |t....y|..1......|
00000080 00 20 fb a0 64 7c 3c ff 74 02 88 c2 52 bb 17 04 |. ..d|<.t...R...|
00000090 f6 07 03 74 06 be 88 7d e8 17 01 be 05 7c b4 41 |...t...}.....|.A|
000000a0 bb aa 55 cd 13 5a 52 72 3d 81 fb 55 aa 75 37 83 |..U..ZRr=..U.u7.|
000000b0 e1 01 74 32 31 c0 89 44 04 40 88 44 ff 89 44 02 |..t21..D.@.D..D.|
000000c0 c7 04 10 00 66 8b 1e 5c 7c 66 89 5c 08 66 8b 1e |....f..\|f.\.f..|
000000d0 60 7c 66 89 5c 0c c7 44 06 00 70 b4 42 cd 13 72 |`|f.\..D..p.B..r|
000000e0 05 bb 00 70 eb 76 b4 08 cd 13 73 0d 5a 84 d2 0f |...p.v....s.Z...|
000000f0 83 d0 00 be 93 7d e9 82 00 66 0f b6 c6 88 64 ff |.....}...f....d.|
00000100 40 66 89 44 04 0f b6 d1 c1 e2 02 88 e8 88 f4 40 |@f.D...........@|
00000110 89 44 08 0f b6 c2 c0 e8 02 66 89 04 66 a1 60 7c |.D.......f..f.`||
00000120 66 09 c0 75 4e 66 a1 5c 7c 66 31 d2 66 f7 34 88 |f..uNf.\|f1.f.4.|
00000130 d1 31 d2 66 f7 74 04 3b 44 08 7d 37 fe c1 88 c5 |.1.f.t.;D.}7....|
00000140 30 c0 c1 e8 02 08 c1 88 d0 5a 88 c6 bb 00 70 8e |0........Z....p.|
00000150 c3 31 db b8 01 02 cd 13 72 1e 8c c3 60 1e b9 00 |.1......r...`...|
00000160 01 8e db 31 f6 bf 00 80 8e c6 fc f3 a5 1f 61 ff |...1..........a.|
00000170 26 5a 7c be 8e 7d eb 03 be 9d 7d e8 34 00 be a2 |&Z|..}....}.4...|
00000180 7d e8 2e 00 cd 18 eb fe 47 52 55 42 20 00 47 65 |}.......GRUB .Ge|
00000190 6f 6d 00 48 61 72 64 20 44 69 73 6b 00 52 65 61 |om.Hard Disk.Rea|
000001a0 64 00 20 45 72 72 6f 72 0d 0a 00 bb 01 00 b4 0e |d. Error........|
000001b0 cd 10 ac 3c 00 75 f4 c3 de 9c 09 00 00 00 80 20 |...<.u......... |
000001c0 21 00 83 a9 23 65 00 08 00 00 df f7 ff 04 00 00 |!...#e..........|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
and of a USB key:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 00 00 00 00 60 9d b9 ec 00 00 00 00 |........`.......|
000001c0 21 00 06 2a ea ca 20 00 00 00 e0 b7 3b 00 00 00 |!..*.. .....;...|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
There are some similarities: you can see some sort of error message (presumably displayed if this disk cannot boot) on the bootable drives and you’ll notice the end of the 512 bytes are zero-padded, but end with the values 55 aa
. Not a coincidence!
Imaging a drive
I kinda already let the horse outta the barn, above: you can directly read these “files” and you’ll get the bytes from the disk. Of course, we don’t usually do it with hexdump. Instead, there are various utilities that can do it for you. The simplest such is dd
, which just copies bytes block-by-block (default: 512 bytes at a time) from an input (default: standard in) to an output (default: standard out).
The basic invocation looks like this:
dd if=/dev/rdisk0 of=/Users/liberato/disk-image.dd bs=512
Though that won’t work: I can’t image an entire drive into a file inside a filesystem on the drive, for obvious (I hope) reasons. Usually, you need another drive to capture the data to. For demonstration purposes, I’ll limit the count
of blocks here so that (a) data fits and (b) it doesn’t take all day.
dd if=/dev/rdisk0 of=/Users/liberato/disk-image.dd bs=512 count=10
Output:
10+0 records in
10+0 records out
5120 bytes transferred in 0.001093 secs (4683716 bytes/sec)
10 full records + 0 partial records in and out.
I can also compute a hash of the file and/or the drive:
shasum /dev/rdisk0 # note that this will take a looong time
Again, I can read just some of the drive for demonstration purposes:
dd if=/dev/rdisk0 bs=512 count=10 | shasum
10+0 records in
10+0 records out
5120 bytes transferred in 0.003004 secs (1704352 bytes/sec)
4556ea34b55f51eb35b9338e47b07e6710378f98 -
And check the bytes I saved:
shasum /Users/liberato/disk-image.dd
4556ea34b55f51eb35b9338e47b07e6710378f98 disk-image.dd
There are a couple other details to consider. First, what if the drive has errors? The simplest thing to do is replace the sectors you cannot read with just 0s in the image. You must pass two options to the conv
argument of dd
to make this happen:
dd if=/dev/rdisk0 of=/Users/liberato/disk-image.dd bs=512 count=10 conv=noerror,sync
noerror
means to not stop on error, and sync
pads erroneous read with NUL (zero) bytes. See man dd
for more details.
(Data recovery of corrupted hardware is beyond the scope of this course.)
Finally, a note expounded upon more in the text. In this day and age, forensic exams that are conducted on-site are conducted according to a protocol.
Machines that are off are brought back to a lab, and the drive is imaged. But notably, we don’t (usually) boot the OS on the machine; instead we boot from a known-good OS (like, say a Linux LiveCD) and use it to run the imaging operation. We might also interpose a hardware and/or software “write blocker” to prevent making changes to the drive being imaged. This overall process is called a “dead acquisition.”
In contrast, a “live acquisition” is performed on a running machine. Usually, we might dump memory of an active machine or do other memory forensics (a topic we may touch upon later in the semester), then decide whether to attempt a live acquisition or to shut the machine down to prevent further changes. Lots of factors to consider here, including:
- techincal sophistication of the user
- presence of disk encryption
- rootkits
- etc.
that go beyond the scope of this lecture.
Interpreting the data: Disk volumes
So now we know how to get some or all of the raw data from a disk. What does it mean?
To answer this question, we’re going to first introduce some terminology and sketch some abstract examples of how disks are organized. Then we’ll dive into some specifics.
“Volumes” are organized by “volume systems”, assembled from one or more disks, usually but not always 1:1. A volume is a collection of addressable “sectors” (sometimes also: “blocks”) which are the smallest unit of addressing that most disk controllers support (older disks: 512 bytes; newer disks can be larger (4KB or Advanced Format) but have backward-compatibility translation layers(!!)) that appear continuous to the OS.
Volumes are usually divided into one or more “partitions”. A partition names a particular collection of consecutive sectors in a volume. For example, my Mac’s HD has two user-visible partitions (show in Disk Utility), as well as two that are not visible through the GUI (show in System Report):
EFI:
Capacity: 209.7 MB (209,715,200 bytes)
BSD Name: disk0s1
Content: EFI
Volume UUID: BDC1974F-6B8C-3DAE-9DB2-3AA3C17BF506
disk0s2:
Capacity: 299.42 GB (299,418,038,272 bytes)
BSD Name: disk0s2
Content: Apple_CoreStorage
Recovery HD:
Capacity: 650 MB (650,002,432 bytes)
BSD Name: disk0s3
Content: Apple_Boot
Volume UUID: 42320CA6-833A-3699-AAC3-64080DD45FF8
Cobalt:
Capacity: 199.86 GB (199,864,942,592 bytes)
Available: 198.94 GB (198,938,521,600 bytes)
Writable: Yes
File System: Journaled HFS+
BSD Name: disk0s4
Mount Point: /Volumes/Cobalt
Content: Apple_HFS
Volume UUID: 42E09BD5-9547-36E4-9879-4BB9C01484EB
And here’s a partition on the USB key:
MARC'S USB:
Capacity: 2 GB (2,003,812,352 bytes)
Available: 2 GB (2,001,010,688 bytes)
Writable: Yes
File System: MS-DOS FAT16
BSD Name: disk2s1
Mount Point: /Volumes/MARC'S USB
Content: DOS_FAT_16
Volume UUID: 8117D4F3-4CD8-38D5-8B94-75D720C736A5
Different operating systems and devices use different methods of partitioning drives and labeling them, though most modern consumer PC hardware and OSes (Windows, Mac, Linux) these days are converging on two standards: the newer Unified Extensible Firmware Interface’s GUID Partition Table, and legacy support for Master Boot Records (notably, on basically every USB thumb drive and SD storage card in existence, as well as older PCs). There are other formats, but understanding these two will give you the basis to understand others if you need to.
If you want to carve out individual partitions, you can use mmls
to find their offsets, then dd
to read/write them (note you can pass a skip
or iseek
parameter to dd
). But usually you would just operate on the entire image; most toolsets (TSK included) have other, volume-aware tools to deal with individual partitions, as we showed in our demo in Lecture 2.
The Master Boot Record
The older “master boot record” (MBR) style of partitioning (sometimes called “DOS” style, as it’s the OS that popularized this format) has no formal standard, though it’s well documented in many places since it’s so ubiquitious.
In its simplest form, a MBR contains three things:
- boot code (literally: it’s executable code that the BIOS will load then execute)
- a partition table
- a signature
Note that modern MBRs on HDDs and SSDs don’t contain bootcode – the firmware handles this now, and the bootcode area is used for other information instead. We’ll talk more about this when we get to UEFI. (See https://en.wikipedia.org/wiki/Master_boot_record#Sector_layout.) And USBs don’t usually contain bootcode either.
The signature value we’ve seen already: The last two bytes of a sector containing a MBR are 55 AA
; this is another “magic number” not unlike the SOI/EOI tags in a JPEG file. Seeing it is not a guarantee of a valid MBR, but not seeing it means it’s definitely not an MBR.
A disk with three partitions has an MBR then three partitions, and the MBR has entries for each of the three partitions: (on board). These entries are stored in the partition table.
Each of the (at most four) entries contains the following (https://en.wikipedia.org/wiki/Master_boot_record#PTE):
- status/flags (1 byte)
- starting CHS address (3 bytes)
- type (1 byte)
- ending CHS address (3 bytes)
- starting LBA sector (4 bytes)
- number of sectors (4 bytes)
CHS is a legacy system (when disk locations where referred to by Cylinder / Head / Sector, see https://en.wikipedia.org/wiki/Cylinder-head-sector if you’re curious) and basically irrelevant these days. These values are often hardcoded to various marker values that indicate that LBA address should be used instead, e.g., (1023, 254, 63) or (1023, 255, 63).
The type is a value you look up in a table (e.g., https://en.wikipedia.org/wiki/Partition_type) though different OSes and tools might name different types slightly differently due to the lack of a standard here.
The LBA sector is an offset from the start of the disk, in terms of 512-byte sectors, to the start of the partition, and the number of sectors tells you how bit that partition is. Easy-peasy.
Or is it? What if you want more than four partitions on a disk?
MBR and extended partitions
Instead of a nice neat table, you end up with a hybrid. (Up to) the first three partitions are treated as normal and given entries in the MBR. The last partition in the MBR is turned into a “Primary Extended Partition,” which is further subdivided into what looks like a linked-list of “Secondary Extended Partitions.”
Each of these extended partitions starts with an “Extended Boot Record” which is just a simplified version of the MBR, containing two entries:
- The first entry is the data partition as you’d expect: it points to the data partition (offset from this EBR) and contains the length of this partition, in sectors.
- The second entry is the address of the next EBR relative to the start of the primary extended partition; it’s length includes all sectors in that span up to the end of that partition, not just filled ones (as some sectors can be unallocated for various reasons).
Extended partitions are a PITA but are becoming more rare as GPTs are becoming standard. (And MBRs on USB keys and the like typically have just a single partition, so generally no extended partition nonsense occurs there.)
Let’s pull up the MBR documentation on Wikipedia https://en.wikipedia.org/wiki/Master_boot_record#Sector_layout (see also Carrier for a good alternative presentation) and the MBR of my USB key, and see what we can see:
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000100 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001b0 00 00 00 00 00 00 00 00 60 9d b9 ec 00 00 00 00 |........`.......|
000001c0 21 00 06 2a ea ca 20 00 00 00 e0 b7 3b 00 00 00 |!..*.. .....;...|
000001d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200
Very important: All multi-byte fields are little endian in the MBR!
Let’s look at just the partition table, starting at 0x1BE:
00 00 21 00 06 2a ea ca 20 00 00 00 e0 b7 3b 00
And now let’s parse it:
https://en.wikipedia.org/wiki/Master_boot_record#PTE
00
: status (not bootable)00 21 00
: CHS start (ignore)06
: type 0x06 is FAT-16 https://en.wikipedia.org/wiki/Partition_type2a ea ca
: CHS end (ignore)20 00 00 00
: LBA start, in this case 32 sectors from the start of the diske0 b7 3b 00
: number of sectors in partition (not its LBA end!) To convert in Python, use:struct.unpack('<I', bytes.fromhex('e0 b7 3b 00'))[0]
, in this case 3913696
Does this match mmls
?
mmls /dev/rdisk2
DOS Partition Table
Offset Sector: 0
Units are in 512-byte sectors
Slot Start End Length Description
000: Meta 0000000000 0000000000 0000000001 Primary Table (#0)
001: ------- 0000000000 0000000031 0000000032 Unallocated
002: 000:000 0000000032 0003913727 0003913696 DOS FAT16 (0x06)
Look at that! We can parse MBRs!
A note about partitions and slack
There’s nothing in the MBR that implies all sectors will be part of a partition. Space that’s not allocated is not accessible under OSes. One could imagine deleting a partition entry in an MBR to “hide” it from examination, and putting it back in when you wanted to access the data.