对程序进行反向工程后,我发现了约束。
我必须找到两个这样的无符号数字:
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寄存器中的进位标志位和溢出标志位都将被置位。
答案 0 :(得分:1)
这里的问题是,您已将* def json = { id: 1, priority: 1, compRound: { id: 1, comp_id: 89 } }
* def compRound = { id: '#number' }
* match json == { id: '#number', priority: '#number', compRound: '#(^compRound)' }
和x
声明为任意宽的整数,而不是固定长度的位向量。只需更改您的声明以匹配基础位大小即可。假设您希望算术以32位完成,您会说:
y
相反。您还应该类似地声明x = BitVec('x', 32)
y = BitVec('y', 32)
:
result
进行这些更改后,您的程序应该可以正常运行。
请注意,在这种情况下,实际上不需要使用result = BitVecVal(int(sys.argv[1], 16), 32)
进行屏蔽。因为数字已经是32位宽。仅当0x00000000ffffffff
和x
较大时才需要保留它;说64位。
通过上述更改,运行程序并使用y
进行调用时,将得到以下输出:
0xC0ED91BD
这看起来似乎令人困惑,因为数字似乎比您认为的要大。但是请记住,对位向量进行算术运算是对[y = 2123561944, x = 1113232869]
[y = 1440310864, x = 1796483949]
[y = 1171875408, x = 2064919405]
... many other lines ..
进行模运算,其中2^n
是位大小,因此结果实际上是正确的:
n
等