Buuctf - Universe_final_answer 1 之Z3求解器的代码

贴一份经典的Z3求解的代码

from z3 import *
s = Solver()
a1 = [0] * 32
for i in range(32):
    a1[i] = Int('a1['+str(i)+']')

s.add ( 1629056 * a1[0] == 166163712 )
s.add ( 6771600 * a1[1] == 731332800 )
s.add ( 3682944 * a1[2] == 357245568 )
s.add( 10431000 * a1[3] == 1074393000 )
s.add ( 3977328 * a1[4] == 489211344 )
s.add ( 5138336 * a1[5] == 518971936 )
s.add ( 7532250 * a1[7] == 406741500 )
s.add ( 5551632 * a1[8] == 294236496 )
s.add( 3409728 * a1[9] == 177305856 )
s.add( 13013670 * a1[10] == 650683500 )
s.add ( 6088797 * a1[11] == 298351053 )
s.add( 7884663 * a1[12] == 386348487 )
s.add ( 8944053 * a1[13] == 438258597 )
s.add ( 5198490 * a1[14] == 249527520 )
s.add ( 4544518 * a1[15] == 445362764 )
s.add ( 10115280 * a1[16] == 981182160 )
s.add( 3645600 * a1[17] == 174988800 )
s.add ( 9667504 * a1[18] == 493042704 )
s.add ( 5364450 * a1[19] == 257493600 )
s.add( 13464540 * a1[20] == 767478780 )
s.add( 5488432 * a1[21] == 312840624 )
s.add ( 14479500 * a1[22] == 1404511500 )
s.add ( 6451830 * a1[23] == 316139670 )
s.add ( 6252576 * a1[24] == 619005024 )
s.add ( 7763364 * a1[25] == 372641472 )
s.add ( 7327320 * a1[26] == 373693320 )
s.add ( 8741520 * a1[27] == 498266640 )
s.add ( 8871876 * a1[28] == 452465676 )
s.add ( 4086720 * a1[29] == 208422720 )
s.add ( 9374400 * a1[30] == 515592000 )
s.add (5759124 *a1[31] == 719890500)
s.check()
for i in range(32):
    print('a[' +str(i)+']'+'=',end = "")
    print(s.model()[a1[i]])

但此题代码有移位
使用 z3.LShR 函数时,参数必须是 Z3 的位向量表达式(Z3 bit-vector expression)。当前代码中,v6 和 v7 是 Int 类型,而不是 BitVec 类型,因此导致了 Z3Exception。

所以在设置类型时

a1[i] = BitVec('a1[' + str(i) + ']', 32)

贴修改后代码

from z3 import *

s = Solver()
a1 = [0] * 10
for i in range(10):
    a1[i] = BitVec('a1[' + str(i) + ']', 32)  # 使用 32 位整数

v1 = a1[1]
v2 = a1[0]
v3 = a1[2]
v4 = a1[3]
v5 = a1[4]
v6 = a1[6]
v7 = a1[5]
v8 = a1[7]
v9 = a1[8]
v11 = a1[9]

s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (LShR(v6, 6)) - 120 * v9 == -10283)
s.add(71 * v6 + (LShR(v7, 7)) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)

if s.check() == sat:
    m = s.model()
    for i in range(10):
        print('a1[' + str(i) + ']' + '=' , end="")
        print(m[a1[i]])
else:
    print("No solution")

可以对照一下修改前

from z3 import *

s = Solver()
a1 = [0] * 10
for i in range(10):
    a1[i] = Int('a1[' + str(i) + ']')

v1 = a1[1]
v2 = a1[0]
v3 = a1[2]
v4 = a1[3]
v5 = a1[4]
v6 = a1[6]
v7 = a1[5]
v8 = a1[7]
v9 = a1[8]
v11 = a1[9]

s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (LShR(v6, 6)) - 120 * v9 == -10283)
s.add(71 * v6 + (LShR(v7, 7)) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)

if s.check() == sat:
    m = s.model()
    for i in range(10):
        print('a1[' + str(i) + ']' + '=' , end="")
        print(m[a1[i]])
else:
    print("No solution")

当然LshR(v7,7)等于右移7位,即//128,整除128,但是Z3无整除应该改为Div

整数除法:在 Z3 中,ArithRef 类型不支持 // 运算符。需要使用 Div 函数来进行整数除法。
Div 函数:Div(v6, 64) 表示将 v6 整除 64,Div(v7, 128) 表示将 v7 整除 128。

此方法大家可以自行尝试

s.model()用于获取所有满足条件的解
s.model() 返回一个模型(model),该模型包含所有变量的赋值,这些赋值满足所有添加的约束条件。

。。。LshR是逻辑右移,这个题<<是左移,我说怎么一直输出错误
左移可以直接用 <<
无论Int类型还是Bitvec都可以
分别贴三份代码

Bitvecs设一组变量
from z3 import *

