声明
本文章中所有内容仅供学习交流使用,不用于其他任何目的,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!若有侵权,请联系公众号【逆不逆】删除。
前言
本来想水一期ks的__NS_hxfalcon,然后看到某书的xs更新到了4.3.1,那就先水一期xs吧。
流程分析
根据惯例,依旧是在window.mnsv2对应的vmp的for循环的第一个else进行断点

依旧是从后往前看日志,可以看到现在的数组变成了144位,之前4.2.6是124位,4.2.9是135位

144位数组由124位 + 20位组成,而20位的数组由4位 + 16位组成,这个4位数组其实就是 len('a3') + 'a3' + 后面那段数组的长度16。

跟之前一样,这个16位数组是由另一个数组异或124位数组中用到的随机数的第一个字节得到的

然后就是继续往山找这个215开头的16位数组生成的位置。
可以看到一个24位数组,然后是一个_0xfca8c3方法,然后就出现了16位数组,那么大概率这个16位数组就是有_0xfca8c3方法生成的,入参很可能就是这个24位数组

24位数组的来源,跟之前4.2.9一样,时间戳 + md5(api)

那么我们进入_0xfca8c3方法,没错,又是一个vmp,继续根据惯例在这个巨大的for循环里打上断点(ps: 当你的断点没生效时,可能是此时的vmp已经变了,根据日志重新进入新的vmp中)。
我们继续看日志,跟过之前md5的方案的同学应该不陌生,将一个无符号整数变成4个字节,同理可以找到另外3个无符号整数。

继续往上看日志我们可以发现,跟之前的md5方案有很大区别,没看到之前的SV那些64位的数组,而且运算步骤也不是很明确,不过"IV"还是能看到的。

另外build_block也能看到,我们将24字节的输入传入md5的build_block,得到一个6位或者8位数组
def build_block(data: list[int]) -> list[int]:
buf = data[:] + [0] * (32 - len(data))
out = []
for i in range(0, 32, 4):
v = (
buf[i]
| (buf[i + 1] << 8)
| (buf[i + 2] << 16)
| (buf[i + 3] << 24)
)
out.append(to_int32(v))
return out
data = [106, 139, 80, 33, 156, 1, 0, 0, 108, 177, 103, 186, 135, 225, 167, 86, 66, 13, 145, 111, 194, 52, 128, 60]
print(build_block(data))
# [558926698, 412, -1167609492, 1453842823, 1871777090, 1015035074, 0, 0]
在日志中对应的位置就是

接下来看一下558926698是怎么被使用的。似乎参与了两次运算,但是具体的运算流程完全看不出来

那么我们就需要去看0x1b这些指令到底做了什么
0x1b是加法

0x3d为异或

0x1c

0xa

可以发现参与运算的值基本是_0x47fda0[_0x4cd76e]和_0x47fda0[_0x4cd76e--],
那么我们是不是可以在日志中输出这两个值?在此时进行指令判断,输出运算符和运算结果也是可以的,而且更有助于后续的分析,这里就不演示了(因为懒)。

日就是触发断点,看日志
a = left_rotate(((a + M[0]) ^ c) & 0xFFFFFFFF, 7)

b = left_rotate(((b ^ M[0]) + d) & 0xFFFFFFFF, 11)

同理可以分析出c、d的计算方式,三轮计算后的abcd分别如下

可以发现最终生成16字节数组的abcd并不是这4个,说明中间还有其他运算步骤




这里推荐先对最终的a进行分析,这里以另一份日志为例,此时最终的a=1430864007



bcd三个也可以根据日志分析还原出来,值此,这篇水文就这样结束了(ps: 不会AST的日志好痛苦)



377

被折叠的 条评论
为什么被折叠?



