记录一道题目[FlareOn6]Overlong
记录一道题目:[FlareOn6]Overlong
方法1
运行之后,只有一个MessageBox,显示I never break the encoding:
结合提示文本可以猜测应该是去解冒号后方的内容。
用IDA32打开,输出Messagebox位置:
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_7B1160(Text, (int)&unk_7B2008, 0x1Cu);
Text[v6] = 0;
MessageBoxA(0, Text, Caption, 0);
return 0;
}
unsigned int __cdecl sub_7B1160(char *a1, char *a2, unsigned int a3)
{
unsigned int i; // [esp+4h] [ebp-4h]
for ( i = 0; i < a3; ++i )
{
a2 += sub_7B1000((unsigned __int8 *)a1, a2);
if ( !*a1++ )
break;
}
return i;
}
发现&unk_7B2008
经过sub_7B1160
加密之后赋给Text并输出,但仅仅加密了a3也就是28位。结合“I never break the encoding”可知,应该是要完全复现剩余的算法将&unk_7B2008
的剩余内容加密出来。
写exp的时候要注意:a1,a2均是char型指针变量,指向enc数组和dec数组的当前位置。
exp:
#include<bits/stdc++.h>
#include<stdint.h>
using namespace std;
char a1[128];
unsigned char x[] =
{
0xE0, 0x81, 0x89, 0xC0, 0xA0, 0xC1, 0xAE, 0xE0, 0x81, 0xA5,
0xC1, 0xB6, 0xF0, 0x80, 0x81, 0xA5, 0xE0, 0x81, 0xB2, 0xF0,
0x80, 0x80, 0xA0, 0xE0, 0x81, 0xA2, 0x72, 0x6F, 0xC1, 0xAB,
0x65, 0xE0, 0x80, 0xA0, 0xE0, 0x81, 0xB4, 0xE0, 0x81, 0xA8,
0xC1, 0xA5, 0x20, 0xC1, 0xA5, 0xE0, 0x81, 0xAE, 0x63, 0xC1,
0xAF, 0xE0, 0x81, 0xA4, 0xF0, 0x80, 0x81, 0xA9, 0x6E, 0xC1,
0xA7, 0xC0, 0xBA, 0x20, 0x49, 0xF0, 0x80, 0x81, 0x9F, 0xC1,
0xA1, 0xC1, 0x9F, 0xC1, 0x8D, 0xE0, 0x81, 0x9F, 0xC1, 0xB4,
0xF0, 0x80, 0x81, 0x9F, 0xF0, 0x80, 0x81, 0xA8, 0xC1, 0x9F,
0xF0, 0x80, 0x81, 0xA5, 0xE0, 0x81, 0x9F, 0xC1, 0xA5, 0xE0,
0x81, 0x9F, 0xF0, 0x80, 0x81, 0xAE, 0xC1, 0x9F, 0xF0, 0x80,
0x81, 0x83, 0xC1, 0x9F, 0xE0, 0x81, 0xAF, 0xE0, 0x81, 0x9F,
0xC1, 0x84, 0x5F, 0xE0, 0x81, 0xA9, 0xF0, 0x80, 0x81, 0x9F,
0x6E, 0xE0, 0x81, 0x9F, 0xE0, 0x81, 0xA7, 0xE0, 0x81, 0x80,
0xF0, 0x80, 0x81, 0xA6, 0xF0, 0x80, 0x81, 0xAC, 0xE0, 0x81,
0xA1, 0xC1, 0xB2, 0xC1, 0xA5, 0xF0, 0x80, 0x80, 0xAD, 0xF0,
0x80, 0x81, 0xAF, 0x6E, 0xC0, 0xAE, 0xF0, 0x80, 0x81, 0xA3,
0x6F, 0xF0, 0x80, 0x81, 0xAD, 0x00
};
int sub_7B1000(unsigned char *a1,unsigned 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;
}
int main()
{
int start=0;
unsigned char txt[200];
unsigned char *a1=txt;
unsigned char *a2=x;//a1,a2定义位un char类型指针
for ( int i = 0;; ++i )
{
a2 += sub_7B1000(a1, a2);
if ( !*a1++ )
break;
}
// cout<<a1;
cout<<txt;
return 0;
}
//后半部分:I_a_M_t_h_e_e_n_C_o_D_i_n_g@flare-on.com
方法2
既然是加密的长度出了问题,其实我们只需要用winhex等工具patch一下将28(hex:1C)改掉就可以了。