赞
踩
z3是一个微软出品的开源约束求解器,能够解决很多种情况下的给定部分约束条件寻求一组满足条件的解的问题。
安装:pip install z3-solver
from z3 import *
x = Int('x') #创建名为x的int类型变量
y = Int('y')
solve(x + y==10,2*x+4*y==32) #求解并输出结果
#[y = 6, x = 4]
添加约束条件
from z3 import *
a,b=Ints('a b')
s=Solver() #创建一个约束求解器
s.add(a+b==10) #添加约束条件
s.add(a+3*b==12)
if s.check()==sat: #有解
r=s.model() #求解
print(r) #[b = 1, a = 9]
print(r[a]) #9
print(r[b]) #1
精度设置,简化表达式
from z3 import *
x=Real('x')
y=simplify(3*x+1==2) #化简表达式
print(y) #x == 1/3
solve(y) #[x = 1/3]
set_option(rational_to_decimal=True) #实数结果以小数呈现,默认10位小数
solve(y) #[x = 0.3333333333?]
set_option(precision=30) #精度设为30位
solve(y) #[x = 0.333333333333333333333333333333?]
#有问号说明输出有精度限制
x, y = Reals('x y')
# 简化为单项式之和
t = simplify((x + y)**3, som=True)
print (t) #x*x*x + 3*x*x*y + 3*x*y*y + y*y*y
# 幂运算符简化
t = simplify(t, mul_to_power=True)
print (t) #x**3 + 3*x**2*y + 3*x*y**2 + y**3
快速添加变量
s=[Real('s%d' % i) for i in range(50)] #添加50个Real变量
s.add(s[18]*s[8]==5)
可见字符
s.add(x<127)
s.add(x>=32)
注意:
==
约束数据类型 | 格式 | 解释 |
---|---|---|
整数 | x=Int('x') | |
实数 | y=Real('y') | |
RealVal(1) | 实数1 | |
布尔 | b=Bool('b') | |
有理数 | Q(1,3) | 表示1/3 |
位向量 | x=BitVec('x',16) | 长度16位的变量x |
BitVecVal(10,32) | 大小为32的位向量,其值为10 | |
数组 | a=Array('a',IntSort(),IntSort()) | 索引为整数,值为整数 |
>> <<
== >= > !=
And() Or() Not()
Implies(P,Q) #蕴含式 p->Q,若P则Q
z=If(b,x,y) #b为真,则z=x,否则z=y
useZ3.bin
main函数
跟踪一下
a1,a2是Dword数组的地址,按Y改一波类型
from z3 import *
dword_602120=[0x0000007A, 0x000000CF, 0x0000008C, 0x00000095, 0x0000008E, 0x000000A8, 0x0000005F, 0x000000C9, 0x0000007A, 0x00000091, 0x00000088, 0x000000A7, 0x00000070, 0x000000C0, 0x0000007F, 0x00000089, 0x00000086, 0x00000093, 0x0000005F, 0x000000CF, 0x0000006E, 0x00000086, 0x00000085, 0x000000AD, 0x00000088, 0x000000D4, 0x000000A0, 0x000000A2, 0x00000098, 0x000000B3, 0x00000079, 0x000000C1, 0x0000007E, 0x0000007E, 0x00000077, 0x00000093]
dword_6021C0=[0x00000010, 0x00000008, 0x00000008, 0x0000000E, 0x00000006, 0x0000000B, 0x00000005, 0x00000017, 0x00000005, 0x0000000A, 0x0000000C, 0x00000017, 0x0000000E, 0x00000017, 0x00000013, 0x00000007, 0x00000008, 0x0000000A, 0x00000004, 0x0000000D, 0x00000016, 0x00000011, 0x0000000B, 0x00000016, 0x00000006, 0x0000000E, 0x00000002, 0x0000000B, 0x00000012, 0x00000009, 0x00000005, 0x00000008, 0x00000008, 0x0000000A, 0x00000010, 0x0000000D]
unk_602080=[0x00000008, 0x00000001, 0x00000007, 0x00000001, 0x00000001, 0x00000000, 0x00000004, 0x00000008, 0x00000001, 0x00000002, 0x00000003, 0x00000009, 0x00000003, 0x00000008, 0x00000006, 0x00000006, 0x00000004, 0x00000008, 0x00000003, 0x00000005, 0x00000007, 0x00000008, 0x00000008, 0x00000007, 0x00000000, 0x00000009, 0x00000000, 0x00000002, 0x00000003, 0x00000004, 0x00000002, 0x00000003, 0x00000002, 0x00000005, 0x00000004, 0x00000000]
s=Solver()
a1=[BitVec('%d' % i, 8) for i in range(36)] #8位位向量
ptr=[0]*36
v7=[0]*36
v8=[0]*36
v9=[0]*36
for i in range(36):
s.add(a1[i] <127) #添加约束条件①
s.add(a1[i] >=32)
for i in range(36):
ptr[i] = a1[i] >> 4
v7[i] = a1[i] & 15
for i in range(6):
for j in range(6):
for k in range(6):
v8[6*i+j] += ptr[6*i + k] * unk_602080[6*k+j]
for i in range(6):
for j in range(6):
v9[6*i+j]=v7[6*i+j]+unk_602080[6*i+j] #原函数识别一下数组
for i in range(36):
s.add(v8[i] == dword_602120[i])
s.add(v9[i] == dword_6021C0[i])
flag=[]
if s.check()==sat:
r=s.model()
for i in a1:
flag.append(r[i].as_long())#BitVecNumRef转长整型
print("".join(chr(x) for x in flag))
else:
print("无解")
#hgame{1_think_Matr1x_is_very_usef5l}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。