[ACTF新生赛2020]Universe_final_answe
前话:该题目要用到Z3,先记录下Z3的用法,参考文章:传送门 传送门2
创建一个有解的声明对象
a = Solver()
添加条件
s.add()
判断是否有解
s.check() #如果有解 则反回sat 反之 返回 unsat
返回最后的解
result=s.modul()
print(result)
声明变量
整形(Int):
a, s, d = Ints(‘a s d’)
有理数(Real):
x = Real(‘x’)
y = Real(‘y’)
位向量(BitVec)用于移位运算:
x, y, z = BitVecs(‘x y z’, 8)
正文:
打开主函数,跟进到if中的函数里,第一次做的时候手贱,对着负数按h键,然后变不回来了,又重开了一次。。。
函数最底下返回result,而result=0,所以if条件都要符合,而v1 - v9完全就是输入的字符串,于是用Z3写脚本就可以
from z3 import *
s = Solver()
v1, v2, v3, v4, v5, v6, v7, v8, v9, v0 = Ints('v1 v2 v3 v4 v5 v6 v7 v8 v9 v0')
s.add(-85 * v9 + 58 * v8 + 97 * v6 + v7 + -45 * v5 + 84 * v4 + 95 * v2 - 20 * v1 + 12 * v3 == 12613)
s.add(30 * v0 + -70 * v9 + -122 * v6 + -81 * v7 + -66 * v5 + -115 * v4 + -41 * v3 + -86 * v1 - 15 * v2 - 30 * v8 == -54400)
s.add(-103 * v0 + 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 * v0 == 22855)
s.add(5 * v0 + 23 * v9 + 122 * v8 + -19 * v6 + 99 * v7 + -117 * v5 + -69 * v3 + 22 * v1 - 98 * v2 + 10 * v4 == -2944)
s.add(-54 * v0 + -23 * v8 + -82 * v3 + -85 * v2 + 124 * v1 - 11 * v4 - 8 * v5 - 60 * v7 + 95 * v6 + 100 * v9 == -2222)
s.add(-83 * v0 + -111 * v7 + -57 * v2 + 41 * v1 + 73 * v3 - 18 * v4 + 26 * v5 + 16 * v6 + 77 * v8 - 63 * v9 == -13258)
s.add(81 * v0 + -48 * v9 + 66 * v8 + -104 * v6 + -121 * v7 + 95 * v5 + 85 * v4 + 60 * v3 + -85 * v2 + 80 * v1 == -1559)
s.add(101 * v0 + -85 * v9 + 7 * v6 + 117 * v7 + -83 * v5 + -101 * v4 + 90 * v3 + -28 * v1 + 18 * v2 - v8 == 6308)
s.add(99 * v0 + -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)
输出了一个列表
然后转为字符串输出,这里要按照ida赋值的顺序输出:F0uRT_y7w@
在这里看出flag应该为两段组成,于是便想着去看看sub_C50,这个函数看的很难受,想着动态调试看看能不能拿到什么数值,结果当我输入第一段字符串的时候直接回显了整个flag。。
但想想那个printf函数的输出格式,又感觉确实没毛病