CL 20: Stack Frames (15 pts)

What You Need for This Project

Purpose

To examine memory usage by C programs at the assembly level, including:

Installing

You probably already did this in a previous project, but if you did not, on your Debian Linux machine, in a Terminal window, execute these commands:
sudo apt update
sudo apt install build-essential gcc-multilib gdb -y

Creating the Stack Program

In a Terminal window, execute this command:
nano stack.c
Copy and paste in this code, as shown below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int short_name(char * name) {
   char name3[10];

   unsigned long esp, ebp;
   __asm__ volatile("mov %%esp, %0" : "=r" (esp));
   __asm__ volatile("mov %%ebp, %0" : "=r" (ebp));

   strcpy(name3, name);

   printf("\n*** In short_name() ***\n");
   printf("esp: 0x%lx\n", esp);
   printf("ebp: 0x%lx\n", ebp);
   printf("name3 is stored at %p\n", name3);
   printf("name3: %s\n", name3);
   return 0;
}

int add_salutation(char * name) {
   char name2[30];

   unsigned long esp, ebp;
   __asm__ volatile("mov %%esp, %0" : "=r" (esp));
   __asm__ volatile("mov %%ebp, %0" : "=r" (ebp));

   strcpy(name2, "The Honorable ");
   strcat(name2, name);

   printf("\n*** In add_salutation() ***\n");
   printf("esp: 0x%lx\n", esp);
   printf("ebp: 0x%lx\n", ebp);
   printf("name2 is stored at %p\n", name2);
   printf("name2: %s\n", name2);

   short_name(name);
   return 0;
}

int main(void) {
   char name[100];

   unsigned long esp, ebp;
   __asm__ volatile("mov %%esp, %0" : "=r" (esp));
   __asm__ volatile("mov %%ebp, %0" : "=r" (ebp));

   printf("What is your name?\n");
   scanf("%s", name);

   printf("\n*** In main() ***\n");
   printf("esp: 0x%lx\n", esp);
   printf("ebp: 0x%lx\n", ebp);
   printf("name is stored at %p\n", name);
   printf("Hello, %s!\n", name);

   add_salutation(name);
}

Save the file with Ctrl+X, Y, Enter.

Execute this command to compile the program:

gcc -fno-stack-protector -g -m32 -o stack stack.c
Note these switches:
-fno-stack-protector  Does not prevent buffer overflows in the compiled code
-gGenerate debugging information
-m32Compile for a 32-bit processor

Running the Program

Execute this command to run the program:
./stack
Enter the name FRED and press Enter.

The program runs normally, as shown below.

Notice these features:

Observing Buffer Overflows

Run the program again, but enter this name:
Charles_Philip_Arthur_George_Mountbatten-Windsor
The program crashes in the add_salutation() function, with a "Segmentation fault" message, as shown below.

Run the program again, but enter this name:

MY-NAME-IS-RUMPLESTILTSKIN
The program proceeds through the add_salutation() function, and crashes in the short_name() function, as shown below.

Debugging the Program

Execute these commands to debug and run the program:
gdb -q stack
run
FRED
The program runs normally and exits, as shown below.

Viewing the Stack Frame of the main() Function

In gdb, execute this command to see the source code:
list 42,59
You see the C source code for the main() function, as shown below.

Execute the commands below:

break 58
run
AAAA
info registers
Those commands performed these actions: Note the esp and ebp values, as highlighted in the image shown below.

They match the values printed out by the C program, outlined in blue in the image below.

To see the stack frame, execute the command below:

x/32x $esp
The stack frame starts at the 32-bit word beginning at $esp and ends at the 32-bit word at $ebp. It's highlighted in the image below.

Notice that the name you entered, AAAA, appears in the stack frame, as its hexadecimal encoding, 41414141, outlined in red in the image below.

Viewing the Stack Frame of the add_salutation() Function

In gdb, execute this command to see the source code:
list 22,40
You see the C source code for the add_salutation() function, as shown below.

Execute the commands below:

delete
y
break 38
run
y
AAAA
info registers
Those commands performed these actions: Note the esp and ebp values, as highlighted in the image shown below.

They match the values printed out by the C program for the add_salutation() function, outlined in blue in the image below.

To see the stack frame, execute the command below:

x/16x $esp
The stack frame starts at the 32-bit word beginning at $esp and ends at the 32-bit word at $ebp. It's highlighted in the image below.

Notice that the name you entered, AAAA, appears in the stack frame, as its hexadecimal encoding, 41414141, outlined in red in the image below.

Also notice the word after the end of the stack frame, just after $ebp, outlined in blue in the image below. This is the return pointer -- the address to resume execution at when the function returns.

Viewing the Stack Frame of the short_name() Function

In gdb, execute this command to see the source code:
list 5,20
You see the C source code for the short_name() function, as shown below.

Execute the commands below:

delete
y
break 19
run
y
AAAA
info registers
Those commands performed these actions: Note the esp and ebp values, as highlighted in the image shown below.

They match the values printed out by the C program, outlined in blue in the image below.

To see the stack frame, execute the command below:

x/12x $esp
The stack frame starts at the 32-bit word beginning at $esp and ends at the 32-bit word at $ebp. It's highlighted in the image below.

Notice that the name you entered, AAAA, appears in the stack frame, as its hexadecimal encoding, 41414141, outlined in red in the image below. It's in two adjacent words.

Also notice the word after the end of the stack frame, just after $ebp, outlined in blue in the image below. This is the return pointer -- the address to resume execution at when the function returns.

CL 20.1: Return Value (15 pts)

Execute the commands below:
run
y
AAAABBBBCCCCDDDDEEEEFFFFGGGGHHHHIIII
info registers
x/12x $esp
The flag is covered by a green rectangle in the image below.

Posted 1-11-25