Source: access permission breakthrough
Added some understanding.
When writing code, we put the member data in the private access area according to the Conventions, and then access the data through corresponding functions. So what kind of code can break through the access permission to directly operate the member data in the private section of the class?
First, we thought of pointers, right ~ Pointer is the king of all, but it is also the source of all evil. Let's take a look at how to break through the pointer.Magino line of defense.
Define a test class first
ClassX
{
Private:
IntM_nprivate;
Public:
X ()
: M_nprivate (1)
{}
Template<TypenameT>
VoidFunc (ConstT & T) // a template function exists in the class
{}
Const
IntGetvalue ()
{
ReturnM_nprivate;
}
}; It's easy, right? The Private member m_nprivate is our goal. Let's take a look at the breakthrough code: void * P = & X; // obtain the starting address of the class, which is actually the address of the m_nprivate data member.
Int * n = (int *) P;
Int TMP = 2;
* N = TMP; // rewrite the value.
Cout <X. getvalue () <Endl; // The output is 2.Use Pointer offsetAll right, a successful breakthrough! Let's take a look at other methods.
1. ForgedThis trick is to copy a class definition to be forged, and then use the copied "fake" to achieve the goal.VoidHijack (x
& X)
{
X. m_nprivate =
2;
}
ClassX
{
// Manually add
Friend
: Hijack (x
&);
// Copy the definition of Class X
Private:
IntM_nprivate;
Public:
X ()
: M_nprivate (1)
{}
Template<TypenameT>
VoidFunc (ConstT & T)
{}
Const
IntGetvalue ()
{
ReturnM_nprivate;
}
};
An error occurred while overwriting the class definition.This trick was caught by the vc2008 compiler and failed to pass the compilation. Because it violates the unique definition rule (ODR, one definition rule ). It seems that language lawyers will not let go of this brainless Counterfeiter! Counterfeiting and counterfeiting, the more you get, the more fake you get!2. Stealing MethodsSecretly changing the meaning of the definition class. See :#Define
Private Public// All the evil macro tricks
VoidHijack (x
& X)
{
X. m_nprivate =
2;
}
His fingers are flexible. The command is successfully executed in vc2008. However, he has two violations:
1) # define reserved words are invalid
2) Violation of the unique definition rule (ODR). However, the underlying memory layout of the class has not changed, so it is feasible.
Use # define private public to steal a column
3. scammers
// Memory layout of the same X, with only one int Type Variable
ClassBaitswitch
{
Public:
IntM_nnotprivate;
};
VoidFunc (x
& X)
{
(Reinterpret_cast(X). m_nnotprivate = 2;
} It was successfully executed on vc2008, but the vulnerability exists: the reinterpret_cast behavior in the standard is not defined, and vc2008 allows reference of returned results. Therefore, the scammers are also successful.Creates a new public class with the same memory structure and converts pointer types.
4. Language lawyersA lawyer is a loophole in the law and will never be caught. He is exploiting the loopholes in the law! SeeNamespace
{
StructY {};
}
Template<>
VoidX: func (ConstY &)
{
M_nprivate = 2;
}
VoidTest ()
{
X;
Cout <X. getvalue ()
<Endl;
X. func (Y ());
Cout <X. getvalue ()
<Endl;
}
His success mainly utilizes the fact that X has a member template, the Code fully complies with the standards, and the Standards ensure that such behavior will act according to the intent of the encoding. This method is widely used in boost and Loki.Before the actual compilation, the template compilation process adds a member function to class X.Originally, there was an implemented template function in the class!Then, a template function is added to the External table, resulting in a new one written in the template deduction process and added to the alternative group, which is equivalent to an additional overload.Because the parameters of this function are specific classes in the anonymous space, it completely avoids disturbing the functions of the original function.Brilliant!Opinion:I believe this is not a vulnerability in the C ++ access control mechanism. Maybe we should not have done so. Using a member template to provide effective access to data that may bypass class access control may be what we want to achieve.
Added some understanding.
When writing code, we put the member data in the private access area according to the Conventions, and then access the data through corresponding functions. So what kind of code can break through the access permission to directly operate the member data in the private section of the class?
First, we thought of pointers, right ~ Pointer is the king of all, but it is also the source of all evil. Let's take a look at how to break through the pointer.Magino line of defense.
Define a test class first
ClassX
{
Private:
IntM_nprivate;
Public:
X ()
: M_nprivate (1)
{}
Template<TypenameT>
VoidFunc (ConstT & T) // a template function exists in the class
{}
Const
IntGetvalue ()
{
ReturnM_nprivate;
}
}; It's easy, right? The Private member m_nprivate is our goal. Let's take a look at the breakthrough code: void * P = & X; // obtain the starting address of the class, which is actually the address of the m_nprivate data member.
Int * n = (int *) P;
Int TMP = 2;
* N = TMP; // rewrite the value.
Cout <X. getvalue () <Endl; // The output is 2.Use Pointer offsetAll right, a successful breakthrough! Let's take a look at other methods.
1. ForgedThis trick is to copy a class definition to be forged, and then use the copied "fake" to achieve the goal.VoidHijack (x
& X)
{
X. m_nprivate =
2;
}
ClassX
{
// Manually add
Friend
: Hijack (x
&);
// Copy the definition of Class X
Private:
IntM_nprivate;
Public:
X ()
: M_nprivate (1)
{}
Template<TypenameT>
VoidFunc (ConstT & T)
{}
Const
IntGetvalue ()
{
ReturnM_nprivate;
}
};
An error occurred while overwriting the class definition.This trick was caught by the vc2008 compiler and failed to pass the compilation. Because it violates the unique definition rule (ODR, one definition rule ). It seems that language lawyers will not let go of this brainless Counterfeiter! Counterfeiting and counterfeiting, the more you get, the more fake you get!2. Stealing MethodsSecretly changing the meaning of the definition class. See :#Define
Private Public// All the evil macro tricks
VoidHijack (x
& X)
{
X. m_nprivate =
2;
}
His fingers are flexible. The command is successfully executed in vc2008. However, he has two violations:
1) # define reserved words are invalid
2) Violation of the unique definition rule (ODR). However, the underlying memory layout of the class has not changed, so it is feasible.
Use # define private public to steal a column
3. scammers
// Memory layout of the same X, with only one int Type Variable
ClassBaitswitch
{
Public:
IntM_nnotprivate;
};
VoidFunc (x
& X)
{
(Reinterpret_cast(X). m_nnotprivate = 2;
} It was successfully executed on vc2008, but the vulnerability exists: the reinterpret_cast behavior in the standard is not defined, and vc2008 allows reference of returned results. Therefore, the scammers are also successful.Creates a new public class with the same memory structure and converts pointer types.
4. Language lawyersA lawyer is a loophole in the law and will never be caught. He is exploiting the loopholes in the law! SeeNamespace
{
StructY {};
}
Template<>
VoidX: func (ConstY &)
{
M_nprivate = 2;
}
VoidTest ()
{
X;
Cout <X. getvalue ()
<Endl;
X. func (Y ());
Cout <X. getvalue ()
<Endl;
}
His success mainly utilizes the fact that X has a member template, the Code fully complies with the standards, and the Standards ensure that such behavior will act according to the intent of the encoding. This method is widely used in boost and Loki.Before the actual compilation, the template compilation process adds a member function to class X.Originally, there was an implemented template function in the class!Then, a template function is added to the External table, resulting in a new one written in the template deduction process and added to the alternative group, which is equivalent to an additional overload.Because the parameters of this function are specific classes in the anonymous space, it completely avoids disturbing the functions of the original function.Brilliant!Opinion:I believe this is not a vulnerability in the C ++ access control mechanism. Maybe we should not have done so. Using a member template to provide effective access to data that may bypass class access control may be what we want to achieve.