繁体   English   中英

Z3方程求解器-位掩码操作

[英]Z3 Equation Solver - Bitmask Operation

在对程序进行逆向工程之后,我发现了约束。

我必须找到两个这样的无符号数字:

x + y = 0xC0ED91BD

x * y = Z

在原始程序中,使用imul指令执行数字的乘法。

Z应该使得仅检查Z的低32位时,它应该小于60。

Z & 0x00000000ffffffff < 60

但是,当我将第二个方程式添加为约束时,z3给我一个错误。

这是我的代码:

#! /usr/bin/python

from z3 import *
import sys

s = Solver()
result = int(sys.argv[1], 16)

x = Int('x')
y = Int('y')

s.add(x + y == result)
s.add(x > 0, y > 0)
s.add((x * y) & 0x00000000ffffffff < 60)

while s.check() == sat:
    print s.model()
    s.add(Or(x != s.model()[x], y != s.model()[y]))

更新:

这是基于推荐解决方案的代码:

#! /usr/bin/python

from z3 import *
import sys

s = Solver()
x = BitVec('x', 32)
y = BitVec('y', 32)

result = BitVecVal(int(sys.argv[1], 16), 32)

s.add(x + y == result)
s.add(x > 0, y > 0)
s.add(x * y < 10)

print s.check()
print s.model()

二进制是64位。

但是,乘法运算是使用32位整数执行的,如下所示:

mov     edx, [rbp+var_14]
mov     eax, [rbp+var_10]
imul    eax, edx

所以如果eax = 0x425a95e5和edx = 0x7e92fbd8

然后,使用imul指令相乘后,eax将存储:0x00000038。

之后,EFLAGS寄存器中的进位标志位和溢出标志位都将被置1。

这里的问题是,您已将xy声明为任意宽的整数,而不是固定长度的位向量。 只需更改您的声明以匹配基础位大小即可。 假设您希望算术运算以32位完成,您会说:

x = BitVec('x', 32)
y = BitVec('y', 32)

代替。 您还应该类似地声明result

result = BitVecVal(int(sys.argv[1], 16), 32)

进行这些更改后,您的程序应该可以正常工作。

请注意,在这种情况下,使用0x00000000ffffffff掩膜并不是必须的。 因为数字已经是32位宽。 如果xy较大,则只需要保留它; 说64位。

经过以上更改,运行程序并使用0xC0ED91BD调用时,将得到以下输出:

[y = 2123561944, x = 1113232869]
[y = 1440310864, x = 1796483949]
[y = 1171875408, x = 2064919405]
... many other lines ..

这看起来有些混乱,因为数字似乎比您想象的要大。 但是请记住,对位向量进行算术运算是对2^n模,其中n是位大小,因此结果实际上是正确的:

>>> 2123561944 + 1113232869 % 2**32 == 0xC0ED91BD
True
>>> 2123561944 * 1113232869 % 2**32 < 60
True

等等

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM