🏳️
The CTF Recipes
  • Introduction
  • Cryptography
    • Introduction
    • General knowledge
      • Encoding
        • Character encoding
          • ASCII
          • Unicode
          • UTF-8
        • Data encoding
          • Base16
          • Base32
          • Base64
      • Maths
        • Modular arithmetic
          • Greatest Common Divisor
          • Fermat's little theorem
          • Quadratic residues
          • Tonelli-Shanks
          • Chinese Remainder Theorem
          • Modular binomial
      • Padding
        • PKCS#7
    • Misc
      • XOR
    • Mono-alphabetic substitution
      • Index of coincidence
      • frequency analysis
      • Well known algorithms
        • 🔴Scytale
        • 🔴ROT
        • 🔴Polybe
        • 🔴Vigenere
        • 🔴Pigpen cipher
        • 🔴Affine cipher
    • Symmetric Cryptography
      • AES
        • Block Encryption procedure
          • Byte Substitution
          • Shift Row
          • Mix Column
          • Add Key
          • Key Expansion / Key Schedule
        • Mode of Operation
          • ECB
            • Block shuffling
              • Challenge example
            • ECB Oracle
              • Challenge example
          • CBC
            • Bit flipping
              • Challenge example
            • Padding oracle
              • Challenge example
          • OFB
            • Key stream reconstruction
            • Encrypt to Uncrypt
  • 🛠️Pwn
    • General knowledge
      • STACK
        • Variables storage
        • Stack frame
      • PLT and GOT
      • HEAP
        • HEAP operations
        • Chunk
        • Bins
        • Chunk allocation and reallocation
      • Syscall
    • Architectures
      • aarch32
        • Registers
        • Instruction set
        • Calling convention
      • aarch64
        • Registers
        • Instruction set
        • Calling convention
      • mips32
        • Registers
        • Instruction set
        • Calling convention
      • mips64
        • Registers
        • Instruction set
        • Calling convention
      • x86 / x64
        • Registers
        • Instruction set
        • Calling convention
    • Stack exploitation
      • Stack Buffer Overflow
        • Dangerous functions
          • gets
          • memcpy
          • sprintf
          • strcat
          • strcpy
        • Basics
          • Challenge example
        • Instruction pointer Overwrite
          • Challenge example
        • De Bruijn Sequences
        • Stack reading
          • Challenge example
      • Format string
        • Dangerous functions
          • printf
          • fprintf
        • Placeholder
        • Data Leak
          • Challenge example
        • Data modification
          • Challenge example
      • Arbitrary code execution
        • Shellcode
        • ret2reg
        • Code reuse attack
          • Ret2plt
          • Ret2dlresolve
          • GOT Overwrite
          • Ret2LibC
          • Leaking LibC
          • Ret2csu
          • Return Oriented Programming - ROP
          • Sigreturn Oriented Programming - SROP
          • Blind Return Oriented Programming - BROP
            • Challenge example
          • 🔴Call Oriented Programming - COP
          • 🔴Jump Oriented Programming - JOP
          • One gadget
        • Stack pivoting
    • 🛠️Heap exploitation
      • Heap overflow
        • Challenge example
      • Use after free
        • Challenge example
      • 🛠️Double free
      • 🔴Unlink exploit
    • Protections
      • Stack Canaries
      • No eXecute
      • PIE
      • ASLR
      • RELRO
    • Integer overflow
Powered by GitBook
On this page
  • Simple explanation
  • Code example
  • Stack representation
  1. Pwn
  2. General knowledge
  3. STACK

Variables storage

Simple explanation

When a variable is declared, the process will reserve a certain amount of memory on the stack to store the value of the variable. The process will allocate enough memory to hold the entire possible value. For example, if you declare a string with size 20, the process will allocate 20 bytes of memory on the stack for that string.

If no value is initialized, the initial value of the variable will be undefined. This means that it may have any value, and that value may be different each time the program is executed.

When a value is assigned to a variable, the compiler will store that value at the memory address associated with the variable.

Therefore, it is generally not recommended to rely on the initial value of a variable if it has not been explicitly initialized. This can lead to unpredictable behavior.

It is generally best practice to initialize variables to known values when they are declared.

