Skip to main content
gamedev.net
🔒 Locked

Hacking C++ question

Started by stew Aug 5, 2003 at 10:45 PM 15 replies 2.5k views
Original Post
stew
stew
Hi all, I had a lecture once where we were shown how to access the private (well any) members of a class, change all its vtable etc. without touching the class source code. Trouble is I can''t remember how it was done. He also showed how to turn a singleton into a multiton and back again without touching the singleton objects source. All of it was perfectly legal C++. Anyone have any ideas on how this is done? I know there is no valid reason why you would want to do it but it just interested me. I''m a C++ programmer and I love finding out all the flaws in the C++ design. Thanks
SpaceRogue
SpaceRogue
You can do pretty much anything with pointer manipulation.

Two points:

1) C++ isn''t supposed to offer protection against people deliberately doing this so it isn''t really a ''flaw''. C++ access mechanisms are merely to prevent accidental manipulation of data.

2) It depends on what you define as ''legal''. Things like this that work on one implementation may not work on another, for example: Different C++ implementations may place the vtable in different locations. It may be ''legal'' as in it compiles and runs (on a certain platform, with a certain compiler) but it wouldn''t be considered ''good'' or portable code.
Extrarius
Extrarius
Just do something like
#define private public
#define protected public
#include "class.h"
#undef protected
#undef private
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Leadorn
Leadorn

#include <iostream>
using namespace std;

class s
{
public:
s()
{h = 123456;}
private:
int l;
int h;

};


int main()
{



s cla;
int *j = ((int *)&cla)+1;
cout << *j << endl;

*j = 0;


return 0;
}



Why is this a flaw?
Remember that all the keywords like const private protected are there to help you avoid unnecessary bugs.
daerid
daerid
I fail to see why these are problems.
The only way this could be a problem is if you''re dealing with a programmer with sub-par intelligence.
daerid@gmail.com
Trienco
Trienco
quote:
Original post by Extrarius
Just do something like
#define private public
#define protected public
#include "class.h"
#undef protected
#undef private



two things come to mind:
-"without touching the class source code"
youre doing exactly that, no matter if you do it directly or indirectly

-try to access bla with your trick:
class X {
int bla;
public:
...
}

f@dzhttp://festini.device-zero.de
Extrarius
Extrarius
Its not editing the source files, which is what I took it to mean, and I very rarely see classes that don't explicitly use plublic/private/protected. If you're going to say its editing the source, then the only other option(afaik) is pointer manipulation which varies depending on compiler (or at least, the order in which the member variables are stored in ram, any alignment settings in place, where the virtual table is and how large it is, and probably a few other things as well)

[edited by - Extrarius on August 6, 2003 11:19:51 AM]
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk
Sneftel
Sneftel
quote:
Original post by Extrarius
Its not editing the source files, which is what I took it to mean, and I very rarely see classes that don''t explicitly use plublic/private/protected.


Your code is, however, illegal. The C++ standard explicitly forbids built-in keywords from being #defined.

Here''s a sneaky way that is legal C++, works on all compliant compilers, and doesn''t assume anything about memory layout (which is non-portable):

suppose you have this class:

class C
{
public:
template<typename T> void Func(T arg) { ... }
private:
int cantTouchThis;
};

Then your own code can evilly exploit explicit template instantiation as shown:

class Dummy {};

template<> void Func<Dummy>(Dummy arg)
{
cantTouchThis = 12345;
}

And then just call Func with a Dummy argument to run the code as a priveleged function.


How appropriate. You fight like a cow.
AsciiFish
AsciiFish
quote:
Original post by daerid
I fail to see why these are problems.
The only way this could be a problem is if you''re dealing with a programmer with sub-par intelligence.


As a programmer, I am always dealing with sub-par intelligence

/*Joe DiMichele
C/C++/VB Programmer, A+ Certified Technician
AIM:Krawling Khaos, ICQ:332871787
joedimichele@hotmail.com
oderint dum metuant
Excuse my spelling, programmers can''t spel*/
/Joe DiMichele C/C++/VB Programmer, A+ Certified Technician AIM:Krawling Khaos, ICQ:332871787 joedimichele@hotmail.com oderint dum metuantExcuse my spelling, programmers can't spel/
antareus
antareus
Actually I don''t think anyone has touched on how was presented.

Suppose you have the following declaration:

// looks pretty secure at a glance

class Safe
{
public:
void Store(int amount) { this->money += amount; }

private:
int money;
};


Now, Safe doesn''t provide a way to take money out of the Safe, or so you think. Whats important here is that DecoySafe has the exact same layout in memory that Safe does, just with the restrictions relaxed.

class DecoySafe
{
public:
void Store(int amount);

public: //note public

int money;
};

Now we''re just a pointer conversion away from getting into anyone''s safe:

Safe* lockbox = new Safe;
lockbox->Store(500);

DecoySafe* decoy = reinterpret_cast<DecoySafe*>(lockbox);
int ransom = decoy->money;
decoy->money -= ransom;


Undoubtably this falls into the realm of undefined behavior (reinterpret_cast being your first clue), however I''ve heard its been used when needing to extend 3rd party source only libraries.
--God has paid us the intolerable compliment of loving us, in the deepest, most tragic, most inexorable sense.- C.S. Lewis
Fredrik Dahlberg
Fredrik Dahlberg
The access-levels are more or less just compiler hints in C++. If you want "private" private access use java or something.
sSimontis
sSimontis
I just use protected and friend. Hacking can be done, bnut there are legal requirements.

Scott Simontis
Big Joke: C#
Scott SimontisMy political blog
stew
stew
Hi all,

Thanks for the replies. When I said flaws I really meant idiosyncrasies, I know C++ isn''t designed to make it impossible to do these things. I just mean the little things you can do to trick the compiler.

Catch ya,
Stew
Shannon Barber
Shannon Barber
quote:
Original post by Trienco
-try to access bla with your trick:
class X {
int bla;
public:
...
}




#define class struct

Voila (as mentioned, you''re not suppose to be able to do this, but it works on most compilers).
The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Trienco
Trienco
quote:
Original post by Magmai Kai Holmlor
#define class struct

Voila (as mentioned, you''re not suppose to be able to do this, but it works on most compilers).



*lol* damn.. can i get out of this by saying thats it not exactly the same trick? ,-)

f@dzhttp://festini.device-zero.de
JohnBolton
JohnBolton
quote:
Original post by stew
I had a lecture once where we were shown how to access the private (well any) members of a class, change all its vtable etc. without touching the class source code. Trouble is I can''t remember how it was done. ...


I think forgetting how it is done is a good thing. At some point you wisely decided that it is a bad idea and there is absolutely no reason to allocate space in your brain for that kind of useless crap. And furthermore, I can''t imagine what kind of instructor would lecture about it, unless he was trying to impress some girls or something. haha
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.