异或(xor)的特性:A xor B = C,则 A xor C = B。常用于已知A和C,求flag B。
题目:在IDA里拿到一个列表['f',0Ah,'k',0Ch,'w&O.@',11h,'x',0Dh,'Z;U',11h,'p',19h,'F',1Fh,'v"M#D',0Eh,'g',6,'h',0Fh,'G2O',0]
注意IDA里的h表示十六进制,相当于python里的0x,所以先转成python下的列表:
['f',0x0A,'k',0x0C,'w&O.@',0x11,'x',0x0D,'Z;U',0x11,'p',0x19,'F',0x1F,'v"M#D',0x0E,'g',6,'h',0x0F,'G2O',0]
将列表里的int全都转成字符,再拼接起来得到字符串s:
for i in range(len(s)):
if(type(s[i])==int):
s[i] = chr(s[i])
s = ''.join(s)
由题干得知字符串s是A进行A[i] ^= A[i-1]得到的(^是异或运算符,即s[i]=新A[i]=A[i]^A[i-1]),且A[0]='f',则可利用异或特性对A进行还原:
flag = 'f'
for i in range(1,len(s)):
flag += chr(ord(s[i]) ^ ord(s[i-1]))
print(flag)
得到:flag{QianQiuWanDai_YiTongJiangHu}
下次再碰到这种逐位异或的处理,以其人之道还治其人之身就可以还原。下面详细展示一下原理:
s = 'abcd' # 假设原来的s是a,b,c,d
s1 = 'a'
for i in range(1,len(s)):
s = s.replace(s[i],chr(ord(s[i]) ^ ord(s[i-1])))
print(s) # 新的s是a,b^a,c^(b^a),d^(c^(b^a)),这玩意打印不出来无所谓
for i in range(1,len(s)):
s1 += chr(ord(s[i]) ^ ord(s[i-1])) # 以其人之道还治其人之身
print(s1) # 根据异或特性A^(x^A)=x,s1是a,b,c,d,打印出来确实是