¿Puedo acceder a miembros privados desde fuera de la clase sin usar amigos?


Descargo de responsabilidad

Sí, soy plenamente consciente de que lo que estoy preguntando es totalmente estúpido y que cualquiera que desee probar tal cosa en el código de producción debe ser despedido y/o disparado. Principalmente estoy buscando ver si se puede hacer.

Ahora que eso está fuera del camino, ¿hay alguna manera de acceder a los miembros de la clase privada en C++ desde fuera de la clase? Por ejemplo, ¿hay alguna manera de hacer esto con desplazamientos de puntero?

(Ingenuo y no preparado para la producción técnicas bienvenidas)

Actualizar

Como se señaló en los comentarios, hice esta pregunta porque quería escribir una entrada de blog sobre la sobre-encapsulación (y cómo afecta al TDD). Quería ver si había una manera de decir "usar variables privadas no es una forma 100% confiable de hacer cumplir la encapsulación, incluso en C++."Al final, decidí centrarme más en cómo resolver el problema en lugar de por qué es un problema, por lo que no destacé algunas de las cosas traídas aquí tan prominentemente como lo había hecho planeado, pero aún así dejé un enlace.

En cualquier caso, si alguien está interesado en cómo salió, aquí está: Enemigos del Desarrollo Impulsado por Pruebas parte I: encapsulación (Sugiero leerlo antes de decidir que estoy loco).

Author: Jason Baker, 2009-01-08

24 answers

Si la clase contiene alguna función miembro de la plantilla, puede especializar esa función miembro para satisfacer sus necesidades. Incluso si el desarrollador original no lo pensó.

Seguro.h

class safe
{
    int money;

public:
    safe()
     : money(1000000)
    {
    }

    template <typename T>
    void backdoor()
    {
        // Do some stuff.
    }
};

Main.cpp:

#include <safe.h>
#include <iostream>

class key;

template <>
void safe::backdoor<key>()
{
    // My specialization.
    money -= 100000;
    std::cout << money << "\n";
}

int main()
{
    safe s;
    s.backdoor<key>();
    s.backdoor<key>();
}

Salida:

900000
800000
 65
Author: dalle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 16:43:42

He añadido una entrada a mi blog (ver más abajo) que muestra cómo se puede hacer. Aquí hay un ejemplo de cómo se usa para la siguiente clase

struct A {
private:
  int member;
};

Simplemente declare una estructura para ella donde la describa e instancie la clase de implementación utilizada para robbery

// tag used to access A::member
struct A_member { 
  typedef int A::*type;
  friend type get(A_member);
};

template struct Rob<A_member, &A::member>;

int main() {
  A a;
  a.*get(A_member()) = 42; // write 42 to it
  std::cout << "proof: " << a.*get(A_member()) << std::endl;
}

La plantilla de clase Rob se define así, y solo necesita definirse una vez, independientemente de cuántos miembros privados planee acceder

template<typename Tag, typename Tag::type M>
struct Rob { 
  friend typename Tag::type get(Tag) {
    return M;
  }
};

Sin embargo, esto no muestra que el acceso de c++ las reglas no son confiables. Las reglas de lenguaje están diseñadas para proteger contra errores accidentales-si intenta robar datos de un objeto, el lenguaje por diseño no toma mucho tiempo para prevenirlo.

 47
Author: Johannes Schaub - litb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-14 17:42:32

Lo siguiente es sigiloso, ilegal, dependiente del compilador, y puede no funcionar dependiendo de varios detalles de implementación.

#define private public
#define class struct

Pero es una respuesta a tu OP, en la que invitas explícitamente una técnica que, y cito, es "totalmente estúpida y que cualquiera que desee probar tal cosa en código de producción debe ser despedido y/o disparado".


Otra técnica es acceder a los datos de los miembros privados, mediante la construcción de punteros utilizando compensaciones codificadas/codificadas a mano desde el comienzo del objeto.

 29
