Skip to content

Instantly share code, notes, and snippets.

@guomaimang
Created March 29, 2023 14:27
Show Gist options
  • Save guomaimang/d233d8ab3dbe352038e0e90efbe6851c to your computer and use it in GitHub Desktop.
Save guomaimang/d233d8ab3dbe352038e0e90efbe6851c to your computer and use it in GitHub Desktop.
[03/15/23]seed@VM:~$ sample
Student name: david
Student number: 1179762
Student name: alexander
Student number: 1234568

The stacks of X86 and ARM grow towards lower addresses. The stack analysis is as below.

+ ......         +
+----------------+  
+ main()         +
+----------------+          
+ ......         + 
+----------------+ <-- Stack Top: Lower Address
+ bRec.sNumber   +
+----------------+
+ bRec.name      +
+----------------+   
+ aRec.sNumber   +
+----------------+
+ aRec.name      +
+----------------+ <-- Bottom of the stack: Higher Adderss
+ ......         +

if If only concerned with member variables, then

+----------------+ <-- Stack Top: Lower Address
+ bRec.sNumber[0]+
+----------------+
+ bRec.sNumber[1]+
+----------------+
+ bRec.sNumber[2]+
+----------------+
+ bRec.sNumber[3]+
+----------------+
+ bRec.name[0]   +
+----------------+   
+ bRec.name[1]   +
+----------------+  
+ bRec.name[2]   +
+----------------+  
+ bRec.name[3]   +
+----------------+  
+ bRec.name[4]   +
+----------------+  
+ bRec.name[5]   +
+----------------+  
+ bRec.name[6]   +
+----------------+  
+ bRec.name[7]   + <-- Stack overflow
+----------------+  
+ aRec.sNumber[0]+ 
+----------------+
+ aRec.sNumber[1]+
+----------------+
+ aRec.sNumber[2]+
+----------------+
+ aRec.sNumber[3]+
+----------------+
+ aRec.name[0]   +
+----------------+   
+ aRec.name[1]   +
+----------------+  
+ aRec.name[2]   +
+----------------+  
+ aRec.name[3]   +
+----------------+  
+ aRec.name[4]   +
+----------------+  
+ aRec.name[5]   +
+----------------+  
+ aRec.name[6]   +
+----------------+  
+ aRec.name[7]   +
+----------------+ <-- Bottom of the stack: Higher Adderss

Note that both the diagram above does not show the padding.

Obviously, the length of alexander exceeds 8, it will occupy the extra bytes of a Rec.sNumber.

Validation with GDB

I will analyze in detail why this phenomenon occurs.

seed@VM:~$ g++ -g -fno-stack-protector -o sample sample.cpp
seed@VM:~$ gdb sample

gdb-peda$ break 16  # Pause after strcpy and before output
gdb-peda$ run      

The outcome is as below

1678956794640.png

Viewing stack pointers and values:

gdb-peda$ print &aRec.sNumber
$1 = (int *) 0xbffff354

gdb-peda$ print &aRec.name
$2 = (char (*)[8]) 0xbffff358

gdb-peda$ print &bRec.sNumber
$3 = (int *) 0xbffff348

gdb-peda$ print &bRec.sNumber
$4 = (int *) 0xbffff348

gdb-peda$ print &bRec.name
$5 = (char (*)[8]) 0xbffff34c

gdb-peda$ print &aRec
$6 = (Student *) 0xbffff354

gdb-peda$ print &bRec
$7 = (Student *) 0xbffff348

Next, check the bRec.name

1678957222740.png

  • Original sequence -> Reverse order:0x0 0x12 0x0 0x72
  • 00000000 00010010 00000000 01110010 (2) -> 1179762 (10)

Therefore 1179762 is shown.

#include <iostream>
#include <cstring>
using namespace std;
struct Student {
int sNumber;
char name[8];
};
int main() {
Student aRec, bRec; aRec.sNumber = 1234567; strcpy(aRec.name, "david");
bRec.sNumber = 1234568;
strcpy(bRec.name, "alexander"); // Illegel access of memory space
cout << "Student name: " << aRec.name << endl;
cout << "Student number: " << aRec.sNumber << endl;
cout << "Student name: " << bRec.name << endl;
cout << "Student number: " << bRec.sNumber << endl;
}

copy the source code to the Linux image and compile it

$ g++ -fno-stack-protector -o sample sample.cpp

Run the program. Explain why the variable, aRec.sNumber, has a value that you observe in the Terminal output. Your explanation should provide details about the arrangement and organization of data in the memory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment