基本语法
安装好后进入z3目录下,source ~/z3/bin/activate
照着官网教程学习下
1 | from z3 import * |
结果[q = False, p = False, r = True]
这里Implies是离散数学中的蕴含式,只有(1,0)->0
1 | from z3 import * |
simplify函数简化表达式(我猜可能类似于编译优化中的策略?)
1 | 3 + 3*x + y |
多项式与布尔代数的结合
1 | from z3 import * |
结果[x = -1.4142135623?, p = False]
1 | from z3 import * |
这样是错误的,因为这不是线性约束条件
显示z3内部表示形式
1 | from z3 import * |
输出结果
1 | 2**(1/2) + 3**(1/2) |
遍历模型
遍历约束条件
1 | from z3 import * |
可用于debug,输出如下
1 | assertions: |
解决方案是一组断言约束的模型(model)
模型是使每个断言约束成立的解释
此方法显示了如何遍历所有模型
1 | from z3 import * |
输出结果:
1 | sat |
函数
关于函数,z3中的函数没有副作用并且是完全的(total)
1 | from z3 import * |
其中f是一个未解释的函数(之前已经提到过解释),接收一个类型(又称排序)为整数的参数并产生一个整数值
The solution(interpretation) for f should be read as f(0) is 1,f(1) is 0,and f(a) is 1 for all a different from 0 and 1.
验证摩根定律
1 | from z3 import * |
输出结果
1 | And(p, q) == Not(Or(Not(p), Not(q))) |
以后大概很少尝试证明一些数学内容了,突然想起一句关于黎曼猜想的评论
无论对黎曼猜想的证明是否成立,仍然对Atiyah爵士一生挚爱数学致以敬意
列表推导
python支持列表推导,演示创建列表的简明方法
1 | from z3 import * |
输出结果
1 | [1, 2, 3, 4, 5] |
创建3*3矩阵,两层循环
1 | from z3 import * |
其中pp()类似print,但它使用Z3Py格式化程序来表示列表和元组
输出结果
1 | [[x_1_1, x_1_2, x_1_3], |
Z3Py还提供了创建Boolean,Integer和Real变量向量的函数,同样使用列表推导来实现
1 | from z3 import * |
输出结果
1 | [x__0, x__1, x__2, x__3, x__4] |
BitVec
CTF中用的比较多的应该就是这种BitVec
1 | from z3 import * |
ULT是无符号数的比较之一,其余见文档
1 | from z3 import * |
输出结果
1 | [y = 1, x = 1] |
逻辑移位>>最左都补0,算术移位最左补符号位,这里都是算术移位
1 | from z3 import * |
输出结果
1 | [x = 12] |
CTF&实例
1、解数独
1 | #coding:utf-8 |
输出结果
1 | [[5, 7, 2, 6, 9, 4, 1, 3, 8], |
2、CTF-1
HITB CTF 2016 soup meat tead
题目只给了源代码,稍作改动,如下
1 | // Soup Meat Tea (SMT) (TM) |
里面有很多废话,就是输入32个unsigned char,经过一堆运算后让state==0xde11c105
先给出z3的exp
1 | from z3 import * |
有一些疑问和要注意的
dish函数里的global,捕获外界全局变量
因为代码中是unsigned char,我们为求简便,用BitVec表示,接着把每一个BitVec32的范围都限定在[0,255],显然这里只用BitVec8可能是不好用的…python的类型我不熟悉,感觉挺迷的
这里如何体现正负啊???算了就这么用吧
C代码里由于没有体现类型…….所以直接就转成python函数了,如果有了强转,或者类型不能自动提升该如何是好??
好吧我决定多做几个题看看wp再说
最后的结果是这样的
就是输入给远程程序的数据
题目中是unsigned char,根据上次南大校赛的一个错题,发现gdb调试时会出现无法解决的错误,程序读入char,pwntools一旦发出超过\x7f就会提升类型,不过这好像不是同一个问题
于是…试试echo -e | ./xxx
输出结果
3、CTF-3
z3脚本
1 | from z3 import * |
输出结果: