嘉韦思杯一道简单的逆向题

Auth

An easy Windows re

Analysis

Run it and see what happened

直接运行后

1
2
3
4
5
6
7
8
9
10
11
12
13
14
            .
_|_ ROBOTIC AUTHENTICATION SYSTEM
/\/\ (. .) /
`||' |#|
||__.-"-"-.___
`---| . . |--.\
| : : | ,||,
`..-..' \/\/
|| ||
|| ||
|__|__|

Please enter the first Password:

可知这是一个命令行的算法分析题,用peid查壳后没壳,我们直接拖到ida进行下一步分析,shift+F12后找到之前出现的关键字符串后查找引用找到

1
2
3
4
5
if ( !strcmp(&Str1, Str2) )
{
puts("You passed level1!");
sub_4015EA(0);
}

在加上之前出现的strcpy(Str2, "r0b0RUlez!")我们直接输入**r0b0RUlez!**后出现

1
Please enter the second Password:

成功进入下一关,我们应该注意到这些字符串应该是程序在运行后生成的(在ida字符串中未找到,这题动态调试会更好一些,但鉴于本题不难,我们直接强行静态分析也不难)

这时候我很好奇之前函数为什么定义了那么多字符串,回去看看之前的puts(dword_40AD8C)就懂了,这串数已变,向上找找到了**sub_401500(0)**这函数。我们分析一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int __cdecl sub_401500(signed int a1)
{
int result; // eax@2
_BYTE *i; // [sp+1Ch] [bp-Ch]@3

if ( a1 > 9 )
{
for ( i = (_BYTE *)dword_40AD94; ; ++i )
{
result = dword_40ADA0;
if ( (unsigned int)i >= dword_40ADA0 )
break;
*i ^= 1u; //关键代码,将每位和1进行异或
}
}
else
{
result = sub_401500(a1 + 1);
}
return result;
}

就是这个函数把我们的字符串进行了加工,我们接着sub_4015EA这个函数走,发现它在

1
2
3
4
puts(dword_40AD90);
dword_40ADA8 = 0x401619;
__debugbreak();
result = 0;

跳转之前改变了dword_40ADA8这个值,我们通过它跳到了sub_40157F

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void __cdecl __noreturn sub_40157F(int a1)
{
char v1; // [sp+18h] [bp-20h]@2
int v2; // [sp+2Ch] [bp-Ch]@1

v2 = *(_DWORD *)(*(_DWORD *)(a1 + 4) + 184);
if ( v2 == dword_40ADA8 + 6 )
{
scanf("%20s", &v1);
if ( !sub_401547(&v1, (_BYTE *)dword_40AD98) )
puts(Str);
}
ExitProcess(0);
}

发现最后的函数为sub_401547

1
2
3
4
5
6
7
8
9
10
11
signed int __cdecl sub_401547(_BYTE *a1, _BYTE *a2)
{
while ( *a2 != 2 )
{
if ( *a1 != (*a2 ^ 2) )
return 1;
++a1;
++a2;
}
return 0;
}

输入字符串与u1nnf2lg和2的异或进行比对,最后两个字符串拼接即得flag:),本题不算难,找好跳转就能一步一步解决.