BUUCTF Reverse/[FlareOn6]Overlong
看文件信息,没有加壳且为32位程序
运行一下看看
用IDA32位打开
int __stdcall start(int a1, int a2, int a3, int a4)
{
CHAR Text[128]; // [esp+0h] [ebp-84h] BYREF
unsigned int v6; // [esp+80h] [ebp-4h]
v6 = sub_401160(Text, (int)&unk_402008, 28u);
Text[v6] = 0;
MessageBoxA(0, Text, Caption, 0);
return 0;
}
查看 &unk_402008,看到老长一串
继续跟进sub_401160
unsigned int __cdecl sub_401160(char *a1, int a2, unsigned int a3)
{
unsigned int i; // [esp+4h] [ebp-4h]
for ( i = 0; i < a3; ++i )
{
a2 += sub_401000(a1, (char *)a2);
if ( !*a1++ )
break;
}
return i;
}
跟进sub_401000
int __cdecl sub_401000(_BYTE *a1, char *a2)
{
int v3; // [esp+0h] [ebp-8h]
char v4; // [esp+4h] [ebp-4h]
if ( (int)(unsigned __int8)*a2 >> 3 == 30 )
{
v4 = a2[3] & 0x3F | ((a2[2] & 0x3F) << 6);
v3 = 4;
}
else if ( (int)(unsigned __int8)*a2 >> 4 == 14 )
{
v4 = a2[2] & 0x3F | ((a2[1] & 0x3F) << 6);
v3 = 3;
}
else if ( (int)(unsigned __int8)*a2 >> 5 == 6 )
{
v4 = a2[1] & 0x3F | ((*a2 & 0x1F) << 6);
v3 = 2;
}
else
{
v4 = *a2;
v3 = 1;
}
*a1 = v4;
return v3;
}
算法很简单,就是对那一长串的字符进行加密操作,然后根据加密的结果跳过1到4位下标,然后继续加密,一开始我还想写脚本,,,但是看到这么长一串,,,还是算了。。。
拿出Ollydebug神器,照着上面IDA反汇编出的代码,一个函数一个函数对就行,后面的函数不看都行
这里有push操作就是入栈,汇编语言里面一般入栈就是要传递参数,然后哦下面就调用了一个函数
对应了这个函数
v6 = sub_401160(Text, (int)&unk_402008, 28u);
push 0x1C ,刚好对应这个28u,就是限制输出的字符串长度
就是这个文本框里面输出的东东,字符串长度刚好为28
然后双击汇编,把这个数改大一些,比如说改成 0x7C
然后一直按F8运行就行,看到这里flag已经出来了,可以右键复制到剪贴板
得到: “I never broke the encoding: I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com”
flag : flag{I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com}