[You may only do this practice on Linux..Coz windows behaves weirdly allocating memory for stack variables~ ]
This practice is made by Parthas Menethil(Luke.J.Sun). All rights reserved.
C++ is such a flexible language to have fun. You can break the common rule an do fantastic things. In this post, I am going to work with you to hack private information out from classes using only pointers!
I have three classes declared and instantiated one instance of each class in main. Some of the values inside the class are inaccessible by normal methods. We are going to pull them out from the memory.
NOTE: This program should be complied targeting 32bit operating system. The preferred compiler would be GCC 4.6.3
/* How to access values in a class abnormally
*
* */
#include <iostream>
using namespace std; // Not a good habit, just for testing
class A{
private:
int apples;
double weight;
unsigned int bugs;
public:
A() : apples(100), weight(99.9989), bugs(123456){}
};
class B{
private:
double exam_grade;
protected:
double test_grade;
public:
double quiz_grade;
B(double exam, double test, double quiz){
exam_grade = exam;
test_grade = test;
quiz_grade = quiz;
}
virtual void placeholder(){ /* Nothing to show */ }
};
struct Date{
private:
int day;
int month;
int year;
public:
Date(int d, int m, int y){
day = d;
month = m;
year = y;
}
};
class C : public B{
protected:
Date *d;
public:
C() : B(55, 50, 60.9){
d = new Date(20, 9, 1993);
}
~C(){
delete d;
}
};
int main(){
A a;
B b(99,98,97);
C c;
cout<<"C++ is flexible!"<<endl<<endl;
cout<<"Example done by Parthas Menethil(Luke.J.Sun)"<<endl<<endl;
cout<<"Size of class A: "<<sizeof(a)<<endl;
cout<<"->int(4) + double(8) + uint(4) = 16"<<endl;
cout<<"Size of class B: "<<sizeof(b)<<endl;
cout<<"->virtual table pointer(4) + double(8) * 3 = 28"<<endl<<endl;
cout<<"Now let's retrieve everything from memory..."<<endl;
/* Instance a */
cout<<"In instance a:"<<endl;
// Take stuffs from the beginning pointer
cout<<"[Private]apples:"<<*(int*)(&a)<<endl;
// Change the pointer to a char pointer so offset would moved by 1 per increasement, use sizeof to count the size of variable type
cout<<"[Private]weight:"<<*(double*)((char*)(&a) + sizeof(int))<<endl;
cout<<"[Private]bugs:"<<*(unsigned int*)((char*)(&a) + sizeof(int) + sizeof(double))<<endl<<endl;
/* Instance b */
cout<<"Ininstance b:"<<endl;
// Pass the initial virtual table pointer
cout<<"[Private]exam_grade:"<<*(double*)((char*)&b + 4)<<endl;
// Move forward to pass the first double and retrieve the second one
cout<<"[Protected]test_grade:"<<*(double*)((char*)&b + 4 + sizeof(double))<<endl;
// Move forward to pass the second double and retrive the third one
// The use of sizeof is not necessary because sometimes we know the variable type length
// double has the length of 8
cout<<"[Public]quiz_grade:"<<*(double*)((char*)&b + 4 + sizeof(double) + 8)<<endl<<endl;
/* Let's try to retrieve the values in the Date object in C class */
/* Instance c */
cout<<"Instance c:"<<endl;
cout<<"[Protected]d->day:"<<"[Your answer?]"<<endl;
cout<<"[Protected]d->month:"<<"[Your answer?]"<<endl;
cout<<"[Protected]d->year:"<<"[Your answer?]"<<endl;
return 0;
}
At the beginning, I counted and explained the sizes as well as structures of class A and B, and then retrieved all values from A and B using only pointers.
To get the variables’ values from class C is tricky, you can try to do it by yourself! I believe that you can find the right answers out!
My solution will be released in the next post about this topic. Before that, try it out!
The right output should be:
C++ is flexible!
Example done by Parthas Menethil(Luke.J.Sun)
Size of class A: 16
->int(4) + double(8) + uint(4) = 16
Size of class B: 28
->virtual table pointer(4) + double(8) * 3 = 28
Now let’s retrive everything from memory…
In instance a:
[Private]apples:100
[Private]weight:99.9989
[Private]bugs:123456
Ininstance b:
[Private]exam_grade:99
[Protected]test_grade:98
[Public]quiz_grade:97
Instance c:
[Protected]d->day:20
[Protected]d->month:9
[Protected]d->year:1993
Try to match my output. There could be many ways to do the samething in c++.