2015年12月14日星期一

打破C++之类外不能访问私有成员的限制

#include "stdafx.h"


/*
标题:打破C++之类外不能访问私有成员的限制。

C++规则之一就是私有的成员变量/函数,对于类外是不可访问的。
对于C++的你,这个简单的规则你想过没有,这是如何实现的?

经测试发现,类的成员变量的是放置在一起的,不论其是私有的,功能的还是保护的。
所以从这里可以看出,他们的内存属性是一样的。
因为私有的变量也有修改的属性。
这可以检测的。

所以只能说这是C++的语法或者编译器实现的。
对于操作系统来说,类的私有,功能,保护的变量是一样的。
这是可以通过别的手法,或者变相的方式来修改/实现/突破的。

顺便说下:C++就是C++思想的对C的封装,不信你看C++的反汇编代码。

made by correy
made at 2015.12.14
http://correy.webs.com
*/


#include <Windows.h>
#include <assert.h>


class test
{
public:
    test(void);
    ~test(void);
    int get();
    int set();

    //int p;
private:
    int i;
};


test::test(void)
{
    i = 0x99999999;
    //p = 0x88888888;
}


test::~test(void)
{

}


int test::get(void)
{
    return i;
}


int test::set(void)
{
    return ++i;
}


int _tmain(int argc, _TCHAR* argv[])
{
    test t;

    printf("%p\n", t ); //这个其实是打印的类的第一个成员变量的值,不论是私有,公共还是保护。
    printf("%p\n", &t );//看看内存布局,看看反汇编。

    printf("%p\n", sizeof(test) );//不包含成员函数。

    //printf("%p\n", t.i );//无法访问 private 成员
    printf("%p\n", t.get() );
   
    //t.get();//和主题没用的函数。
    //t.set();

    void * p = &t;
    *(int *)p = 0;//这个是可以修改的,而且也没有发生异常。

    printf("%p\n", t.get() );//看看结果是否变了?

    //看内存属性吧!如果是WINDBG你还可以敲命令看。
    MEMORY_BASIC_INFORMATION mbi = {0};
    SIZE_T s = VirtualQuery(p, &mbi, sizeof (MEMORY_BASIC_INFORMATION));
    assert(s);
    printf("%p\n", mbi.AllocationProtect);

    return 0;
}

没有评论:

发表评论