How to skip C++ access modifiers – not real code security

No comments -

C++ is not a pure object oriented programming language (this topic is just another argument) but it is implementing OOP concepts. On of these concepts is encapsulation: the object hides its contents (attributes or instance variables) by making them private / protected and gives access to them through public methods (like getters and setters).

The solution to implement encapsulation is to declare all the attributes using private access modifier. In this way , you can’t access them from outside the class, like in this example:

#include
#include
using namespace std;
 
class BankAccount
{
private:
	char name[16];
	char *IBAN;
	double balance;
public:
	BankAccount()
	{
		strcpy(name,"My name");
		IBAN = new char[5];
		strcpy(IBAN,"9999");
		balance = 100;
	}
	double getBalance()
	{
		return this -> balance;
	}
};
 
//global method
void main()
{
	BankAccount ba;
	cout<<ba.name;		//COMPILER ERROR
}

In the previous example, if you try to access the name attribute you will get a compiler error:

‘BankAccount::name’ : cannot access private member declared in class ‘BankAccount’

which is very explicit.

But, things are not so safe as they appear. If you know that:

  • pointers are very powerfull in C and C++ because you can achieve control over memory;
  • there is an arithmetic of pointers;
  • any pointer, despite its type, is just a numeric variables used to store addresses (all addresses are the same on a particular arhitecture);
  • compilers may implements optimization techniques like cache optimization (data is aligned in memory at addresses divisible with 8, 16, or 32).

then you can do something like this:

char* baPointer = (char*)&ba;
cout << baPointer << endl;
 
//keep in mind the padding for the cache optimization done by the compiler
char** IBANPointer = (char**)(baPointer+16);	
cout << (*IBANPointer) << endl;
 
//in this case the compiler arrange all variables at addresses mutiple of 8
double * balancePointer = (double*)(baPointer+24);
cout<<*balancePointer << endl;
 
//modify the private attribute value
*balancePointer = 900;
cout << ba.getBalance() << endl;

running the previous statements, you get these prints

My name
9999
100
900
Press any key to continue . . .

which prove that you can access C++ private attributes and even modify them. In short, what we have done:

  1. get the address of the object in a char * pointer; because a char is 1 byte the pointer arithmetic is simpler;
  2. prints the name because it is the first field and also is terminated with string end delimiter – ‘\0′;
  3. get the address of the IBAN field in a char ** pointer; the IBAN value is in Heap; take into consideration that the compiler may implement cache optimization techniques; on my compiler, MS VS2010 C++, it uses 8 byte alignment; anyway, the name has 16 bytes, so no padding;
  4. print the IBAN;
  5. get over the pointer value and get the address of the balance
  6. print the value or modify it.

So, in C++ access modifiers are not a real safe mechanism used to secure your code. The other conclusion is that pointers is a very powerful tool for someone who really understands them.

In real OOP languages like Java or C# you can’t do this because you have the virtual machine which is watching over your code.

, ,


  1. No comments yet.
(will not be published)

  1. No trackbacks yet.