[BUUCTF-xor]
前言:
认识了简单的伪代码之后,要开始看复杂的了。
1.
在exeinfo中确认信息后,放入ida,找到main函数,f5查看伪代码
直接从网上扒来的图,因为我第一眼真的看不懂啊呜呜
逻辑具体是:首先判断我们的输入v6长度是否为33,不是就进入label_12,下面可以看到就是返回"Failed"。
然后i=1,v6[1]
代表从输入的第二位开始,^=
表示异或(即xor)。即把两个数据二进制化,对位相同则输出0,不同输出1,再以输出的二进制转换回来。
例子:5和3转为二进制分别为:0101 、0011,异或结果0110,转换为十进制的6,即5^3=6.
但是a^=b
是什么操作?应该是把异或好的数据赋值给a。
之后,比较v6
与global
,(33uLL我不明白什么意思,uLL应该是数据类型,unsiged Long Long,33应该就是长度吧,但不知道这里面为什么说的是前31位)
2.
跟进global,里面有一串存储数据aFKWOXZUPFVMDGH,再跟进
__cstring:0000000100000F6E aFKWOXZUPFVMDGH db 'f',0Ah ; DATA XREF: __data:_global↓o
__cstring:0000000100000F6E db 'k',0Ch,'w&O.@',11h,'x',0Dh,'Z;U',11h,'p',19h,'F',1Fh,'v"M#D',0Eh,'g'
__cstring:0000000100000F6E db 6,'h',0Fh,'G2O',0
既然知道了求得global的原理是异或,那么就反着来求出flag。异或反运算就是再异或一次。
0Ah
,0ch
这些其实是十六进制,其他为字符串。
于是写python脚本,第一位f是不变的,从第二位0Ah开始。
str1 = ['f', 0x0A, 'k', 0x0C, 'w', '&', 'O', '.', '@', 0x11, 'x', 0x0D, 'Z', ';', 'U', 0x11, 'p', 0x19, 'F', 0x1F, 'v',
'"', 'M', '#', 'D', 0x0E, 'g', 6, 'h', 0x0F, 'G', '2', 'O']
x = 'f'
for i in range(1, len(str1)):
if (isinstance(str1[i], str)):
if (isinstance(str1[i - 1], str)):
x += chr(ord(str1[i]) ^ ord(str1[i - 1]))
else:
x += chr(ord(str1[i]) ^ str1[i - 1])
else:
x += chr(str1[i] ^ ord(str1[i - 1]))
print(x)
首先把我们的数据输入,把16进制的数据写成python能识别的。查看第i位是不是字符串类型,不是就让第二位和第一位异或,输出加在x后面。
ord表示把字符串转化为十进制数字,因为ord()内只能是字符串类型,所以要先isinstance判断。
这个脚本其实有bug,连续两个数字就出错了。改正也很简单,最下面的else内改为
(代码网上找的,基于我这个菜编程能力稍微理解了一点)
if (isinstance(str1[i - 1], str)):
x += chr(str1[i] ^ ord(str1[i - 1]))
else:
x += chr(str1[i] ^ str1[i - 1])
3.
得出结果,flag{QianQiuWanDai_YiTongJiangHu},完事!