How to write say first n bytes of a binary file at a specific HDD sector using Linux dd?

0

I have a VMWare Virtual machine Windows 10 & I have booted into Live Linux Mint.

I just want to write say first n bytes of a binary file to a specific sector on the HDD using dd on Linux. For this purpose I have added a 500MB Virtual HDD in Windows and formatted as NTFS.

The command I am using is

sudo  dd of=/dev/sdb if=/media/mint/<mount>/Temp/mbr.img bs=11 seek=1000 count=1

Here /dev/sdb is the 500 MB HDD (Not a partition on it)

/media/mint/(mount)/Temp/mbr.img is the binary file. I just dumped the MBR for example.

bs=11 I hope this is for the 11 bytes

seek =1000 I hope this is to go to 1000 th sector (512 bytes per sector default)

The command completes successfully.

However when from within Windows 10 Hex Workshop I check the contents of sector 999,1000 & 1001 (I am not too sure what seek=1000 resolves to) they are blank. Nothing is written on to it from the mbr.img.

When I search for sample data of first 11 Bytes on the HDD, I don't find it anywhere.

In Hex Workshop I am sticking to decimal numbers for jumping to a sector.

Can someone help me further troubleshoot what is the mistake/issue here?

enter image description here

rajeev

Posted 2018-09-24T11:44:02.877

Reputation: 1 088

Answers

2

From man 1 dd:

bs=BYTES
read and write BYTES bytes at a time (also see ibs=,obs=)

ibs=BYTES
read BYTES bytes at a time (default: 512)

obs=BYTES
write BYTES bytes at a time (default: 512)

seek=BLOCKS skip BLOCKS obs-sized blocks at start of output

By using bs=11 you affect ibs and obs. seek=1000 uses obs. You expect to skip 1000 sectors of output but instead you skip 1000 chunks of output, 11 bytes each.

It looks like you wanted something like

sudo dd if=/path/to/mbr.img ibs=11 count=1 of=/dev/sdb obs=512 seek=1000 

Kamil Maciorowski

Posted 2018-09-24T11:44:02.877

Reputation: 38 429

0

If you set the block size bs to 11, and then seek for 1000 blocks, you've skipped 1000*11 = 11000 bytes instead of 1000*512=512000 bytes for 1000 sectors. So, obviously, that can't work, and you have now changed some other part of your harddisk, which may come back to bite you (so think about a way of undoing that change).

I know you can use dd to write files with byte precision, so on a file you could do something like

dd ... bs=1 count=11 seek=512000

However, I'm not sure if you can write a part of a block on /dev/sdb. If you can't, one way is to copy that particular block with something like

dd if=/dev/sdb of=/tmp/myblock bs=512 skip=1000 count=1

then either edit the file /tmp/myblock, or use dd to make byte-precision changes as explained above (but without the seek, of course, because the file consists only of the block you want to change), and finally write the block back with

dd of=/dev/sdb if=/tmp/myblock bs=512 seek=1000 count=1

dirkt

Posted 2018-09-24T11:44:02.877

Reputation: 11 627

If you try, please report if direct byte-precision changes (bs=1) work - I'd like to know if they do. – dirkt – 2018-09-24T12:35:39.717

1In my Debian I can change a single byte within a HDD sector, not affecting neighboring bytes. I think the kernel has to read the whole sector, change the byte and write the whole modified sector back; but such manipulations are its job, not dd's (nor any userland tool's). – Kamil Maciorowski – 2018-09-24T12:43:39.037

@KamilMaciorowski: The kernel certainly has to do a read before a write, the question was if it actually does this on block device nodes in the first place (one alternative would have been to just ignore non-blocksized writes, or to throw an error). Which is why I included a workaround. – dirkt – 2018-09-24T12:48:16.627

Yes, I tried the command as suggested by Kamil Maciorowski and it exactly copied the specified n bytes from start of the file to a specified sector. Thank you to you for your answer as well. Learnt something new today. – rajeev – 2018-09-24T13:45:38.203