我們在寫**的時候,按約定都是把成員資料放到private訪問區中,然後在通過相應的函式來訪問。那又有什麼樣的**可以突破訪問許可權來直接操作類中private區段中的成員資料呢?
首先,我們想到了指標,對吧~指標可是萬能之王,然而也是萬惡之源。那我們就先來看看指標如何突破馬其諾防線的。
先定義乙個測試類
class xtemplate
void func(const t &t)
{}const
int getvalue()
};
很簡單是吧,私有成員m_nprivate就是我們的目標。來看看突破**:
void *p = &x; // 獲取類的起始位址,其實也就是m_nprivate資料成員的位址int *n = (int *)p;
int tmp = 2;
*n = tmp; // 改寫其值
cout << x.getvalue() << endl; // 輸出為2
好了,成功突破!我們再來看看其他的方式。
1.偽造者方式
這個伎倆是現將某個有待偽造的類定義複製乙份,然後通過該複製後的「贗品」來達到目的,且看
friend ::hijack(x &);
// 這裡是複製x類定義
private:
int m_nprivate;
public:
x(): m_nprivate(1)
{}template
void func(const t &t)
{}const
int getvalue()
};這個伎倆被vc2008的編譯器逮住了,沒有編譯通過。因為他違反了唯一定義規則(odr,one definition rule)。看來語言律師還是不會放過這種沒腦子的造假者!打假、打假,越打越假!
2. 偷竊者方式
偷偷的改變定義類的含義。且看:
private
public
// 萬惡的巨集伎倆啊
void hijack(x &x)
他的兩根手指頭很靈活喲。在vc2008成功執行得到。然而他卻有兩個違背標準的行為:
1)#define 保留字是非法的
2)違反了但一定以規則(odr),然而類的底層記憶體布局沒改變,故可行
3.**方式
// 同x的記憶體布局,只有乙個int型的變數class baitswitch
;void func(x &x)
在vc2008上成功執行達到目的,但是卻有漏洞:
標準中reinterpret_cast的行為未定義,vc2008允許返回的結果引用。所以也成功讓**得逞。
4.語言律師方式
律師就是鑽法律的漏洞,永遠也不會被逮住,他是在鑽法律的空子!且看;}
template
<>
void x::func(const y&)
void test()
他能成功主要是利用了x具有乙個成員模板的事實,**完全符合標準,標準也確保這種行為會按照編碼者的意圖行事。boost和loki中大量運用此手法。
看法:
我相信這並不是c++訪問控制機制的漏洞,或許,我們本不應該這樣做。用成員模板提供一種有效的訪問似有成員資料可以繞過累的訪問控制,這也許就是我們想達到的目的。
C 借助指標突破訪問許可權
c 物件導向中有一大特性就是封裝,使用不同的訪問控制符來控制外界對其的訪問許可權。例如 c 中類的private成員對外是不可見的,可以通過以下方法突破對private成員的訪問許可權 includeusing namespace std class a templatevoid func cons...
C 突破private訪問許可權的黑科技
昨天,有位同事丟擲了乙個問題 乙個class內有乙個private屬性的struct型別,然後他想做的事情是,在繼承該class的子類中復用這個型別,但是由於該類似的private屬性,編譯是不通過的。因此就引入了乙個問題 如何突破class的private屬性限制 試圖破壞class的封裝性,有點...
C 突破private訪問許可權的黑科技
如何突破class的private屬性限制 試圖破壞class的封裝性,有點 逆天而行 的感覺。includeusing namespace std class x templatevoid func const t t const int getvalue friend void func x x...