python实现zse96算法
知乎 zse96 算法
记录第二次jsvmp扣算法。这里讨论任何关于逆向相关的技术,因为我不会。
至于算法的来源是根据网上的帖子,下日志断点,根据日志文件分析就得到了这个算法。
Python实现
因为这个算法对我没用,所以代码写的比叫垃圾。重在描述算法的流程
算法流程
直接从MD5之后的流程开始。
算法输入32位MD5字符串,最终输出64位字符串。
- 初始化输入和固定的值
md5_input = "4b168fd0a822f5ffcb49acb891be1ac5"
fixed_list = [48,53,57,48,53,51,102,55,100,49,53,101,48,49,100,55]
- 关键的一步是计算一个长度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)]
- 计算过程中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
- 计算关键列表的前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))
- 关键列表后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))
- 下一步是根据关键列表计算每组字符的大数数组。
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)
- 最后一步就是根据大数组装最后的结果
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。