zoukankan      html  css  js  c++  java
  • z3学习档案

    Reference:

    看雪-z3巧解逆向

    知乎:Z3一把梭

    z3 solver学习

    使用z3约束求解器解决CTF中的题目

    Playing with Z3,hacking the serial check

    Z3 - 第一次簡單小練習

    安装

    pip install z3-solver

    使用方法

    >>> from z3 import *
    >>> x = Int('x')
    >>> y = Int('y')
    >>> a = Real('a')
    >>> b = Real('b')
    >>> c = Real('c')
    >>> d = Real('d')
    >>> s = Solver()
    >>> s.add(a + b == 12)
    >>> s.add(c - d == 9)
    >>> s.add(a + c == 22)
    >>> s.add(b + d == 12)
    >>> 
    >>> print(s.check())
    sat
    >>> print(s.model())
    [b = 11/2, a = 13/2, d = 13/2, c = 31/2]
    >>> p = Solver()
    >>> p.add(x + y == 1567856551)
    >>> p.add(x - y == 6535435)
    >>> p.check()
    sat
    >>> p.model()
    [x = 787195993, y = 780660558]

    可以使用'Int','Real','BitVec'等声明一个整数或实数变量,也可以申明一个变量数组,如

    knownarr = [IntVal(i) for i in encrypted]
    message = [Int('flag%d' % i) for i in range(len(encrypted)-1)]
    first = IntVector(‘a’, 4)

    后面都可以通过arrayname[id]进行访问

    Solver()创建求解器

    .add为变量之间增加约束条件

    .check()检查约束条件是否ok

    .model()列出求解结果

    实例

    ISCC2018 Reverse150

    验证函数为两个方程组,解第一个方程组获得种子,而后将字符串按照int进行解析,得到第二个方程组

    按照原逻辑声明变量,添加方程组约束条件即可

    Attention:

    > Int类型函数无法顺利表示过大的数,使用BitVec('x',64)可以声明在64bit之内的变量。

    > 使用ctypes库,可以调用c语言的函数等

    #!/usr/bin/env python
    # -*-coding=utf-8-*-
    from z3 import *
    import ctypes
    from pwn import *
    
    # context.log_level = 'debug'
    s = Int('s')
    s1 = Int('s1')
    s2 = Int('s2')
    s3 = Int('s3')
    
    ans = Solver()
    ans.add(s1 * s - s3 * s2 == 2652042832920173142)
    ans.add(3 * s2 + 4 * s3 - s1 - 2 * s == 397958918) 
    ans.add(3 * s *s3 - s2 * s1 ==  3345692380376715070)
    ans.add(27 * s1 + s - 11 * s3 - s2 ==  40179413815)
    
    if ans.check():
        result = ans.model()
        print result
    
    s3 = 862734414
    s2 = 829124174
    s1 = 1801073242
    s = 1869639009
    
    seed = s ^ s1 ^ s2 ^ s3
    dll = ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6")
    dll.srand(seed)
    v1 = dll.rand() % 50;
    v2 = dll.rand() % 50;
    v7 = dll.rand() % 50;
    v8 = dll.rand() % 50;
    v9 = dll.rand() % 50;
    v10 = dll.rand() % 50;
    v11 = dll.rand() % 50;
    v12 = dll.rand() % 50;
    
    v3 = BitVec('v3',64)
    v4 = BitVec('v4',64)
    v5 = BitVec('v5',64)
    v6 = BitVec('v6',64)
    
    res = Solver()
    res.add(v6 * v2 + v3 * v1 - v4 - v5 == 61799700179)
    res.add(v6 + v3 + v5 * v8 - v4 * v7 == 48753725643)
    res.add(v3 * v9 + v4 * v10 - v5 - v6 == 59322698861)
    res.add(v5 * v12 + v3 - v4 - v6 * v11 == 51664230587)
    # what's this fucking do?
    while res.check() == sat:
        print res.model()
        print '
    ---------------------'
        res.add(Or(res.model()[v3] != v3, res.model()[v4] != v4, res.model()[v5] != v5, res.model()[v6] != v6))
    
    v6 = 1195788129
    v4 = 828593230
    v3 = 811816014
    v5 = 1867395930
    io = process("./Reverse")
    payload = p32(s) + p32(s1) + p32(s2) + p32(s3)
    payload += p32(v3) + p32(v4) + p32(v5) + p32(v6)
    
    io.recvuntil('=
    =======================================
    ')
    io.sendline(payload)
    io.interactive()
    io.close()

     

    高阶用法

    loading..

  • 相关阅读:
    Celery
    高并发架构
    websocket
    git分支管理
    auto_ptr与shared_ptr
    UDP信号驱动IO
    TCP带外数据
    UDP广播
    获取mac地址
    char数组初始化
  • 原文地址:https://www.cnblogs.com/ZHijack/p/9001860.html
Copyright © 2011-2022 走看看