Date: December 3, 2024

Self-destructing program

In words of Linus Torvalds himself, Today I tried "doing something
incredibly stupid". I suppose every programmer has, someday, thought
of writing a self-destructing or self-modifying program. Today, was my day.
I was well-packed, equipped with the following program:


#include <stdio.h>
#include <stdint.h>

struct blob {
  uint32_t x;
  uint32_t y;
} blob = {
  0x000d8f3,
  0x081f7721,
};

void modify_bin (char *file);

int main (int   argc,
          char *argv[])
{
  modify_bin (argv[0]);

  printf ("%u\n", blob.y);
  return 0;
}

#define BITS_IN_BYTE    8
#define UINT32_SIZE     32
#define ELF_HEADER_SIZE 64

void modify_bin (char *file)
{
  char buf[UINT32_SIZE / BITS_IN_BYTE];
  FILE *fptr = fopen (file, "w+");

  /* skip ELF header */
  fseek (fptr, ELF_HEADER_SIZE, SEEK_SET);

  while (fread (buf, sizeof (unsigned char), sizeof (buf), fptr) > 0)
    {
      uint32_t num = *(uint32_t *) buf;

      if (num == blob.y)
        {
          fseek (fptr, - sizeof (buf), SEEK_CUR);
          num += 1;
          fwrite ((unsigned char *) &num,
                  sizeof (unsigned char), sizeof(buf), fptr);
          break;
        }
    }

  fclose (fptr);
}


Wait, the program is crashing?

> starts gdb'ing
> Looks inside errno
> ETXTBSY

Guess what, you're not allowed to modify a executable while it's executing :(
There's a whole article on ETXTBSY's history at lwn.net.
Good read!

Edit:
By "destructing" here, I mean corrupting the original program and not remove()ing it.
There's a huge difference between modifying a in-memory executable code and removing a
executable file from filesystem.