This is purely a theoretical question, I know that if someone declares a method private, you probably shouldn\'t call it. I managed to call private virtual methods and chang
Well, the obvious way would be to edit the code so that it is no longer private.
If you insist on finding an evil way to do it...well...with some compilers it may work create your own version of the header file where that one method is public
instead of private
. Evil has a nasty way of rebounding on you though (that's why we call it "evil").
It can be called if a public
function returns the address of the private
function, then anyone can use that address to invoke the private function.
Example,
class A
{
void f() { cout << "private function gets called" << endl; }
public:
typedef void (A::*pF)();
pF get() { return &A::f; }
};
int main()
{
A a;
void (A::*pF)() = a.get();
(a.*pF)(); //it invokes the private function!
}
Output:
private function gets called
Demo at ideone : http://www.ideone.com/zkAw3
See my blog post. I'm reposting the code here
template<typename Tag>
struct result {
/* export it ... */
typedef typename Tag::type type;
static type ptr;
};
template<typename Tag>
typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template<typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
Some class with private members
struct A {
private:
void f() {
std::cout << "proof!" << std::endl;
}
};
And how to access them
struct Af { typedef void(A::*type)(); };
template class rob<Af, &A::f>;
int main() {
A a;
(a.*result<Af>::ptr)();
}
Define a similar class that is the same apart from the function being public.
Then typecast an object with the private function to one with the public function, you can then call the public function.
Followup on T.E.D.'s answer: Don't edit the header. Instead create your own private copy of the header and insert some friend
declarations in that bogus copy of the header. In your source, #include
this bogus header rather than the real one. Voila!
Changing private to public might change the weak symbols that result from inlined methods, which in turn might cause the linker to complain. The weak symbols that result from inline methods will have the same signatures with the phony and real headers if all that is done is to add some friend declarations. With those friend declarations you can now do all kinds of evil things with the class such as accessing private data and calling private members.
Addendum
This approach won't work if the header in question uses #pragma once
instead of a #include
guard to ensure the header is idempotent.
If we are speaking of MSVC, I think the simplest way with no other harm than the fact of calling a private method itself is the great __asm:
class A
{
private:
void TestA () {};
};
A a;
__asm
{
// MSVC assumes (this) to be in the ecx.
// We cannot use mov since (a) is located on the stack
// (i.e. [ebp + ...] or [esp - ...])
lea ecx, [a]
call A::TestA
}