知乎zse96算法 -- python实现

知乎 zse96 算法

记录第二次jsvmp扣算法。这里讨论任何关于逆向相关的技术,因为我不会。
至于算法的来源是根据网上的帖子,下日志断点,根据日志文件分析就得到了这个算法。

Python实现

因为这个算法对我没用,所以代码写的比叫垃圾。重在描述算法的流程

算法流程

直接从MD5之后的流程开始。

算法输入32位MD5字符串,最终输出64位字符串。

  1. 初始化输入和固定的值
md5_input = "4b168fd0a822f5ffcb49acb891be1ac5"
fixed_list = [48,53,57,48,53,51,102,55,100,49,53,101,48,49,100,55]
  1. 关键的一步是计算一个长度48的列表,下面是处理MD5字符串,和根据一个固定列表计算一个长度16列表,参与后面生成关键列表的参数。
# 前两位
phase_list = [int(random.random() * 127), 0]
# 中间32位
phase_list.extend([ord(i) for i in md5_input])
# 最后14位
phase_list.extend([14] * 14)
# 计算第二阶段列表
phase1_list = [fixed_list[i] ^ phase_list[i] ^ 42 for i in range(16)]
  1. 计算过程中JS的移位和Python略有不同
def left_shift(x, y):
    x,y = ctypes.c_int32(x).value,y % 32
    return ctypes.c_int32(x << y).value

def right_without_sign(num, bit=0) -> int:
    MAX32INT = 4294967295
    val = ctypes.c_uint32(num).value >> bit
    return (val + (MAX32INT + 1)) % (2 * (MAX32INT + 1)) - MAX32INT - 1
  1. 计算关键列表的前16位,这部分代码是从JS翻译来的有点乱
def B_func(e, t):
    temp = [left_shift((255 & e[t+i]), 8*(3-i)) for i in range(4)]
    return temp[0] | temp[1] | temp[2] | temp[3]

def Q_func(e, t):
    return left_shift((4294967295 & e), t) | right_without_sign(e, 32 - t)

def G_func(e):
    t = [255 & e >> 8*(3-i) for i in range(4)]
    # 固定数组 h.zb
    h_zb = [ 
        20, 223, 245, 7, 248, 2, 194, 209, 87, 6, 227, 253, 240, 128, 222, 91, 
        237, 9, 125, 157, 230, 93, 252, 205, 90, 79, 144, 199, 159, 197, 186, 
        167, 39, 37, 156, 198, 38, 42, 43, 168, 217, 153, 15, 103, 80, 189, 71, 
        191, 97, 84, 247, 95, 36, 69, 14, 35, 12, 171, 28, 114, 178, 148, 86, 
        182, 32, 83, 158, 109, 22, 255, 94, 238, 151, 85, 77, 124, 254, 18, 
        4, 26, 123, 176, 232, 193, 131, 172, 143, 142, 150, 30, 10, 146, 162, 
        62, 224, 218, 196, 229, 1, 192, 213, 27, 110, 56, 231, 180, 138, 107, 
        242, 187, 54, 120, 19, 44, 117, 228, 215, 203, 53, 239, 251, 127, 81, 
        11, 133, 96, 204, 132, 41, 115, 73, 55, 249, 147, 102, 48, 122, 145, 
        106, 118, 74, 190, 29, 16, 174, 5, 177, 129, 63, 113, 99, 31, 161, 76, 
        246, 34, 211, 13, 60, 68, 207, 160, 65, 111, 82, 165, 67, 169, 225, 57, 
        112, 244, 155, 51, 236, 200, 233, 58, 61, 47, 100, 137, 185, 64, 17, 70, 
        234, 163, 219, 108, 170, 166, 59, 149, 52, 105, 24, 212, 78, 173, 45, 0, 
        116, 226, 119, 136, 206, 135, 175, 195, 25, 92, 121, 208, 126, 139, 3, 75, 
        141, 21, 130, 98, 241, 40, 154, 66, 184, 49, 181, 46, 243, 88, 101, 183, 8, 
        23, 72, 188, 104, 179, 210, 134, 250, 201, 164, 89, 216, 202, 220, 50, 221, 
        152, 140, 33, 235, 214,
    ]
    n = [h_zb[255 & t[i]] for i in range(4)]
    r = B_func(n, 0)
    return r ^ Q_func(r, 2) ^ Q_func(r, 10) ^ Q_func(r, 18) ^ Q_func(r, 24)


def r_func(e):
    n = [B_func(e, i*4) for i in range(4)]
    # n.extend([0] * 32)
    h_zk = [ 
        1170614578, 1024848638, 1413669199, -343334464, 
        -766094290, -1373058082, -143119608, -297228157, 
        1933479194, -971186181, -406453910, 460404854, 
        -547427574, -1891326262, -1679095901, 2119585428, 
        -2029270069, 2035090028, -1521520070, -5587175, 
        -77751101, -2094365853, -1243052806, 1579901135, 
        1321810770, 456816404, -1391643889, -229302305, 
        330002838, -788960546, 363569021, -1947871109
    ]
    for r in range(32):
        o = G_func(n[r+1] ^ n[r+2] ^ n[r+3] ^ h_zk[r])
        n.append(n[r] ^ o)
    print(n)
    res = []
    for i in range(4):
        res.extend([255 & n[35-i] >> 8*(3-j) for j in range(4)])
    return res

上面是前16位计算相关的函数。critical_list = r_func(phase1_list))

  1. 关键列表后32位计算
def x_func(e, t):
    res = []
    temp = r_func([e[i] ^ t[i] for i in range(16)])
    res.extend(temp)
    temp = [e[16:][i] ^ temp[i] for i in range(16)]
    res.extend(r_func(temp))
    return res

x_func_param = [ord(i) for i in md5_input[14:]]
x_func_param.extend([14] * 14)

最终得到关键列表:critical_list.extend(x_func(x_func_param))

  1. 下一步是根据关键列表计算每组字符的大数数组。
xor_list = [0, 0, 0, 58] * 12
group_nums = [
    (critical_list[i] ^ xor_list[i]) << 16 | (critical_list[i+1] ^ xor_list[i+1]) << 8 | (critical_list[i+2] ^ xor_list[i+2])
    for i in range(0, 48, 3)
]
reversed(group_nums)
  1. 最后一步就是根据大数组装最后的结果
origin_str = "6fpLRqJO8M/c3jnYxFkUVC4ZIG12SiH=5v0mXDazWBTsuw7QetbKdoPyAl+hN9rgE"
x_zse_96 = ''
for num in group_nums:
    group_str = ''
    for i in range(4):
        str_index = right_without_sign(num, 6*i) & 63
        group_str += origin_str[str_index]
    x_zse_96 += group_str

print(x_zse_96)

结束

这个算法分析很简单适合新手入门。如有侵删,联系:1822908587@qq.com。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值