Tweezing apart ESXi image – Part 1

How to tweeze apart the ESXi 4.1 infrastructure – Part 1: The imagedd.bz2 file

What you need

  • ESXi 4.1 ISO image
  • Linux server, with the following tools:
    1. mount
    2. dd
    3. od
    4. gunzip
    5. bzip2
    6. tar

      Method

      Copy the files from the CD:

      # mount -o ro,loop -t iso9660 VMware-VMvisor-Installer-4.1.0-260247.x86_64.iso /mnt
      # cp -rp /mnt /extract/
      # umount /mnt
      # cd /extract
      # md5sum imagedd.bz2
      17e94a90a1b66c81d2f37718295b75c1  imagedd.bz2
      # cat imagedd.md5
      17e94a90a1b66c81d2f37718295b75c1  VMware-VMvisor-big-260247-x86_64.dd.bz2

      Within the imagedd.bz2 compressed file is a raw dump of a disk. The first sector of which is a partition table (MBR signature 0xaa55 [stored in disk in little-endian format])

      # bzip2 -d < imagedd.bz2 > imagedd
      # od -A d -j 446 -N 66 -t x1 -v imagedd
      0000446 00 00 01 04 05 3f e0 83 00 20 00 00 00 00 1c 00
      0000462 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0000478 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0000494 80 01 01 00 04 3f 20 03 20 00 00 00 e0 1f 00 00
      0000510 55 aa
      0000512

      From this we can see that there are 2 partitions.

      Remember that the top 2 bits of the sector byte are bits 9 and 10 of the cylinder byte. (0xE0 becomes 0x20, and 0x83 becomes 0x383):

      # echo $((0xE0 & 0x3F))
      32
      # echo $((0xE0 >> 6))
      3

      From this we can deduce that the geometry of the disk is 32 sector per track, since MBR partitions are usually whole-cylinder aligned.
      And it also looks like there are 64 heads in total, since the partitions start on head 0, and finish on head 63,. So this makes the CHS geometry of the disk  [nnnn/64/32]. (We don’t know the absolute size of the disk yet, but by looking at the size of the image, and knowing the sectors and heads, we can work out the geometry:

      # ls -al imagedd
      -rw-r--r--  1 root root 943718400 Sep 29 13:57 imagedd
      # echo $((943718400 / 64 / 32 / 512))
      900

      So we get CHS = 900/64/32

      Now onto the partitions:

      (partition 1, non-bootable, partition type 0x05, H/S/C start 0x00/0x01/0x04, H/S/C end 0x3f/0x20/0x383)
      (partition 4, bootable, partition type 0x04, H/S/C start 0x01/0x01/0x00, H/S/C end 0x3f/0x20/0x03)

      To convert to LBA addresses, you use the formula:

      LBA = (CylinderNumber * [HeadsPerCylinder * SectorsPerTrack]) + (HeadNumber * [SectorsPerTrack]) + SectorNumber – 1

      (-1 since blocks are addressed from 0, but all sectors start from 1!)

      So this works out for our partitions:

      Partition 4:
      starting block (0x00 * 64 * 32) + (0x01 * 32) + 0x01 – 1 = 32
      ending block (0x03 * 64 * 32) + (0x3f * 32) + 0x20 -1 = 8191

      Partition 1:
      starting block (0x04 * 64 * 32) + (0x00 * 32) + 0x01 – 1 = 8192
      ending block (0x383 * 64 * 32) + (0x3f * 32) + 0x20 -1 = 1843199

      We can also verify the LBA offsets which occur in the last 8 bytes of each 16 byte partition record.

      20 00 00 00 == 0x00000020 == 32 [start]
      e0 1f 00 00 == 0x00001fe0 == 8160 [length]
      00 20 00 00 == 0x00002000 == 8192 [start]
      00 00 1c 00 == 0x001c0000 == 1835008 [length]

      So the LBA addresses are in agreement with the C/H/S addresses!

      If only that were that easy! Partition 1 is actually a primary partition with partition type 5, which means extended partitions are present

      Dealing with Extended Partitions

      Unlike the Primary Partition Table, The format of Extended Boot Records is such that the record immediately preceeds the data that it points to, followed up another record and so on. Only one extended partition exists per EBR.

      The extended partitions are stored within the data section pointed to by the extended partition. We can display it in exactly the same way:

      # od -A d -j $((8192*512+446)) -N 66 -t x1 -v imagedd
      4194750 00 01 01 04 06 3f 20 fd 20 00 00 00 e0 cf 07 00
      4194766 00 00 01 fe 05 3f 60 f7 00 d0 07 00 00 d0 07 00
      4194782 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      4194798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      4194814 55 aa
      4194816

      Extended partitions are numbered from 5.
      Going through the same process again, we have:

      (partition 5, non-bootable, partition type 0x06, H/S/C start 0x01/0x01/0x04, H/S/C end 0x3f/0x20/0xfd)
      Start 8224, End 520191 (and number of blocks according to LBA = 0x0007cfe0 == 511968)

      And the next line is not a partition, but a pointer to the next EBR. which is
      (next EBR = H/S/C start 0x00/0x01/0xfe, H/S/C end 0x3f/0x20/0x1f7)
      Start 520192, End 1032191

      Which is not surprising – the next EBR immediately follows partition 5.

      So now we must seek to this EBR partition:

      # od -A d -j $((520192*512 + 446)) -N 66 -t x1 -v imagedd
      266338750 00 01 01 fe 06 3f 60 f7 20 00 00 00 e0 cf 07 00
      266338766 00 00 41 f8 05 3f a0 65 00 a0 0f 00 00 70 03 00
      266338782 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      266338798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      266338814 55 aa
      266338816

      And the existence of the 0xaa55 marker confirms we have found the next record.

      So this gives us:

      (partition 6 = non-bootable, partition type 0x06, H/S/C start 0x01/0x01/0xfe, H/S/C end 0x3f/0x20/0x1f7)
      Start 520224, End 1032191

      Next EBR = H/S/C start 0x00/0x01/0x1f8, H/S/C end 0x3f/0x20/0x265)
      Start 1032192, End 1257471

      # od -A d -j $((1032192*512 + 446)) -N 66 -t x1 -v imagedd
      528482750 00 01 41 f8 fc 3f a0 65 20 00 00 00 e0 6f 03 00
      528482766 00 00 81 66 05 3f e0 83 00 10 13 00 00 f0 08 00
      528482782 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      528482798 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      528482814 55 aa
      528482816

      This one gives us:

      (partition 7 = non-bootable, partition type 0xfc, H/S/C start 0x01/0x01/0x1f8, H/S/C end 0x3f/0x20/0x265)
      Start 1032224, End 1257471

      Next EBR = H/S/C start 0x00/0x01/0x266, H/S/C end 0x3f/0x20/0x383
      Start 1257472, End 1843199

      # od -A d -j $((1257472*512 + 446)) -N 66 -t x1 -v imagedd
      643826110 00 01 81 66 06 3f e0 83 20 00 00 00 e0 ef 08 00
      643826126 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      643826142 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      643826158 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      643826174 55 aa
      643826176

      And this time, since the next EBR record is blank, this will be the last extended partition.

      (partition 8 = non-bootable, partition type 0x06, H/S/C start 0x01/0x01/0x266, H/S/C end 0x3f/0x20/0x383)
      Start 1257504, End 1843199

      Summary

      So, in summary, the partition table looks like this:

      Partition 1 :    8192 - 1843199        Type 0x05 (Extended Partition)
      Partition 4 :      32 -    8191        Type 0x04
      Partition 5 :    8224 -  520191        Type 0x06
      Partition 6 :  520224 - 1032191        Type 0x06
      Partition 7 : 1032224 - 1257471        Type 0xFC
      Partition 8 : 1257504 - 1843199        Type 0x06
      

      Whilst we could have done this with “fdisk”, it’s nice to see how to do it manually.

      Now we know the partition offsets, we can tweeze apart this file further.

      Advertisements

      Leave a Reply

      Fill in your details below or click an icon to log in:

      WordPress.com Logo

      You are commenting using your WordPress.com account. Log Out / Change )

      Twitter picture

      You are commenting using your Twitter account. Log Out / Change )

      Facebook photo

      You are commenting using your Facebook account. Log Out / Change )

      Google+ photo

      You are commenting using your Google+ account. Log Out / Change )

      Connecting to %s

      %d bloggers like this: