首先用Exeinfo PE打开文件查看信息
这是 linux 的 32位 ELF 文件 直接用ida32打开,直接进主函数查看伪代码(F5)
主函数比较简单,各自看一下其功能
第一个 setlocale() 是一个初始化函数,是 c++ 中的自有函数 不影响解题
第二个
int banner()
{
unsigned int v0; // eax
v0 = time(0);
srand(v0);
wprintf(&unk_80488B0);
rand();
return wprintf(&unk_8048960);
}
进入后查看后发现这个函数仅仅是用于输出两句话,没有实际作用
第三个函数
int prompt_authentication()
{
return wprintf(&unk_80489F8);
}
发现是输出以下的话:
please enter authentication details:
以上三个与解题无关,
关键函数为第四个
void authenticate()
{
wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch]
wchar_t *s2; // [esp+801Ch] [ebp-Ch]
s2 = decrypt(&s, &dword_8048A90);
if ( fgetws(ws, 0x2000, stdin) )
{
ws[wcslen(ws) - 1] = 0;
if ( !wcscmp(ws, s2) )
wprintf(&unk_8048B44);
else
wprintf(&unk_8048BA4);
}
free(s2);
}
查看代码,发现 decrypt 函数,百度中搜到这是一个解密函数,然后把解出的结果存到s2
先往后看
fgetws函数 是从指定的位置按行读取字符串的函数,结果存储在ws处,就是输入的信息
最后有一个 if 判断输出
ws和s2相等输出了 succes!
这是判断s2就是我们要得到的flag
我们就接着跟进decrypt函数,查看算法
wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
size_t v2; // eax
signed int v4; // [esp+1Ch] [ebp-1Ch]
signed int i; // [esp+20h] [ebp-18h]
signed int v6; // [esp+24h] [ebp-14h]
signed int v7; // [esp+28h] [ebp-10h]
wchar_t *dest; // [esp+2Ch] [ebp-Ch]
v6 = wcslen(s);
v7 = wcslen(a2);
v2 = wcslen(s);
dest = (wchar_t *)malloc(v2 + 1);
wcscpy(dest, s);
while ( v4 < v6 )
{
for ( i = 0; i < v7 && v4 < v6; ++i )
dest[v4++] -= a2[i];
}
return dest;
}
分析代码,传入的s和s2的长度,接着dest = s,再接着对dest处理后,返回出来就是s2的值
这时,我们只需要去找到传入的s和a2,编写脚本,即可得到flag
这是s
这是a2
由于字符串的结尾会以\0结尾,在数组后会多出4个0,删除后,就是我们要得到的值
#include <iostream>
using namespace std;
int main()
{
int i = 0, j = 0, k = 0;
int s[] =
{
58, 20, 0, 0, 54, 20, 0, 0, 55, 20, 0, 0,
59, 20, 0, 0, 128, 20, 0, 0, 122, 20, 0, 0,
113, 20, 0, 0, 120, 20, 0, 0, 99, 20, 0, 0,
102, 20, 0, 0, 115, 20, 0, 0, 103, 20, 0, 0,
98, 20, 0, 0, 101, 20, 0, 0, 115, 20, 0, 0,
96, 20, 0, 0, 107, 20, 0, 0, 113, 20, 0, 0,
120, 20, 0, 0, 106, 20, 0, 0, 115, 20, 0, 0,
112, 20, 0, 0, 100, 20, 0, 0, 120, 20, 0, 0,
110, 20, 0, 0, 112, 20, 0, 0, 112, 20, 0, 0,
100, 20, 0, 0, 112, 20, 0, 0, 100, 20, 0, 0,
110, 20, 0, 0, 123, 20, 0, 0, 118, 20, 0, 0,
120, 20, 0, 0, 106, 20, 0, 0, 115, 20, 0, 0,
123, 20, 0, 0, 128, 20, 0, 0,
};
int a2[] =
{
1, 20, 0, 0, 2, 20, 0, 0, 3, 20,0, 0,
4, 20, 0, 0, 5, 20, 0, 0,
};
while (i < 152)
{
k = s[i++] - a2[j++ % 20];
if (k > 32)
cout << (char)k;
}
return 0;
}
得到flag为