Author: ChrisW,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-14 23:26:02

Hmmm, no sé si esto funcionaría, pero podría valer la pena intentarlo. Cree otra clase con el mismo diseño que el objeto con miembros privados pero con privado cambiado a público. Cree una variable de puntero a esta clase. Use un cast simple para apuntar esto a su objeto con miembros privados e intente llamar a una función privada.

Esperar chispas y tal vez un accidente;)

 23
Author: Shane MacLaughlin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 13:04:52
class A 
{ 
   int a; 
}
class B
{
   public: 
   int b;
}

union 
{ 
    A a; 
    B b; 
};

Eso debería bastar.

ETA: Funcionará para este tipo de clase trivial, pero como cosa general no lo hará.

TC++PL Sección C. 8.3: "Una clase con un constructor, destructor, o operación de copia no puede ser el tipo de un miembro de la unión ... porque el compilador no sabría qué miembro destruir."

Así que nos quedamos con la mejor apuesta es declarar class B para que coincida con el diseño de A y hackear para mirar las partes privadas de una clase.

 12
Author: Rob K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-26 10:12:09

Es definitivamente posible acceder a miembros privados con un desplazamiento de puntero en C++. Supongamos que tenía la siguiente definición de tipo a la que quería acceder.

class Bar {
  SomeOtherType _m1;
  int _m2;
};

Asumiendo que no hay métodos virtuales en Bar, el caso fácil es _m1. Los miembros en C++ se almacenan como desplazamientos de la ubicación de memoria del objeto. El primer objeto está en el desplazamiento 0, el segundo objeto en el desplazamiento de sizeof (primer miembro), etc...

Así que aquí hay una forma de acceder a _m1.

SomeOtherType& GetM1(Bar* pBar) {
  return*(reinterpret_cast<SomeOtherType*>(pBar)); 
}

Ahora _m2 es un poco dificultar. Necesitamos mover el puntero original sizeof(SomeOtherType) bytes desde el original. El cast to char es para asegurar que estoy incrementando en un byte offset

int& GetM2(Bar* pBar) {
  char* p = reinterpret_cast<char*>(pBar);
  p += sizeof(SomeOtherType);
  return *(reinterpret_cast<int*>(p));
}
 8
Author: JaredPar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 15:34:39

Si puede obtener un puntero a un miembro de una clase, puede usar el puntero sin importar cuáles sean los especificadores de acceso (métodos pares).

class X;
typedef void (X::*METHOD)(int);

class X
{
    private:
       void test(int) {}
    public:
       METHOD getMethod() { return &X::test;}
};

int main()
{
     X      x;
     METHOD m = x.getMethod();

     X     y;
     (y.*m)(5);
}

Por supuesto, mi pequeño hack favorito es la plantilla de amigo puerta trasera.

class Z
{
    public:
        template<typename X>
        void backDoor(X const& p);
    private:
        int x;
        int y;
};

Asumiendo que el creador de lo anterior ha definido backDoor para sus usos normales. Pero desea acceder al objeto y mirar las variables de miembro privado. Incluso si la clase anterior se ha compilado en una biblioteca estática, puede agregar su propia plantilla especialización para backDoor y así acceder a los miembros.

namespace
{
    // Make this inside an anonymous namespace so
    // that it does not clash with any real types.
    class Y{};
}
// Now do a template specialization for the method.
template<>
void Z::backDoor<Y>(Y const& p)
{
     // I now have access to the private members of Z
}

int main()
{
    Z  z;   // Your object Z

    // Use the Y object to carry the payload into the method.
    z.backDoor(Y());
}
 8
Author: Martin York,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 19:22:16

Buena pregunta por cierto... aquí está mi pieza:

using namespace std;

class Test
{

private:

  int accessInt;
  string accessString;

public:

  Test(int accessInt,string accessString)
  {
    Test::accessInt=accessInt;
    Test::accessString=accessString;
  }
};

