[HGAME 2023 week2]math

z3约束器

Z3约束器是一个由微软出品的开源约束求解器,它能够解决多种情况下的给定部分约束条件寻求一组满足条件的解的问题。以下是对Z3约束器的详细介绍:

一、基本概念

  • 定义:Z3是一个高性能的定理证明器,专门用于求解各种形式的约束问题。
  • 应用:广泛应用于软件验证、硬件验证、程序分析、约束求解、混合系统分析、安全性分析以及生物学(计算机分析)等领域。在CTF(Capture The Flag,夺旗赛)等信息安全竞赛中,Z3也常被用于解决密码题、二进制逆向、符号执行、Fuzzing模糊测试等问题。
  • 特点:Z3功能强大且易于使用,它内置了多种变量类型,包括整数、浮点数、位向量(BitVector)、数组等,能够覆盖常见的计算机数据结构。此外,Z3还提供了一个类似于Lisp的内置语言,但通常使用Python Binding进行操作会更为方便。

二、安装与使用

  • 安装:可以通过pip命令安装Z3约束器,即pip install z3-solver。或者从GitHub上下载Z3的源代码进行编译安装。

  • 使用:在Python中使用Z3约束器时,需要先导入z3库。然后可以声明变量、添加约束条件并求解。

    • 声明变量:可以使用Int(name)声明一个整数变量,使用BitVec(name, size)声明一个位向量变量。其中,name是变量的名字,size是位向量的大小(即2的幂次方表示的范围)。
    • 添加约束条件:使用solver.add(constraint)方法向求解器中添加约束条件。其中,solver是一个求解器对象,constraint是一个表示约束条件的表达式。
    • 求解:使用solver.check()方法检查是否存在满足所有约束条件的解。如果存在解,则可以使用solver.model()方法获取一个满足所有约束条件的解的模型

三、示例

# 导包
from z3 import *

# 整数型
a = Int('a')  # 定义一个整形 a,前面一个a是代表,括号里面的a是所求
b,c = Ints('b c') #定义多个整形
s = Solver()  # 生成一个约束求解器
s.add(a + b < 2)  # 添加约束条件 a+b<2
s.add(a >= 0,c > 0)  # 添加多个约束条件
if s.check() == sat:  # 检查约束求解器是否有解,如果有,返回sat; 如果不满足,返回unsat
    print(s.model())  # 输出结果


# 实数型
a = Real('a')  # 定义一个实数型 a,前面一个a是代表,括号里面的a是所求
b,c = Reals('b c') #定义多个实数型
s = Solver()  # 生成一个约束求解器
s.add(a + b < 2)  # 添加约束条件 a+b<2
s.add(a >= 0,c > 0)  # 添加多个约束条件
if s.check() == sat:  # 检查约束求解器是否有解,如果有,返回sat; 如果不满足,返回unsat
    print(s.model())  # 输出结果
# 布尔类型
p = Bool('p')
q = Bool('q')
r = Bool('r')
solve(Implies(p, q), r == Not(q), Or(Not(p), r))
#Implies(p, q):如果p为真,则q也为真。这是一个条件命题,通常写作p → q。
#r == Not(q):r等于q的非(即r是q的否命题)。这表示r和q的真假值相反。
#Or(Not(p), r):p的非或者r为真。这是一个析取命题,表示至少有一个子命题为真

#公式简化(公式化简):Simplify
x = Int('x')
y = Int('y')
print (simplify(x + y + 2*x + 3))
print (simplify(x < y + x + 2))
print (simplify(And(x + 1 >= 3, x**2 + x**2 + y**2 + 2 >= 5)))



[HGAME 2023 week2]math

查壳

无壳,用64位的ida打开,F5找到主函数

主要是这里经过运算后得到的数组与v12对比,这里涉及到了指针的偏移&savedregs-0x170的值刚好是v8的栈帧最高处

  • [rsp+10h]表示v8数组的地址相对于当前栈指针rsp偏移了16个字节(h表示十六进制,10h等于16十进制)。
  • [rbp-170h]表示v8数组的地址相对于基指针rbp向下的偏移量是272个字节

也就是说v8在这进行运算,数值要计算而且每一轮有五个比如‘num[0]*126+num[1]*253+num[2]*62 +num[3]*118 +num[4]*59,’

这五个要用z3来解

from z3 import *
v10 = [0] * 25
v12 = [0] * 25
v11 = [0] * 25
v10[0] = 126
v10[1] = 225
v10[2] = 62
v10[3] = 40
v10[4] = 216
v10[5] = 253
v10[6] = 20
v10[7] = 124
v10[8] = 232
v10[9] = 122
v10[10] = 62
v10[11] = 23
v10[12] = 100
v10[13] = 161
v10[14] = 36
v10[15] = 118
v10[16] = 21
v10[17] = 184
v10[18] = 26
v10[19] = 142
v10[20] = 59
v10[21] = 31
v10[22] = 186
v10[23] = 82
v10[24] = 79
v12[0] = 63998
v12[1] = 33111
v12[2] = 67762
v12[3] = 54789
v12[4] = 61979
v12[5] = 69619
v12[6] = 37190
v12[7] = 70162
v12[8] = 53110
v12[9] = 68678
v12[10] = 63339
v12[11] = 30687
v12[12] = 66494
v12[13] = 50936
v12[14] = 60810
v12[15] = 48784
v12[16] = 30188
v12[17] = 60104
v12[18] = 44599
v12[19] = 52265
v12[20] = 43048
v12[21] = 23660
v12[22] = 43850
v12[23] = 33646
v12[24] = 44270
s = Solver()
flag = [Real('num[%d]' % i) for i in range(32)]  # 定义实数型
print(flag)
for i in range(5):
    for j in range(5):
        for k in range(5):
            v11[5 * i + j] += flag[5 * i + k] * v10[5 * k + j]
for i in range(25):
    s.add(v11[i] == v12[i])   # 约束求解
if s.check() == sat:
    m = s.model()
print(m)
for i in range(32):
    print(chr(m.eval(flag[i]).as_long()), end='')  # 遍历值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值