Search code examples
mountvhd

RAW write to a vhd without mounting


I know that if you mount an vhd (or another virtual disk format), you can write to it. But how can you write to a vhd without mounting it? Is there a good piece of software to use?

By raw i mean what HDD Raw Copy Tool provides. You can just take a textfile or another file an write the bytes in it exactly to a disk.


Solution

  • For a "fixed" VHD you could, as you said : "just take a textfile or another file an write the bytes in it exactly to a disk." Fixed VHDs are just flat disk images plus a 512 footer at the end. As long you don't touch this trailing footer the raw block level edits (manual or programmatic) should be fine.

    For dynamic VHDs or any other sparse representation of a physical disk, the task boils down to translating logical disk offsets into the "container" file offsets. Specifically, for dynamic VHDs, the entire length of the physical disk is divided into logical 2MB windows. The dynamic VHD representation of this physical disk is essentially a sequence of such 2MB blocks, in no particular order. Meaning: In dynamic VHD image, a 2MB (physical) disk window could potentially reside (in the dynamic VHD) after a 2MB disk window which in the actual disk would always be physically before the first 2 MB window. The mapping of which VHD block corresponds to which physical disk window is maintained in the Block Allocation Table. BAT entries (unlike how data blocks are potentially positioned non-sequentially) are ordered and contain the dynamic VHD file offset of the corresponding container data block.

    So all we have to do is: find the "VHD file offset" of the logical block which we need to write to using the entry for the 2MB logical window present in the BAT. Then, add 512 to it (i.e. skip the sector bitmap which precedes every block). The VHD file offset which you get at this point is the offset where you need to write to given the input, logical disk offset. It is quite possible that the BAT does not have an entry for the logical disk block that you need to write to. In such scenario, you need to append a new [512 Bytes + 2MB] data block to the dynamic VHD, update the BAT entry to point to the start of this block (the 512 sector) and then update the dynamic header and footer's CRC field since we have updated the BAT (CRC is over it). Please bear in mind that this scheme is valid only for dynamic VHDs which are not linked. Meaning, if there's a linked differencing child VHD then we should apply the above process on the child and not the base. The relationship on who's the parent and who's the child are again present in the dynamic VHD's header. Writing to the child additionally requires updating the 512 byte sector bitmap.

    Every virtualized image container has similar schemes to represent disk blocks in a sparse fashion. If we go through the format then reading and writing (at block level) is possible. Furthermore, for most cases we could, in principle, do granular volume level reads by translating volume level offsets to disk level and then running the above look-ups