[英]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。
这里的问题是,您已将x
和y
声明为任意宽的整数,而不是固定长度的位向量。 只需更改您的声明以匹配基础位大小即可。 假设您希望算术运算以32位完成,您会说:
x = BitVec('x', 32)
y = BitVec('y', 32)
代替。 您还应该类似地声明result
:
result = BitVecVal(int(sys.argv[1], 16), 32)
进行这些更改后,您的程序应该可以正常工作。
请注意,在这种情况下,使用0x00000000ffffffff
掩膜并不是必须的。 因为数字已经是32位宽。 如果x
和y
较大,则只需要保留它; 说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.