ida打开
没有发现main函数,可以从字符串入手,找到对应的函数。
点进一个字符串,两个都一样
ctrl+x找到所属函数
发现如下
找到调用此函数的函数
点进去
关于代码的解释
v4 = (CWnd *)((char *)this + 100);
v1 = CWnd::GetDlgItem(this, 1002); //这些系统函数一开始吓到我了,虽然系统函数一直不是什么考点,但还是认为这里会有和输入相关的东西,后来下载了API的chm文档查了一下作用,的确,后面的GetBuffer应该就是获取用户输入了,但只是获取而已,相当于scanf,知道即可,还是没什么考点
CWnd::GetWindowTextA(v1, v4);
v2 = sub_401A30((char *)v8 + 100);
Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v2);
if ( !strlen(Str) )
return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0); //弹框函数,这里犯下第一个错误,IDA双击进去的数据都是db类型的,而我们一开始看到的弹框显示的是中文,所以我们要改类型为dd类型才可以,不然就显示不了中文,所以&byte_4035DC跟踪进去后要用热键D改为dd类型再转字符。
for ( i = 0; Str[i]; ++i ) //把输入的字符串逐个判断条件并根据不同条件修改,
{
if ( Str[i] > 57 || Str[i] < 48 )
{
if ( Str[i] > 122 || Str[i] < 97 )
{
if ( Str[i] > 90 || Str[i] < 65 )
sub_4017B0(); //有一个不是弹框范围内就返回失败
else
v5[i] = Str[i] - 29; //范围在65~90中,输出结果在36~61中
}
else
{
v5[i] = Str[i] - 87; //范围在97~122中,输出结果在10~35中
}
}
else
{
v5[i] = Str[i] - 48; //范围在48~57中,输出结果在0~9中
}
}
return sub_4017F0((int)v5); //把修改后的数组结果作为参数赋给后面密文对照函数。
int __cdecl sub_4017F0(int a1)
{
int result; // eax
char Str1[28]; // [esp+D8h] [ebp-24h] BYREF
int v3; // [esp+F4h] [ebp-8h]
int v4; // [esp+F8h] [ebp-4h]
v4 = 0;
v3 = 0;
while ( *(int *)(a1 + 4 * v4) < 62 && *(int *)(a1 + 4 * v4) >= 0 )
{
Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)]; //aAbcdefghiabcde双击跟踪是abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'的62位长度字符串,也就不难解释while判断条件的<62了,这里还犯下第二,第三个错误,第二个错误是一开始没看出来这是个数组,*(_DWORD *)(a1 + 4 * v4)是取索引而已,a1是数组头地址,现在要知道带方括号的[]基本都是数组取字符! 第三个错误是这里*(_DWORD *)(a1 + 4 * v4)型我是真的搞不懂,明明a1是int型,还是数组头地址,它前面的(_DWORD *)把它又变成了uint32型地址,先不说这多此一举,关键是int型地址+1就是加4个字节啊!这里直接+4*v4,那不是一下就跳过4个a1数组元素了吗!关键是我调试IDA既然没有问题!!!好吧,只能认为是IDA分析出错了,
++v4;//可以看为 Str1[v4] = aAbcdefghiabcde【a1【v4】】
}
Str1[v4] = 0;
if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") ) //从字典中获取的字符与明文对比,符合就是flag
result = sub_401770();
else
result = sub_4017B0();
return result;
}
首先逆推出v5也就是a1这个数组
key1 = 'abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'
key2 = 'KanXueCTF2019JustForhappy'
s = []
for i in range(len(key2)):
for j in range(len(key1)):
if key2[i] == key1[j]:
s.append(j)
print(s)
然后根据第一个解释逆推写出第二个脚本
flag = ''
v5 = s
for i in v5:
if 0 <= i <= 9:
v5 = i + 48
elif 10 <= i <= 35:
v5 = i + 87
elif i >= 36:
v5 = i + 29
flag += chr(v5)
print(flag)
最终得到flag:flag{j0rXI4bTeustBiIGHeCF70DDM}