记录一道题目[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)改掉就可以了。

posted @ 2024-11-03 17:24  brs7  阅读(4)  评论(0编辑  收藏  举报