s = Solver()
v1,v2,v3,v4,v5,v6,v7,v8,v9,v11 = BitVecs('v1 v2 v3 v4 v5 v6 v7 v8 v9 v11',8)


s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - ((v6 << 6)) - 120 * v9 == -10283)
s.add(71 * v6 + ((v7 << 7)) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)

if s.check() == sat:
    print(s.model())
else:
    print("No solution")
Int类型并没有影响,代码如下
from z3 import *
 
s = Solver()
v1 = Int('v1')
v2 = Int('v2')
v3 = Int('v3')
v4 = Int('v4')
v5 = Int('v5')
v6 = Int('v6')
v7 = Int('v7')
v8 = Int('v8')
v9 = Int('v9')
v11 = Int('v11')
 
s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(
    30 * v11 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v11 + 120 * v8 + 108 * v7 + 48 * v4 + -89 * v3 + 78 * v1 - 41 * v2 + 31 * v5 - (
            v6 * 64) - 120 * v9 == -10283)
s.add(71 * v6 + (v7 * 128) + 99 * v5 + -111 * v3 + 85 * v1 + 79 * v2 - 30 * v4 - 119 * v8 + 48 * v9 - 16 * v11 == 22855)
s.add(5 * v11 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v11 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v11 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v11 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v11 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v11 + -28 * v9 + 5 * v8 + 93 * v6 + -18 * v7 + -127 * v5 + 6 * v4 + -9 * v3 + -93 * v1 + 58 * v2 == -1697)
 
if s.check() == sat:
    result = s.model()
 
print(result)
Bitvecs变量下 算术用左移也没影响
from z3 import *

m = BitVec('m',8)
v0,v1,v2,v3,v4,v5,v6,v7,v8,v9= BitVecs('v0 v1 v2 v3 v4 v5 v6 v7 v8 v9', 8)
s = Solver()#初始化一个Solver类
s.add(-85 * v8 + 58 * v7 + 97 * v6 + v5 + -45 * v4 + 84 * v3 + 95 * v0 - 20 * v1 + 12 * v2 == 12613)
s.add(30 * v9 + -70 * v8 + -122 * v6 + -81 * v5 + -66 * v4 + -115 * v3 + -41 * v2 + -86 * v1 - 15 * v0 - 30 * v7 == -54400)
s.add(-103 * v9 + 120 * v7 + 108 * v5 + 48 * v3 + -89 * v2 + 78 * v1 - 41 * v0 + 31 * v4 - (v6 << 6) - 120 * v8 == -10283)
s.add(71 * v6 + (v5 << 7) + 99 * v4 + -111 * v2 + 85 * v1 + 79 * v0 - 30 * v3 - 119 * v7 + 48 * v8 - 16 * v9 == 22855)
s.add(5 * v9 + 23 * v8 + 122 * v7 + -19 * v6 + 99 * v5 + -117 * v4 + -69 * v2 + 22 * v1 - 98 * v0 + 10 * v3 == -2944)
s.add(-54 * v9 + -23 * v7 + -82 * v2 + -85 * v0 + 124 * v1 - 11 * v3 - 8 * v4 - 60 * v5 + 95 * v6 + 100 * v8 == -2222)
s.add(-83 * v9 + -111 * v5 + -57 * v0 + 41 * v1 + 73 * v2 - 18 * v3 + 26 * v4 + 16 * v6 + 77 * v7 - 63 * v8 == -13258)
s.add(81 * v9 + -48 * v8 + 66 * v7 + -104 * v6 + -121 * v5 + 95 * v4 + 85 * v3 + 60 * v2 + -85 * v0 + 80 * v1 == -1559)
s.add(101 * v9 + -85 * v8 + 7 * v6 + 117 * v5 + -83 * v4 + -101 * v3 + 90 * v2 + -28 * v1 + 18 * v0 - v7 == 6308)
s.add(99 * v9 + -28 * v8 + 5 * v7 + 93 * v6 + -18 * v5 + -127 * v4 + 6 * v3 + -9 * v2 + -93 * v1 + 58 * v0 == -1697)
check = s.check()#检测是否有解(有解sat、无解unsat)
print(check)
model = s.model()#取出所有结果,一个ModelRef类,
print(model)

已老实,以后还是用Int变量
除非变量数目太多 Bitvecs直接设置一堆变量

但是我这样输出有个问题,还要一个一个去找他们的chr类型
好吧,找了下也没更简单的输出,自己写吧

a = [70, 48, 117,84,95, 121, 55, 119, 64]
for i in range(len(a)):
    print(chr(a[i]),end = "")

注意对照一下a1角标的顺序就行

会发现除了if()内
还对flag进行了一次加密,但加密函数太过复杂
后面代码显示能直接输出flag
文件拖入Linux中运行一下

老是False key
发现之前的a1看错了

应该是F0uRTy_7w@

运行之后得到flag

posted @ 2025-04-21 20:52  Bri1  阅读(36)  评论(0)    收藏  举报