下载附件是一个.pyc文件,在pyc在线反编译工具里反编译一下,代码如下:
`
print "Welcome to Re World!"
print "Your input1 is your flag~"
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num
for i in range(l - 1):
code[i] = code[i] ^ code[i + 1]
print code
code = [
"\x1f",
"\x12",
"\x1d",
"(",
"0",
"4",
"\x01",
"\x06",
"\x14",
"4",
",",
"\x1b",
"U",
"?",
"o",
"6",
"*",
":",
"\x01",
"D",
";",
"%",
"\x13",
]
`
这个代码直接copy是不能运行的,有的地方读起来很奇怪,需要连蒙带猜。
代码的结构是输入我的flag,flag经过两次变换生成了code。
`
code += num
`
第一个for结构里的第二条语句需要结合最终的code来看,code是一个有许多元素的列表,可以看出num是列表中带引号的ASCII码,所以这条语句的含义可以被猜出:将num放入code列表。
代码是先运算再异或得到结果,已知结果的情况下,应该先异或再逆运算。
由于异或运算的特殊性,A^B=C,B^C=A。原先的`code[i]^code[i+1]=code[i]=A`,那么已知变换后的code[i]也就是A的情况下,只需要将`code[i+1]^A`即可得到原先的code[i]。
不难看出,由于循环到l-1,所以code的最后一个元素是未经过change的。因此我们只需要从最后一位开始,逐次异或回来即可。代码写作:
`
for i in range(l-1):
code[l-i-2]=code[l-i-1]^code[l-i-2]
`
这也就是说,从倒数第二位开始,其本身和其后一位(也就是从倒数第一位开始)进行异或。
接着进行第二步逆运算。取模的逆运算我不会,而且感觉取模不能逆运算(。
既然让我逆,说明确实可逆。这里有运气成分(。)不知道怎么就想到了ASCII码,查了一下发现它只有128个数字。那么这个128保证的就是num在0-128的范围内。
`
num = ((input1[i] + i) % 128 + 128) % 128
`首先分析最外面的%128。已知:(A+B)%C=A%C+B%C是取模运算的法则(即使不知道的话,用(1+128)%128=129%128这样的数据测试一下也能猜到)
128%128=0,由于input1[i]+j先对128取模,此时(input1[i] + i) % 128已经是一个小于128的数字了,故再对其取模没意义,所以原式被化简为:(input1[i] + i) % 128
如果(input1[i] + i)整体小于128,那么这个取模相当于没有。所以我想知道的是整体大于128的情况要如何运算。所以我其实要探索的是(input1[i] + i) % 128的本质。假设input1[i]=126,i=5,先进行一个运算:
(input1[i] + i) % 128=(126+5)%128=(128+3)%128=3
我现在已知code列表,也就是各个num的值,也就是(input1[i] + i) % 128的结果。同时我也知道每个num所对应的i,一个未知数一个方程,input1[i]首先可以确定是可求的。
根据我上面假定数值的运算过程,很容易发现我想求input1[i]+5,只需要求n*128+3即可。那么n是多少呢?首先我的input1范围是0-127,i的范围是0-22,那么input1[i]+i显然小于150,也就是不可能超过128*2,那么n最大只能是1才能保证n*128+num小于150 。
所以input1[i]=128+num-i。但是这里又出现一个问题,也就是说,如果我的128+num-i大于128怎么办呢?我的flag是0-127的数值呀。所以我需要对它再进行一次取模:
`
(input1[i] +num- i) % 128
`
即为所求。
脚本如下:
`
code = [
"\x1f",
"\x12",
"\x1d",
"(",
"0",
"4",
"\x01",
"\x06",
"\x14",
"4",
",",
"\x1b",
"U",
"?",
"o",
"6",
"*",
":",
"\x01",
"D",
";",
"%",
"\x13",
]
input=[]
l = len(code)
for i in range(l - 1):
code[l-i-2]=chr(ord(code[l-i-2])^ord(code[l-i-1]))
for i in range(l):
code[i]=(ord(code[i])-i)%128
for i in range(l):
print(chr(code[i]),end="")
`