如何识别位掩码背后的目的?

逆向工程 拆卸 反编译
2021-07-09 16:58:33

位掩码用于操作整数变量的值。从调试中,我猜测按位运算生成最接近的偶数整数。这是大会:

mov     r8d, 0FFFFFFF8h
jnz     loc_x
mov     eax, [rsp+48]
add     eax, 7
and     eax, r8d
mov     edi, eax
mov     r8d, eax
mov     [rsp+48], rdi
call    operator_new
xor     r8d, r8d
mov     rsi, rax
test    rax, rax
jz      loc_y

感兴趣的伪代码是:

a = (b + 7) & 0xFFFFFFF8;
c = a;

那么,0xFFFFFFF8价值有什么作用呢?我如何确定该操作背后的目的(以及将来可能的任何其他目的)?

3个回答

不知道结果用于什么,但是如果您想“向上舍入”到最近的 8 字节边界,这正是您会看到的。

该+7确保推动所有“无关位”出来的低3位,而在同一时间确保我们圆(只是做按位&与整并不能保证这个结果)。然后按位&与所述位掩码确保去除 3 个最低有效位,产生我上面描述的结果。

现在显然这到底用于什么超出了我的范围,因为通过查看目标二进制文件,我缺乏您拥有的上下文,但是通过我的回答,该机制应该变得清晰。

只是对 0xC00000022Ls 的补充已经给出了解释。您可以在 Henry S. Warren Jr. 所著的“Hackers Delight”一书中找到他的答案以及许多其他非常有用的解释和技巧:

在第 3-1 章中有。“向上/向下舍入到已知 2 的幂的倍数”

引用:

... 一个无符号整数 x 可以四舍五入到下一个更大的 8 倍数

(x+7) & -8 

或者

x + (-x+7).

-8 在 32 位中表示为 0xfffffff8

有时一个 python 脚本使它更容易理解

def bitbut(a,b):
    for i in range(a,b,1):
        b = 0 + i
        c = b + 7
        d = c & 0xfffffff8
        print "%3d" % (d),
    print "\n"
for i in range(0,256,16):
    bitbut(i,i+16)

输出

  0   8   8   8   8   8   8   8   8  16  16  16  16  16  16  16 

 16  24  24  24  24  24  24  24  24  32  32  32  32  32  32  32 

 32  40  40  40  40  40  40  40  40  48  48  48  48  48  48  48 

 48  56  56  56  56  56  56  56  56  64  64  64  64  64  64  64 

 64  72  72  72  72  72  72  72  72  80  80  80  80  80  80  80 

 80  88  88  88  88  88  88  88  88  96  96  96  96  96  96  96 

 96 104 104 104 104 104 104 104 104 112 112 112 112 112 112 112 

112 120 120 120 120 120 120 120 120 128 128 128 128 128 128 128 

128 136 136 136 136 136 136 136 136 144 144 144 144 144 144 144 

144 152 152 152 152 152 152 152 152 160 160 160 160 160 160 160 

160 168 168 168 168 168 168 168 168 176 176 176 176 176 176 176 

176 184 184 184 184 184 184 184 184 192 192 192 192 192 192 192 

192 200 200 200 200 200 200 200 200 208 208 208 208 208 208 208 

208 216 216 216 216 216 216 216 216 224 224 224 224 224 224 224 

224 232 232 232 232 232 232 232 232 240 240 240 240 240 240 240 

240 248 248 248 248 248 248 248 248 256 256 256 256 256 256 256 

可以看出,
对于介于
0 和 8之间的任何输入,都可以从输出中辨别出模式,输出将是 8
9 和 16 都包括在内,输出将是 16,依此类推,
因此汇编代码段将输入四舍五入为下一个边界
是 8 的倍数