签到

05月11日
尚未签到

共有回帖数 0

    做月子

    等级:
    先看一个类

    #include stdio.h

    class A
    {
    private:
       char *str;
    public:
       A(): str("nothing"){};
    };

    int main()
    {
       A a;
       return 0;
    }

    如何输出a的私有成员str所指向的字符串"nothing"?可以任意添加代码,但不可以修改这个类。

    ★★方法一:
    在定义A前,加一句“#define private public”。该方法可以欺骗编译器,让它把“private”当作“public”,然后就可以用“a.str”了。

    达到了我们的目的,只可惜这个方法有点“左道旁门”。

    ★★方法二:
    a.str的地址就是a的地址,所以用“puts(*(char**)&a);”即可访问a.str。

    ★方法二变种:
    方法二不错,但如果str不是类的第一个成员变量,就会有点麻烦。比如,把A改成如下形式:

    class A
    {
    private:
       char d;
       char *str;
    public:
       A(): str("nothing"){};
    };

    d占一个字节,a.str的地址相对于a的地址,偏移量为1,可以这么用“puts(*(char**)((char*)&a+1));”。这看似不错,但没有考虑字节对齐

    问题。为了能高效的访问变量,编译器可能会以空间换时间,采取字节对齐措施。字节对齐后,程序高效了,但对我们而言就麻烦了。str的地

    址的偏移量未必是1,可以是2、4、8等,怎么才能获取a.str的偏移量呢?别急,我们可以给该方法打打补丁。

    ☆方法二变种的补丁:
    在定义A前,加一句“#pragma pack(1)”,这行代码可以让编译器按1字节进行对齐,这样以后就可以放心大胆地用“puts(*(char**)(char*)

    &a+1));”了。


    ★★方法三:
    方法二的变种打了补丁后,也有了“左道旁门”的“嫌疑”。方法三就显得“高尚”多了。构造一个和A相似的类,但增加了一个非虚成员函数

    ,用来返回str的地址。

    #include stdio.h

    class A
    {
    private:
       char *str;
    public:
       A(): str("nothing"){};
    };

    class B
    {
    private:
       char *str;
    public:
       B(): str("nothing"){};
       char *get()
       {
           return str;
       }
    };

    int main()
    {
       A a;
       puts(((B*)(&a))-get());
       return 0;
    }

    ★★方法四:
    和方法三一样,也是构造一个新的类。但有所不同的是,“private”变成了“public”。B的布局和A相同,即同名变量的偏移量相同。这样,

    我们就可以把A实例的指针转化为B*类型,来访问str了。

    #include stdio.h

    class A
    {
    private:
       char *str;
    public:
       A(): str("nothing"){};
    };

    class B
    {
    public:
       char *str;
    public:
       B(): str("nothing"){};
    };

    int main()
    {
       A a;
       //或“puts(((B*)(&a))-str);”
       puts(reinterpret_castB*(&a)-str);
       return 0;
    }
    以上方法全是我独立想出来的
    事情多,忙啊……总算写完了
    ——————————
    3:
    是这样的

    这个方法只对某些编译器有效……通用性不够高……
    比如VS2005可以用
    __asm push a.str;
    __asm call puts;

    楼主 2016-01-23 10:22 回复

共有回帖数 0
  • 回 帖
  • 表情 图片 视频
  • 发表

登录直线网账号

Copyright © 2010~2015 直线网 版权所有,All Rights Reserved.沪ICP备10039589号 意见反馈 | 关于直线 | 版权声明 | 会员须知