0x01. 进入环境,下载附件
题目给出了一个exe注册机文件,我们双击打开,如图: 输入的crack不对,则会提示错了。推测可能让去寻找正确的口令即可。
0x02. 问题分析
使用IDA打开文件进行分析,如图: 在左侧找到main函数,F5反编译,如图,发现没有任何思路,没有其他有价值的信息: 我们将代码转成字符串(shift+f12),如图: 双击请输入pass,跳转到对应的位置,如图: 涉及到的函数段为:sub_401890,双击到对应的函数,如图: 其次反编译查看反编译代码:
int __thiscall sub_401890(CWnd *this)
{
struct CString *v1;
CWnd *v2;
int v3;
int v5[26];
int i;
char *Str;
CWnd *v8;
v8 = this;
v1 = (CWnd *)((char *)this + 100);
v2 = CWnd::GetDlgItem(this, 1002);
CWnd::GetWindowTextA(v2, v1);
v3 = sub_401A30((char *)v8 + 100);
Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v3);
if ( !strlen(Str) )
return CWnd::MessageBoxA(v8, "请输入pass!", 0, 0);
for ( i = 0; Str[i]; ++i )
{
if ( Str[i] > '9' || Str[i] < '0' )
{
if ( Str[i] > 'z' || Str[i] < 'a' )
{
if ( Str[i] > 'Z' || Str[i] < 'A' )
sub_4017B0();
else
v5[i] = Str[i] - 29;
}
else
{
v5[i] = Str[i] - 87;
}
}
else
{
v5[i] = Str[i] - 48;
}
}
return sub_4017F0((int)v5);
}
基本的逻辑就是将输入的数据,经过一串的if处理,对每个字符进行变换,得到变换后的v5,送入函数sub_4017F0中进行后续操作。双击sub_4017F0函数查看内容,如下:
int __cdecl sub_4017F0(int a1)
{
int result;
char Str1[28];
int v3;
int v4;
v4 = 0;
v3 = 0;
while ( *(_DWORD *)(a1 + 4 * v4) < 62 && *(_DWORD *)(a1 + 4 * v4) >= 0 )
{
Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];
++v4;
}
Str1[v4] = 0;
if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )
result = sub_401770();
else
result = sub_4017B0();
return result;
}
a1为v5 数组的首地址。*(_DWORD *)(a1 + 4 * v4) 相当于是a1[v4]。因为这里是DWORD类型,也就是4个字节,每次循环+4,相当于是取数组的下一个元素。上述代码可以知道,要弹出pass,需要变换后的Str1和KanXueCTF2019JustForhappy相等。双击aAbcdefghiabcde可以查看到变量内容。 因此我们可以先求a1数组的内容:
src = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
dst = "KanXueCTF2019JustForhappy"
data = []
for i in dst:
data.append(src.index(i))
print(data)
输出后的data为:[19, 0, 27, 59, 44, 4, 11, 55, 14, 30, 28, 29, 37, 18, 44, 42, 43, 14, 38, 41, 7, 0, 39, 39, 48]
接着逆向处理if函数,还原值后再进行if判断:
flag = ''
for i in data:
tmp1, tmp2, tmp3 = i + 29, i + 87, i + 48
if 65 <= tmp1 <= 90:
flag += chr(tmp1)
elif 97 <= tmp2 <= 122:
flag += chr(tmp2)
elif 48 <= tmp3 <= 57:
flag += chr(tmp3)
print("flag{{{}}}".format(flag))
因此,最终答案为:flag{j0rXI4bTeustBiIGHeCF70DDM}
|