【另一种smc】【对于time()与rand的一种处理方法】【buu】[网鼎杯 2020 青龙组]jocker


这次的smc不同于之前的那道,这次的smc是有名字的和一定特征解smc函数的

而不是想上次要在一个大段中寻找插入的函数


查壳无壳32,ida

main

这个栈平衡不会影响程序调试,先不管它

这里的encrypt跟进后是没有伪代码而只有汇编代码,而且汇编代码也是非常的匪夷所思,

但是下面有个186次循环是来解它的变成正确的函数的smc

所以这个题是要动调

回到main在for循环打个断点

由于v7要等于24,所以输入一个长度为24的字符串

然后会在for循环处停下

Destination是把输入的字符串未经处理复制过去


切到汇编界面smc

这个地方就是smc

进行完循环后会停在左面的块中,这时停下,去解密encrypt与finally

注意找好硬编码 55 89 ,这里会有两端函数,encrypt下面就是finally

这里要解密2个函数


然后进入encrypt

enc

这里是要要让输入的字符和buffer进行异或等于403040

写个脚本:

1
2
3
4
5
6
7
str = 'hahahaha_do_you_find_me?'

v21 = [14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
for j in range(19):
v21[j] ^= ord(str[j])
print(chr(v21[j]))

运行后发现flag还少一部分


回到main跟进finally

finally

这里有个获取当时时间和伪随机的复制

这个if会有点匪夷所思,不过根据encrypt可知这也可能是要异或

问gpt是说这里if中的 != 判断可以视为异或,

也就是说 v3 ^ a1 = v4

不过我们并不知道这个异或的值

因此我们需要进行一个逆运算操作来求:

1
2
3
4
5
6
7
8
str = 'hahahaha_do_you_find_me?'

str1 = [0X25,0X74,0X70,0X26,0X3A]
xor = 0X3A ^ ord('}')//来求异或的值
for i in range(5):
str1[i] ^= xor
print(chr(str1[i]))

这样求出了剩下的flag