int main(int argnum,char **args)
{
  int x;
  string xyz;
  Test obj(1,"Shit... This works!");

  x=((int *)(&obj))[0];
  xyz=((string *)(&obj))[1];

  cout<<x<<endl<<xyz<<endl;
  return 0;
}

Espero que esto ayude.

 4
Author: Sushant Mahajan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-12-20 14:08:08

Esta respuesta se basa en el concepto exacto demostrado por @Johannes's answer/blog, ya que parece ser la única forma "legítima". He convertido ese código de ejemplo en una utilidad práctica. Es fácilmente compatible con C++03 (implementando std::remove_reference y reemplazando nullptr).

Biblioteca

#define CONCATE_(X, Y) X##Y
#define CONCATE(X, Y) CONCATE_(X, Y)

#define ALLOW_ACCESS(CLASS, TYPE, MEMBER) \
  template<typename Only, TYPE CLASS::*Member> \
  struct CONCATE(MEMBER, __LINE__) { friend TYPE (CLASS::*Access(Only*)) { return Member; } }; \
  template<typename> struct Only_##MEMBER; \
  template<> struct Only_##MEMBER<CLASS> { friend TYPE (CLASS::*Access(Only_##MEMBER<CLASS>*)); }; \
  template struct CONCATE(MEMBER, __LINE__)<Only_##MEMBER<CLASS>, &CLASS::MEMBER>

