题目
做法
下载压缩包,解压,把解压后的文件拖进Exeinfo PE进行分析
(注:当我们进行附件解压时会出现MACOX文件夹 这个是属于mac端解压下来的垃圾文件,不必理会,你拖进Exeinfo PE也不会有什么信息给你)
64位,无壳
扔进IDA(64位),找到main,F5反编译
没有什么像flag这样的直接关键词,我们直接从上往下分析一下代码
上面都是一些无关痛痒的东西,简单会看懂就行,我们看到这里
for ( i = 1; i < 33; ++i )
v6[i] ^= v6[i - 1];
代码功能:
这段代码是一个 for 循环,其功能是对数组 v6 进行按位异或(XOR)操作。
具体步骤如下:
- 循环从索引 i = 1 开始,到 i < 33 结束。也就是说,循环会对数组 v6 中索引从 1 到 32 的元素进行处理。
- 在每次循环中,使用按位异或运算符 ^ 将当前元素 v6[i] 与前一个元素 v6[i - 1] 进行异或操作,然后将结果重新赋值给 v6[i]。
然后继续往下
if ( !strncmp(v6, global, 0x21uLL) )
printf("Success", v3);
比较数组 v6 和 global 的前 0x21uLL(十六进制,转换为十进制是 33)个字符。
若这前 33 个字符完全相同,就会输出 “Success”。
结合全文进行分析,v3=global,我们的输入内容存放地址为v6
即我们输入内容和v3相等,就返回"成功"
先提取v3(global)的值,点v3点不进去,我们双击global
再双击红框圈起的地方
按Shift+E导出数据
根据global的值,再结合上面的for循环,我们就可以编写一个异或脚本,反向推出这道题的flag
(输入一个值进行异或操作后,再对异或结果使用相同的密钥进行一次异或操作,得到的是最初输入的值,也就是我们原本输入的还没有进行过异或操作的值)
exp(一般我们写脚本都是用Python写的,可以自行下载PyCharm等进行编写)
list1 = [0x66, 0x0A, 0x6B, 0x0C, 0x77, 0x26, 0x4F, 0x2E, 0x40, 0x11,
0x78, 0x0D, 0x5A, 0x3B, 0x55, 0x11, 0x70, 0x19, 0x46, 0x1F,
0x76, 0x22, 0x4D, 0x23, 0x44, 0x0E, 0x67, 0x06, 0x68, 0x0F,
0x47, 0x32, 0x4F, 0x00]
flag = chr(list1[0]) #结果为f 因为异或不会处理数据中第一个的值,但它也是flag的一部分,保留
#chr的作用是将一个整数(代表 Unicode 码位)转换为对应的 Unicode 字符
#我们的flag通常不是数字,而是字符串形式,这样做的目的是构建出一个字符串形式的 flag,下同
#使用 for 循环从第二个元素开始进行异或操作
for i in range(1, len(list1)):
flag += chr(list1[i] ^ list1[i - 1]) #从输入的第二个数据开始,将其与前一位异或
print(flag)
运行,得出结果,去掉最后的0就是我们这道题的答案啦
更新
于2025.4.17