【问题标题】:Memory exploitation for setting member variables of a Structure in one step [duplicate]一步中设置结构成员变量的内存利用[重复]
【发布时间】:2018-08-01 03:37:47
【问题描述】:

下面的算法可以输出99 0000

请告诉我下面这行代码是如何工作的?

*(long*)&(st->flag1) = 0;

算法是:

#include <stdio.h>

struct SpecialFlags{
 int  id;
 char flag1;
 char flag2;
 char flag3;
 char flag4;
};


void ClearFlags( SpecialFlags *st )
{
  *(long*)&(st->flag1) = 0;
}

int main(void)
{
  SpecialFlags flags;
  flags.id =    99;

  flags.flag1 = 1;
  flags.flag2 = 2;
  flags.flag3 = 3;
  flags.flag4 = 4;
  ClearFlags( &flags );

  printf( "%d %d%d%d%d\n", flags.id, 
    flags.flag1, flags.flag2, 
    flags.flag3, flags.flag4 );
  return 0;
}

【问题讨论】:

  • 它将最后一颗钉子钉入未定义的棺材。
  • 从右到左阅读。获取st-&gt;flag1 的地址(&amp;),将其转换为long*,然后取消引用(*)该指针。写这句话的人把它用作一个可怕的黑客,将所有四个flags 设置为 0。
  • @0x5453 &amp;这里取的是地址,不是引用
  • ...**if** sizeof long 实际上是 4...
  • @DevSolar 我错过了您评论中的if。

标签: c++ pointers


【解决方案1】:

在下面的结构中

struct SpecialFlags{
        int  id;
        char flag1;
        char flag2;
        char flag3;
        char flag4;
};

        id       flag1     flag2     flag3      flag4
     -------------------------------------------------- 
     | 99      | 1(49)    | 2(50)   | 3(51)   |  4(52) |
     ---------------------------------------------------
   0x100     0x104       0x105     0x106      0x107   0x108 <--lets say starting address is 0x100

当ClearFlags() 被调用时,st 指向结构的开头。当您执行 *(long*)&amp;(st-&gt;flag1) = 0; 第一个 address 的 st-&gt;flags1(char type) 被转换为 long* 类型时,这意味着它将一次获取 4 bytes 最后 * 表示 4 个字节中的值.

从上图看

  • (long*)&amp;(st-&gt;flag1) => 从0x104 地址到下一个 4 字节,即直到 0x108
  • *(long*)&amp;(st-&gt;flag1) => 0x104 location 到 0x108 location 之间的值是多少
  • *(long*)&amp;(st-&gt;flag1) = 0 => 在0x104 位置和0x108 位置之间有什么值,将被0(zero) 覆盖

在这句话之后你的结构看起来像

       id       flag1     flag2     flag3      flag4
     -------------------------------------------------- 
     | 99      | 0(48)    | 0(48)   | 0(48)   |  0(48) |
     ---------------------------------------------------
   0x100     0x104       0x105     0x106      0x107   0x108

现在,当您打印 flags.flag1、flags.flag2.. 时,它会打印 0。

【讨论】:

  • 有个小错误。这些值是数字而不是字符。所以0是0而不是48。如果要将标志设置为'0',则需要分配*(long*)&amp;(st-&gt;flag1) = 48+256*(48+256*(48+256*48));
猜你喜欢
  • 2019-01-30
  • 2012-09-02
  • 1970-01-01
  • 1970-01-01
  • 2016-03-29
  • 1970-01-01
  • 2019-07-28
  • 2021-12-29
  • 2021-05-06
相关资源
最近更新 更多