#define ACCESS(OBJECT, MEMBER) \  
(OBJECT).*Access((Only_##MEMBER<std::remove_reference<decltype(OBJECT)>::type>*)nullptr)

API

ALLOW_ACCESS(<class>, <type>, <member>);

Uso

ACCESS(<object>, <member>) = <value>;   // 1
auto& ref = ACCESS(<object>, <member>); // 2

Ejemplo

struct X {
  int get_member () const { return member; };
private:
  int member = 0;
};

ALLOW_ACCESS(X, int, member);

int main() {
  X x;
  ACCESS(x, member) = 42;
  std::cout << "proof: " << x.get_member() << std::endl;
}
 4
Author: iammilind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:21

Si sabe cómo su compilador C++ manipula los nombres, sí.

A menos que, supongo, sea una función virtual. Pero entonces, si usted sabe cómo su compilador de C++ construye la VTABLE ...

Editar: mirando las otras respuestas, me doy cuenta de que malinterpreté la pregunta y pensé que era sobre las funciones de los miembros, no sobre los datos de los miembros. Sin embargo, el punto sigue en pie: si sabe cómo su compilador presenta los datos, entonces puede acceder a esos datos.

 3
Author: kdgregory,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 20:09:20

Como alternativa al método de puerta trasera de plantilla, puede usar la clase de puerta trasera de plantilla. La diferencia es que no necesitas poner esta clase backdoor en el área pública de la clase que vas a probar. Utilizo el hecho de que muchos compiladores permiten que las clases anidadas accedan al área privada de la clase envolvente (que no es exactamente el estándar de 1998, pero se considera que es el comportamiento "correcto"). Y por supuesto en C++11 esto se convirtió en comportamiento legal.

Vea este ejemplo:

#include <vector>
#include <cassert>
#include <iostream>
using std::cout;
using std::endl;


///////// SystemUnderTest.hpp
class SystemUnderTest
{
   //...put this 'Tested' declaration into private area of a class that you are going to test
   template<typename T> class Tested;
public:
   SystemUnderTest(int a): a_(a) {}
private:
   friend std::ostream& operator<<(std::ostream& os, const SystemUnderTest& sut)
   {
      return os << sut.a_;
   }
   int a_;
};

/////////TestFramework.hpp
class BaseTest
{
public:
   virtual void run() = 0;
   const char* name() const { return name_; }
protected:
   BaseTest(const char* name): name_(name) {}
   virtual ~BaseTest() {}
private:
   BaseTest(const BaseTest&);
   BaseTest& operator=(const BaseTest&);
   const char* name_;
};

class TestSuite
{
   typedef std::vector<BaseTest*> Tests;
   typedef Tests::iterator TIter;
public:
   static TestSuite& instance()
   {
      static TestSuite TestSuite;
      return TestSuite;
   }
   void run()
   {
      for(TIter iter = tests_.begin(); tests_.end() != iter; ++iter)
      {
         BaseTest* test = *iter;
         cout << "Run test: " << test->name() << endl;
         test->run();
      }
   }
   void addTest(BaseTest* test)
   {
      assert(test);
      cout << "Add test: " << test->name() << endl;
      tests_.push_back(test);
   }
private:
   std::vector<BaseTest*> tests_;
};

#define TEST_CASE(SYSTEM_UNDER_TEST, TEST_NAME) \
class TEST_NAME {}; \
template<> \
class SYSTEM_UNDER_TEST::Tested<TEST_NAME>: public BaseTest \
{ \
   Tested(): BaseTest(#SYSTEM_UNDER_TEST "::" #TEST_NAME) \
   { \
      TestSuite::instance().addTest(this); \
   } \
   void run(); \
   static Tested instance_; \
}; \
SYSTEM_UNDER_TEST::Tested<TEST_NAME> SYSTEM_UNDER_TEST::Tested<TEST_NAME>::instance_; \
void SYSTEM_UNDER_TEST::Tested<TEST_NAME>::run()


//...TestSuiteForSystemUnderTest.hpp
TEST_CASE(SystemUnderTest, AccessPrivateValueTest)
{
   SystemUnderTest sut(23);
   cout << "Changed private data member from " << sut << " to ";
   sut.a_ = 12;
   cout << sut << endl;
}

//...TestRunner.cpp
int main()
{
   TestSuite::instance().run();
}
 1
Author: AlexT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-08 12:07:31

A todas las personas que sugieren " # definir privado público":

Este tipo de cosas es ilegal. El estándar prohíbe definir / undef-ing macros que son léxicamente equivalentes a palabras clave de lenguaje reservadas. Si bien su compilador probablemente no se quejará (aún no he visto un compilador que lo haga), no es algo que sea "Bueno" hacer.

 0
Author: Tritium,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 16:16:12

En realidad es bastante fácil:

class jail {
    int inmate;
public:
    int& escape() { return inmate; }
};
 0
Author: MSalters,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 16:22:48

El siguiente código accede y modifica un miembro privado de la clase usando un puntero a esa clase.

#include <iostream>
using namespace std;
class A
{
    int private_var;
    public:
    A(){private_var = 0;}//initialized to zero.
    void print(){cout<<private_var<<endl;}
};

int main()
{
    A ob;
    int *ptr = (int*)&ob; // the pointer to the class is typecast to a integer pointer.  
    (*ptr)++; //private variable now changed to 1.
    ob.print();
    return 0;
}
/*prints 1. subsequent members can also be accessed by incrementing the pointer (and
  type casting if necessary).*/
 0
Author: tanujrastogi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-10 12:58:58

Al lado de #define private public también puedes #definir private protected y luego definir alguna clase foo como descendiente de la clase wanted para tener acceso a sus métodos (ahora protegidos) a través de type casting.

 -1
Author: dmajkic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 13:01:40

Simplemente cree su propia función miembro de acceso para extender la clase.

 -1
Author: RichieHH,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-08 13:30:34

"el uso de variables privadas no es una forma 100% confiable de imponer la encapsulación, incluso en C++." ¿En serio? Puede desmontar la biblioteca que necesita, encontrar todas las compensaciones necesarias y usarlas. Eso le dará la posibilidad de cambiar a cualquier miembro privado que desee... ¡PERO! No se puede acceder a los miembros privados sin un poco de piratería sucia. Digamos que escribir const no hará que tu constante sea realmente constante, porque puedes cast const lejos o simplemente use su dirección para lo invalida. Si está utilizando MSVC++ y especificó " - merge:.rdata=.datos " para un enlazador, el truco funcionará sin fallas de acceso a la memoria. Incluso podemos decir que escribir aplicaciones en C++ no es una forma confiable de escribir programas, porque el código de bajo nivel resultante puede ser parcheado desde algún lugar fuera cuando su aplicación se está ejecutando. Entonces, ¿cuál es la forma documentada confiable de hacer cumplir la encapsulación? ¿Podemos ocultar los datos en algún lugar de la RAM y evitar que nada acceda a ellos excepto nuestro código? La única idea que tienen que cifrar los miembros privados y hacer copias de seguridad de ellos, porque algo puede corromper a esos miembros. Lo siento si mi respuesta es demasiado grosera, no quise ofender a nadie, pero realmente no creo que esa declaración sea sabia.

 -1
Author: Dmitriy Yurchenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-12-22 21:55:26

Dado que usted tiene un objeto de clase requerida, supongo que tiene declaración de clase. Ahora lo que puede hacer es declarar otra clase con los mismos miembros, pero mantener todos los especificadores de acceso como públicos.

Por ejemplo, la clase anterior es:

class Iamcompprivate
{
private:
    Type1 privateelement1;
    Typ2 privateelement2;
    ...

public:
    somefunctions
}

Puede declarar una clase como

class NowIampublic
{
**public:**
    Type1 privateelement1;
    Type2 privateelement2;
    ...

    somefunctions
};

Ahora todo lo que necesita hacer es convertir el puntero de la clase Iamcompprivate en un puntero de la clase NowIampublic y usarlos como desee.

Ejemplo:

NowIampublic * changetopublic(Iamcompprivate *A)
{
    NowIampublic * B = (NowIampublic *)A;
    return B;
}
 -1
Author: Alok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-13 01:01:35

Haciendo referencia a * este habilita una puerta trasera para todos los datos privados dentro de un objeto.

class DumbClass
{
private:
    int my_private_int;
public:
    DumbClass& backdoor()
    {
        return *this;
    }
}
 -1
Author: mage_hat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-03 19:32:51

Muy a menudo una clase proporciona métodos mutadores a datos privados (getters y setters).

Si una clase proporciona un getter que devuelve una referencia const (pero no un setter), entonces puede simplemente const_cast el valor devuelto del getter, y usarlo como un valor l:

class A {
  private:
    double _money;
  public:
    A(money) :
      _money(money)
    {}

    const double &getMoney() const
    {
      return _money;
    }
};

A a(1000.0);
const_cast<double &>(a.getMoney()) = 2000.0;
 -1
Author: Lanting,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-07-16 10:14:59

He utilizado otro enfoque (y solución) útil para acceder a un miembro privado/protegido de c++.
La única condición es que pueda heredar de la clase a la que desea acceder.
Entonces todo el crédito va a reinterpret_cast().

Un posible problema es que no funcionará si inserta una función virtual, que modificará la tabla virtual y, por lo tanto, el tamaño/alineación del objeto.

class QObject
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(QObject)
    void dumpObjectInfo();
    void dumpObjectTree();
...
protected:
    QScopedPointer<QObjectData> d_ptr;
...
}

class QObjectWrapper : public QObject
{
public:
    void dumpObjectInfo2();
    void dumpObjectTree2();
};

Entonces solo necesita usar la clase de la siguiente manera:

QObject* origin;
QObjectWrapper * testAccesor = reinterpret_cast<QObjectWrapper *>(origin);
testAccesor->dumpObjectInfo2();
testAccesor->dumpObjectTree2();

Mi el problema original era el siguiente: Necesitaba una solución que no implicara recompilar bibliotecas QT.
Hay 2 métodos en QObject, dumpObjectInfo() y dumpObjectTree(), que simplemente trabaje si las libs de QT están compiladas en modo de depuración, y por supuesto necesitan acceso al miembro protegido d_ptr (entre otras estructuras internas).
Lo que hice fue usar la solución propuesta para reimplementar (con copiar y pegar) esos métodos en dumpObjectInfo2 () y dumpObjectTree2 () en mi propia clase ( QObjectWrapper) eliminando esos protectores de preprocesador de depuración.

 -1
Author: kikeenrique,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-08 15:31:07

Solo propósito del estudio.... prueba esto ....puede ser útil, supongo..... este programa puede acceder a los datos privados con solo conocer los valores...

//GEEK MODE....;)
#include<iostream.h>
#include<conio.h>

    class A
    {
    private :int iData,x;
    public: void get()             //enter the values
        {cout<<"Enter iData : ";
            cin>>iData;cout<<"Enter x : ";cin>>x;}

        void put()                               //displaying values
    {cout<<endl<<"sum = "<<iData+x;}
};

void hack();        //hacking function

void main()
{A obj;clrscr();
obj.get();obj.put();hack();obj.put();getch();
}

void hack()         //hack begins
{int hck,*ptr=&hck;
cout<<endl<<"Enter value of private data (iData or x) : ";
cin>>hck;     //enter the value assigned for iData or x
for(int i=0;i<5;i++)
{ptr++;
if(*ptr==hck)
{cout<<"Private data hacked...!!!\nChange the value : ";
cin>>*ptr;cout<<hck<<" Is chaged to : "<<*ptr;
return;}
}cout<<"Sorry value not found.....";
}
 -1
Author: NEURON ENIX,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-18 18:11:30

Inspirado en @Johannes Schaub - litb, el siguiente código puede ser un poco más fácil de digerir.

    struct A {
    A(): member(10){}
    private:
    int get_member() { return member;}
    int member;
   };

   typedef int (A::*A_fm_ptr)();
   A_fm_ptr  get_fm();

  template<   A_fm_ptr p> 
  struct Rob{ 
     friend A_fm_ptr  get_fm() {
   return p;
  }
};

 template struct Rob<  &A::get_member>;

 int main() {
   A a;
  A_fm_ptr p = get_fm();

    std::cout << (a.*p)() << std::endl;

  }
 -1
Author: Yunzhou Wu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-22 22:03:30
class Test{
    int a;
    alignas(16) int b;
    int c;
};

Test t;

Método A: estado de ánimo intrusivo. dado que podemos acceder al código fuente y volver a completarlo, podemos utilizar muchas otras formas como clase amigo para acceder a miembro privado, todos ellos son backdoor legal.

Método B: humor bruto.

int* ptr_of_member_c = reinterpret_cast<int*>(reinterpret_cast<char*>(&t) + 20);

Usamos un número mágico (20) , y no siempre es correcto. Cuando el diseño de la prueba de clase cambió, el número mágico es una gran fuente de errores.

Método C: humor de super hacker. ¿hay algún estado de ánimo no intrusivo y no bruto ? dado que la información de diseño de la prueba de clase es ocultar por el complier, no podemos obtener información de compensación de la boca del complie. ex.

offsetof(Test,c); //complie error. they said can not access private member.

Tampoco podemos obtener el puntero del miembro de la prueba de clase. ex.

&Test::c ;  //complie error. they said can not access private member.

@Johannes Schaub - litb tiene un blog, encontró una manera de robar puntero miembro privado. pero pensé que esto debería ser el error de Complier o la trampa del lenguaje. puedo cumplirlo en gcc4.8, pero no en vc8 complier.

Así que la conclusión puede ser : la construcción del propietario toda la puerta trasera. el ladrón siempre tiene mala forma de entrar. el hacker accidental tiene una forma elegante y automatizada de entrar.

 -2
Author: thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-11 03:42:31