简单逆向29(pyc反编译,z3,unpack)

35 篇文章 5 订阅

诺莫29

pyc文件,先反编译成py文件:
方法见简单逆向27

# uncompyle6 version 3.7.4
# Python bytecode 2.7 (62211)
# Decompiled from: Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)]
# Embedded file name: E:\CTF\Geek-python\python2\python2.py
# Compiled at: 2019-10-22 19:40:16
import struct, time

def fun(start, end, s):
    a = 32310901
    b = 1729
    c = s
    m = end - start
    while True:
        d = int((a * c + b) % m)
        yield d
        c = d


arr = [
     77, 263, 394, 442, 463, 512, 667, 641, 804, 752, 885, 815, 1075, 1059, 1166, 1082, 1429, 1583, 1696, 1380,
     1987, 2263, 2128, 2277, 2387, 2670, 2692, 3255, 3116, 3306, 3132, 3659, 3139, 3422, 3600, 3584, 3343, 3546,
     3299, 3633, 3281, 3146, 2990, 2617, 2780, 2893, 2573, 2584, 2424, 2715, 2513, 2324, 2080, 2293, 2245, 2309,
     2036, 1944, 1931, 1817, 1483, 1372, 1087, 1221, 893, 785, 697, 586, 547, 324, 177, 184]#72 - 32 = 40
flag = raw_input('plz input your flag:')
length = len(flag) #40
a = struct.unpack('<I', flag[length - 4:].encode())[0] & 0XFF
b = []
c = fun(1, 255, a)
for i in range(32):
    b.append(next(c))

d = [ 0 for i in range(72) ]
for i in range(length):
    for j in range(32):
        a = ord(flag[i]) ^ b[j]
        d[(i + j)] += a

for i in range(len(d)):
    if d[i] != arr[i]:
        print 'fail'
        time.sleep(5)
        exit(0)

print 'success'
time.sleep(5)
exit(0)

是个很复杂的算法:
使用了迭代器,亦或,混淆
这种复杂的算法一般都没法直接写逆向算法。
可以使用z3库:见简单逆向10

算法里面的迭代器:yield

from z3 import *
import struct


def fun(start, end, s):
    a = 32310901
    b = 1729
    c = s
    m = end - start
    while True:
        d = int((a * c + b) % m)
        yield d
        c = d

arr = [
     77, 263, 394, 442, 463, 512, 667, 641, 804, 752, 885, 815, 1075, 1059, 1166, 1082, 1429, 1583, 1696, 1380,
     1987, 2263, 2128, 2277, 2387, 2670, 2692, 3255, 3116, 3306, 3132, 3659, 3139, 3422, 3600, 3584, 3343, 3546,
     3299, 3633, 3281, 3146, 2990, 2617, 2780, 2893, 2573, 2584, 2424, 2715, 2513, 2324, 2080, 2293, 2245, 2309,
     2036, 1944, 1931, 1817, 1483, 1372, 1087, 1221, 893, 785, 697, 586, 547, 324, 177, 184]#72 - 32 = 40

s = Solver()
B = [BitVec("x%s"%i,8) for i in range(41)]

length = 40
a = struct.unpack('<I', "xxx}".encode())[0] & 255 #因为有并运算,所以只需要最后一个字符正确也就是},前面xxx无论是什么,都不影响
b = []
c = fun(1, 255, a)
for i in range(32):
    b.append(next(c))

d = [ 0 for i in range(72) ]
for i in range(41):
    for j in range(32):
        a = B[i] ^ b[j]
        d[(i + j)] += a
for i in range(72):
    s.add(d[i] == arr[i])

print(s.check())
c = s.model()
print(c)

for i in range(41):
    print(c[B[i]], end = ',')
print()
r = [83,121,99,123,89,48,117,95,83,51,101,95,90,51,95,49,115,95,115,111,111,111,111,48,48,48,48,48,95,73,110,116,101,114,101,115,116,49,110,103,125]
flag = ""
for i in range(41):
    flag += chr(r[i])
print(flag)

在这里插入图片描述
这个地方开始没有看出前面三个没有影响,我想直接把变量容器里面的变量转为字符串放进去,结果失败,应该是不支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

I Am Rex

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值