aboutsummaryrefslogtreecommitdiffstats
path: root/src/examples/overflow.c
blob: 4673d32978d096840eaa0324b43461efae4b8a8d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/* klaar@ida
  
   noopsled | pintos --fs-disk=2 -v -k -p ../examples/overflow -a overflow -p ../examples/crack -a crack -- -f -q run overflow
  
   This program is possible to crack with carefully crafted input.
   It examplifies the danger of buffer overflow.
*/

#include <syscall.h>
#include <stdio.h>
#include <string.h>

static void stringcopy(char* dst, const char* src)
{
  while (*src)
    *dst++ = *src++;
  *dst = '\0';
}

int main(void);

/* A messy not very good buffer overflow example. A little bit too
 * contrieved. */
static int getline (char* destination)
{
  char line[200];
  int i = 0;
  char* dst = destination;

//#define DEBUG_CODE
#ifdef DEBUG_CODE
  int r, c;
  unsigned* ret = (unsigned*)(&dst - 1);

  printf ("Return address address: 0x%08x\n", (unsigned)&ret);
  printf ("Return address content: 0x%08x\n", *ret);
  printf ("Main function address : 0x%08x\n", (unsigned)main);
  printf ("Line buffer address   : 0x%08x\n", (unsigned)line);
#endif
  
  do /* !!! Buffer overflow when i >= 200 !!! */
  {
    if ( read (STDIN_FILENO, &line[i], 1) != 1)
      break; /* failed to read requested number of characters */
  }
  while ( line[i++] != '\n' );
  
  line[i-1] = '\0';
  
#ifdef DEBUG_CODE
  /* hex dump of read data */
  for (r = 0; r < 16; ++r)
  {
    printf ("0x%08x: ", (unsigned)&line[ 16*r ]);
    for (c = 0; c < 16; ++c)
    {
      int code = line[ 16*r + c ] & 0xff;
      printf("\\x%02x", code);
    }
    printf("\n");
  }
        
  printf ("Return address content: 0x%08x\n", *ret);
#endif

  stringcopy(dst, line);

  return ( strlen(line) > 1 );
}

/* Stupid program to echo every line you write to screen. And to make
 * matter worse, getline have a serious buffer overflow. */
int main (void)
{
  char msg[2000];
  char quote = '"';
  char endl = '\n';
  
  while ( getline (msg) )
  {
    write (STDOUT_FILENO, &quote, 1);
    write (STDOUT_FILENO, msg, strlen(msg));
    write (STDOUT_FILENO, &quote, 1);
    write (STDOUT_FILENO, &endl, 1);
  }
  
  return 0;
}