Code example

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

int main(void) {
  char string1[16]; // create an array of characters with size 16
  char string2[16]; // create a second array of characters with size 16

  printf("string1 stack address : %p\n", string1);
  printf("string2 stack address : %p\n", string2);

  printf("%s\n", string1);
  printf("%s\n", string2);

  // fill the first string with 15 'A's followed by a null character '\0'
  memset(string1, 'A', 15);
  string1[15] = '\0';

  // fill the second string with 15 'B's followed by a null character '\0'
  memset(string2, 'B', 15);
  string2[15] = '\0';

  printf("String 1: %s\n", string1); // print string 1
  printf("String 2: %s\n", string2); // print string 2

  return 0;
}

This code will declare two arrays of characters, string1 and string2, and set them with the strings "AAAAAAAAAAAAAAA" and "BBBBBBBBBBBBBBB", respectively.

The output of this program would be :

string1 stack address : 0xfff7da80
string2 stack address : 0xfff7da70

�C��
String 1: AAAAAAAAAAAAAAA
String 2: BBBBBBBBBBBBBBB

This code provides a basic example of how variables are treated on the stack in C.

Stack representation

When the string1 variable is declared, the process reserve 16 byte onto the stack to store this variable :

  address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------- string1 --------------------------+
0xffffd280: |   | 0x01	0x00	0x00	0x00	0x54	0xd3	0xff	0xff |
0xffffd288: |   | 0x5c	0xd3	0xff	0xff	0xad	0x62	0x55	0x56 |
            |   +------------------------------------------------------------+
0xffffd290: |    0xb0	0xd2	0xff	0xff	0x00	0x00	0x00	0x00
0xffffd298: |    0x00	0x00	0x00	0x00	0x46	0xce	0xdd	0xf7
  ...       |    ...

Note that values on the stack aren't initialized to any specific value. If there is already some data in the memory space allocated to the variable, this data will remain until it is overwritten by a new value.

When the string2 variable is declared, the process reserve 16 byte onto the stack to store this variable

  address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------- string2 --------------------------+
0xffffd270: |   | 0xfc	0x73	0xfa	0xf7	0x01	0x00	0x00	0x00 |
0xffffd278: |   | 0x00	0x90	0x55	0x56	0xdb	0x62	0x55	0x56 |
            |   +------------------------------------------------------------+
            |   +------------------------- string1 --------------------------+
0xffffd280: |   | 0x01	0x00	0x00	0x00	0x54	0xd3	0xff	0xff |
0xffffd288: |   | 0x5c	0xd3	0xff	0xff	0xad	0x62	0x55	0x56 |
            |   +------------------------------------------------------------+
0xffffd290: |    0xb0	0xd2	0xff	0xff	0x00	0x00	0x00	0x00
0xffffd298: |    0x00	0x00	0x00	0x00	0x46	0xce	0xdd	0xf7
  ...       |    ...

The variable string2 is stored above the string1 variable due to LIFO system

Then, the process will do a memset() to each variable to set "A" and "B" 15 times respectively into string1 and string2 and then put a null byte 0x00 at the end of the string

  address   |   values
------------+-------------------------------------------------------------------
            |   +------------------------- string2 --------------------------+
0xffffd270: |   | 0x42	0x42	0x42	0x42	0x42	0x42	0x42	0x42 |
0xffffd278: |   | 0x42	0x42	0x42	0x42	0x42	0x42	0x42	0x00 |
            |   +------------------------------------------------------------+
            |   +------------------------- string1 --------------------------+
0xffffd280: |   | 0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x41 |
0xffffd288: |   | 0x41	0x41	0x41	0x41	0x41	0x41	0x41	0x00 |
            |   +------------------------------------------------------------+
0xffffd290: |    0xb0	0xd2	0xff	0xff	0x00	0x00	0x00	0x00
0xffffd298: |    0x00	0x00	0x00	0x00	0x46	0xce	0xdd	0xf7
  ...       |    ...

string1 contains 15 0x41 wich is the hex value of A following by a null byte 0x00

string2 contains 15 0x42 wich is the hex value of B following by a null byte 0x00

PreviousSTACKNextStack frame

Last updated 7 months ago

🛠️