【问题标题】:How do you implement the inverse of bit shift operations in C? [closed]如何在 C 中实现移位操作的逆运算? [关闭]
【发布时间】:2019-08-21 22:00:04
【问题描述】:

在对使用位移位操作的 C 代码进行逆向工程时,我对获得以下逆向代码背后的方法感到困惑。

unsigned char red = 37;
unsigned char blue = 100;
unsigned char green = 77
unsigned short us = (red << 8) + (blue);
us = (us << 5 ) | (us >> 11);
unsigned int threebytes = (us << 8) + green;

由于 NOT 是反转位的操作,我假设我可以实现 NOT 以反转每一行或代码末尾的位,但是,我的结果与导致我的预期输出不匹配相信我误会了。我对逆向工程有什么不了解的地方?

【问题讨论】:

  • 那不叫“逆向工程”,这里也没有NOT操作。如果你不知道运算符是什么,你需要先阅读一本 C 的书来代替
  • 我不关注这里。如果向左移位,则可以通过向右移位来反转操作,反之亦然。
  • 你没有解释你的预期输出是什么。请这样做,并为输入和输出使用二进制。

标签: c bit-manipulation reverse-engineering


【解决方案1】:

这似乎是理解 C 位操作的课堂练习。它进一步似乎假设unsigned char 是 8 位,unsigned short 是 16 位,unsigned int 可能是 32 位。您在练习中的工作是了解哪些位被移动到哪里,并设计新的操作,将这些位从threebytes 中的结果值移回三个独立变量中的原始值。

以下是理解代码的一些帮助:

unsigned short us = (red << 8) + (blue);

此代码将red 的值左移(高)八位,并将blue 的值放在低八位。

us = (us << 5 ) | (us >> 11);

这执行了有效的位旋转。假设我们标记us 中的 16 位,以便我们可以跟踪它们:

fedcba9876543210

表达式us &lt;&lt; 5 以 16 位生成 this(由于 C 规则,中间结果实际上有 32,但后面的高 16 将被丢弃,因此我们忽略它们):

a9876543210_____

下划线表示移入的新 0 位。其他数字是前一个位值的标签。

表达式us &gt;&gt; 11 产生这个:

___________fedcb.

当这些与(us &lt;&lt; 5) |(us >> 11)`中的|结合时,结果是:

a9876543210fedcb

因此,原始位 fedcba9876543210 已旋转为 a9876543210fedcb

然后这个:

unsigned int threebytes = (us << 8) + green

us 的 16 位左移 8 位,并将 green 的值插入低 8 位。

由此,您应该能够了解redbluegreen 中的所有位最终在threebytes 中的位置。然后练习是让您编写新代码,将这些位从threebytes 移回单独的变量。

【讨论】:

    【解决方案2】:

    我假设您的意思是将threebytes 解码回其组成的 RGB 分量。

    首先让我们看看threebytes 的样子。

    第一步 (red &lt;&lt; 8) + (blue) 生成一个 16 位数字,格式类似于 rrrr rrrr bbbb bbbb

    第二步,(us &lt;&lt; 5 ) | (us &gt;&gt; 11),是向左旋转 5 位,所以结果看起来像 rrrb bbbb bbbr rrrr(其中底部的 r 位实际上是 top 5红色通道的位)。

    最后一步(us &lt;&lt; 8) + green 将绿色位附加到它上面,形成rrrb bbbb bbbr rrrr gggg gggg

    可以通过(像往常一样)采取相反的步骤并以相反的顺序执行这些步骤来取消这些步骤(这个原则与“穿上袜子,然后穿上鞋子”很相似,后者通过“脱鞋,然后拿袜子”)。所以:

    // rrrb bbbb bbbr rrrr gggg gggg
    // take green from the bottom 8 bits
    unsigned char green = threebytes;
    
    // take the remaining mixed R and B bits
    unsigned short us = threebytes >> 8;
    // rrrb bbbb bbbr rrrr
    // rotate right by 5
    us = (us << 11) | (us >> 5);
    // rrrr rrrr bbbb bbbb
    // split into red and blue
    unsigned char blue = us;
    unsigned char red = us >> 8;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-13
      • 1970-01-01
      • 1970-01-01
      • 2019-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多