[QCTF2018]babyre
搜索字符串定位到主函数,F5 发现和粑粑一样,只能看汇编分析
首先找到了一个 cmp,合理猜测输入长度为 32,继续看分支
并不是很长,但是看不懂在干啥,尝试动调看一下
输入 32 个字符,我这里输入了 abcdefghijklmnopqrstuvwxyz123456,函数暂且不用跟进去,看看能不能通过瞪眼法猜测函数做了些什么
首先看到sub_56025EA0D250 干的事情似乎是复制输入的字符串
接下来等到了 sub_56025EA082D0 函数时,发现字符串发生了变化
00007FAC7C21C060 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F 70 abcdefghijklmnop
00007FAC7C21C070 71 72 73 74 75 76 77 78 79 7A 31 32 33 34 35 36 qrstuvwxyz123456
00007FAC7C21C080 63 61 64 62 67 65 68 66 6B 69 6C 6A 6F 6D 70 6E cadbgehfkiljompn
00007FAC7C21C090 73 71 74 72 77 75 78 76 31 79 32 7A 35 33 36 34 sqtrwuxv1y2z5364
四个为一组进行一些移位,1->2,2->4,3->1,4->3
继续往下,来到第二个操作:sub_56025EA089C0
00007FAC7C21C080 63 61 64 62 67 65 68 66 6B 69 6C 6A 6F 6D 70 6E cadbgehfkiljompn
00007FAC7C21C090 73 71 74 72 77 75 78 76 31 79 32 7A 35 33 36 34 sqtrwuxv1y2z5364
00007FAC7C21C0A0 6A 73 BC E3 6E 77 C0 E7 72 7B C4 EB 76 7F C8 EF js......r{..v...
00007FAC7C21C0B0 7A 83 CC F3 7E 87 D0 F7 38 8B 8A FB 3C 45 8E B5 z...~...8...<E..
通过瞪眼法观察发现,依旧是每四个为一组,第 1~4 个数分别加上 7,18,88,129 得到新值
继续看第三个函数:sub_56025EA09300
00007F4F6FE1C080 53 DC 79 3E 73 DD 81 7E 93 DE 89 BE B3 DF 91 FE S..>s..~.މ ..ߑ .
00007F4F6FE1C090 D3 E0 99 3F F3 E1 A1 7F C1 E2 15 BF E1 51 1D 5B ...?...........[
00007F4F6FE1C0A0 6A 73 BC E3 6E 77 C0 E7 72 7B C4 EB 76 7F C8 EF js......r{..v...
00007F4F6FE1C0B0 7A 83 CC F3 7E 87 D0 F7 38 8B 8A FB 3C 45 8E B5 z...~...8...<E..
瞪眼瞪不出来了,尝试动调看一下,发现依旧是四个为一组,以操作的第一组为例,分别进行了如下操作:
- (0x7b>>2 | 0x7b<<6)
- (0xc4>>7 | 0xc4<<1)
- (0xeb>>4 | 0xeb<<4)
- (0x76>>5 | 0x76<<3)
而且可以看到第一个开始操作的数是 0x7b,有一个长度为 9 的偏移
所以如果是从第一个数开始的话,四个为一组,进行的操作应该是:
- (num1>>5 | num1<<3)
- (num2>>2 | num2<<6)
- (num3>>7 | num3<<1)
- (num4>>4 | num4<<4)
变换操作的函数就这些,继续往下走进入 sub_55D61C209F50,看到有一串数据
正好 32 个捏,大胆猜测这是最后要比较的数据,写个脚本试一试
#include <bits/stdc++.h>
using namespace std;
int a[] = {
0xDA, 0xD8, 0x3D, 0x4C, 0xE3, 0x63, 0x97, 0x3D,
0xC1, 0x91, 0x97, 0x0E, 0xE3, 0x5C, 0x8D, 0x7E,
0x5B, 0x91, 0x6F, 0xFE, 0xDB, 0xD0, 0x17, 0xFE,
0xD3, 0x21, 0x99, 0x4B, 0x73, 0xD0, 0xAB, 0xFE};
void work3() {
for (int i = 0; i < 32; i++) {
if (i % 4 == 0) a[i] = (a[i]>>3 | a[i]<<5);
else if (i % 4 == 1) a[i] = (a[i]>>6 | a[i]<<2);
else if (i % 4 == 2) a[i] = (a[i]>>1 | a[i]<<7);
else a[i] = (a[i]>>4 | a[i]<<4);
}
}
void work2() {
for (int i = 0; i < 32; i++) {
if (i % 4 == 0) a[i] -= 7;
else if (i % 4 == 1) a[i] -= 18;
else if (i % 4 == 2) a[i] -= 88;
else a[i] -= 129;
}
}
void work1() {
for (int i = 0; i < 8; i++) {
int num1, num2, num3, num4;
num1 = a[i * 4];
num2 = a[i * 4 + 1];
num3 = a[i * 4 + 2];
num4 = a[i * 4 + 3];
a[i * 4] = num2;
a[i * 4 + 1] = num4;
a[i * 4 + 2] = num1;
a[i * 4 + 3] = num3;
}
}
int main() {
work3(); work2(); work1();
for (int i = 0; i < 32; i++)
cout << (char)a[i];
return 0;
}
没问题,得到 flag
flag{Rus4_1s_fun4nd_1nt3r3st1ng}