-2

I was trying to write a program as a proof of concept in order to delete the GPT partition table from my HDD. To cut it short after opening the disk, I do something like the following:

   //Removes the first partition table in the beginning of the disk
    ::lseek(fd, 0, SEEK_SET);
    ::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);
    
    //Removes the backup partition in the end of the disk
    ::lseek(fd, -GPT_PARTITION_TABLE_SIZE, SEEK_END);
    ::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);

Even though that seemed to work well, I got a word from a friend that this way is not correct and I should use a local buffer for writing and that my code tries to use NULL as a pointer into write() which is not the right way.

I spend quite a few hours to understand what he meant, but I am still not sure I get it. Has anyone have ever tried something similar?

Machavity
  • 30,841
  • 27
  • 92
  • 100
Cooli
  • 169
  • 3
  • 14
  • 1
    Are you sure this worked? It looks like you wrote a partition size chunk.of random memory starting at address 0. – Neil Dec 12 '17 at 21:26
  • What did you *intend* to write, by using `'\0'`? Do you intend to write zeros? How many of them? – Greg Hewgill Dec 12 '17 at 21:26
  • @Cooli You didn't check return value of `write`. It actually failed and didn't write anything. –  Dec 12 '17 at 21:31
  • @Greg @Neil Yes that was the idea. Further up in my code I define the GPT_PARTITION_TABLE_SIZE as: `#define GPT_PARTITION_TABLE_SIZE (34 * 512)` – Cooli Dec 12 '17 at 21:32
  • @Ivan Hmm could it be that write way would be to, create a buffer first, e.g.char buf[GPT_PARTITION_TABLE_SIZE]; : : And then call the write like e.g.: ::write(fd, buf, strlen(buf)); ? – Cooli Dec 12 '17 at 21:47
  • 1
    Do you understand that the 2nd parameter to `write()` is a pointer, and how it should work? If you don't, then you should probably review the last few chapters in your C++ book, you're missing some fundamental concepts, and stackoverflow.com isn't really a tutorial site. – Sam Varshavchik Dec 12 '17 at 21:47
  • I doubt you'll be able to write to the raw disk from C++ without the help of either some syscall/kernel API or raw asm (which I doubt your kernel will allow to bypass it and its disk driver - unless your OS is DOS or similar - btw; what OS are you using?). – Jesper Juhl Dec 12 '17 at 22:04
  • @Jesper, As far as I looked into it, it looks like it is doable. For the record, I am using linux. – Cooli Dec 12 '17 at 23:25

1 Answers1

4

In this line of code:

::write(fd, '\0', GPT_PARTITION_TABLE_SIZE);

the second argument to write is a const void *. What is happening is the char NUL ('\0') value is a constant 0 and thus equivalent to NULL, or converted to the nullptr value. the write call then tries to read GPT_PARTITION_TABLE_SIZE bytes starting at that address. On typical systems the address for NULL is literally 0 and usually tehre is no page mapped there and it causes an exception. Inside an operating system kernel or in some embedded systems, there may be memory mapped readable at address 0 and this might write whatever is mapped there.

Compare to the code example:

char buffer[GPT_PARTITION_TABLE_SIZE];
memset(buffer, '\0', sizeof(buffer));
write(fd, buffer, sizeof(buffer));
Zalman Stern
  • 3,161
  • 12
  • 18