После обратного проектирования программы я нашел ограничения.
Я должен найти два числа без знака, таких как:
x + y = 0xC0ED91BD
и
x * y = Z
В исходной программе умножение чисел выполняется с помощью инструкции imul.
Z должно быть таким, чтобы при проверке только младших 32 битов Z оно было меньше 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 будут установлены после него.