遇到一个需要计算的题,逆向不出来,就想想使用正向求解,z3了解一下

什么是z3

Z3 is a theorem prover from Microsoft Research. It >is licensed under the MIT license.

If you are not familiar with Z3, you can start >here.

Pre-built binaries for releases are available from >here, and nightly builds from here.

Z3 can be built using Visual Studio, a Makefile or >using CMake. It provides bindings for several >programming languages.

See the release notes for notes on various stable >releases of Z3.

就是一个约束器,可以简单理解为解方程的东西。

z3英文文档

z3翻译文档

通俗易懂

z3有三种变量类型

Int型

这种就像是我们平常说的整型,一般简单运算都可以用这个,用运算符<, <=, >, > =, ==和 !=来进行比较

案例

x = Int('x')
y = Int('y')
solve(x > 2, y < 10, x + 2*y == 7)

RealVal型

就是小数形式,使用的很多,

案例

x = Real('x')
y = Real('y')
solve(x**2 + y**2 == 3, x**3 == 2)

set_option(precision=30)
print "Solving, and displaying result with 30 decimal places"
solve(x**2 + y**2 == 3, x**3 == 2)

BitVec型

现代CPU和主流编程语言使用固定大小的位向量进行算术运算。机器算法在Z3Py中可用Bit-Vectors来表示。
它实现了无符号和有符号二补数算术的精确表示,只有这个类型才可以使用异或等位运算

案例

x = BitVec('x', 16)
y = BitVec('y', 16)
print x + 2
# Internal representation
print (x + 2).sexpr()

# -1 is equal to 65535 for 16-bit integers 
print simplify(x + y - 1)

# Creating bit-vector constants
a = BitVecVal(-1, 16)
b = BitVecVal(65535, 16)
print simplify(a == b)

a = BitVecVal(-1, 32)
b = BitVecVal(65535, 32)
# -1 is not equal to 65535 for 32-bit integers 
print simplify(a == b)

一些命令如下

命令 效果
set_option(rational_to_decimal=True) 设置结果全局十进制表示
set_option(precision=30) 设置结果小数点后位数表示
simplify 化简之后约束条件
assertions 显示全部约束条件

CTF案例

文件地址
主要IDA逻辑

from z3 import *
data1 = [0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 
  0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 
  0x3F, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x7B, 0x7C, 
  0x7D, 0x7E]
data2 = [0x72, 0xE9, 0x4D, 0xAC, 0xC1, 0xD0, 0x24, 0x6B, 0xB2, 0xF5, 
  0xFD, 0x45, 0x49, 0x94, 0xDC, 0x10, 0x10, 0x6B, 0xA3, 0xFB, 
  0x5C, 0x13, 0x17, 0xE4, 0x67, 0xFE, 0x72, 0xA1, 0xC7, 0x04, 
  0x2B, 0xC2, 0x9D, 0x3F, 0xA7, 0x6C, 0xE7, 0xD0, 0x90, 0x71, 
  0x36, 0xB3, 0xAB, 0x67, 0xBF, 0x60, 0x30, 0x3E, 0x78, 0xCD, 
  0x6D, 0x35, 0xC8, 0x55, 0xFF, 0xC0, 0x95, 0x62, 0xE6, 0xBB, 
  0x57, 0x34, 0x29, 0x0E, 0x03]

s = Solver()
xor_res = [0]*0x41
k = [BitVec(("k%s"%i),8) for i in range(0x22)]
for i in k:
    s.add(i>0x20,i<0x7E)
for m in range(0x22):
    for n in range(0x20):
        xor_res[m+n] += k[m]^data1[n]
for j in range(0x41):
    s.add(xor_res[j]==data2[j])
print(s.check())
aa = s.model()
for i in range(0x22):
    print(chr(int('%s'%aa[k[i]])),end='')

几秒解出,很方便



逆向  

z3 Python

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!