BUUCTF SimpleRev

题目:BUUCTF SimpleRev


查壳,没壳,64位
ida打开一通分析

main():

while ( 1 )
  {
    while ( 1 )
    {
      printf("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: ");
      v4 = getchar();
      if ( v4 != 100 && v4 != 68 )// d/D
        break;                                  
      Decry();
    }
    if ( v4 == 113 || v4 == 81 )// q/Q
      Exit("Welcome to CTF game!\nPlease input d/D to start or input q/Q to quit this program: ", argv);
    puts("Input fault format!");
    v3 = getchar();
    putchar(v3);
  }

很好懂,主要看Decry

Decry():

v11 = __readfsqword(0x28u);
  *(_QWORD *)src = 'SLCDN';
  v7 = 0LL;
  v8 = 0;
  v9[0] = 'wodah';
  v9[1] = '\0';
  v10 = 0;
  text = join(key3, (const char *)v9);          // text = key3 + v9
  strcpy(key, key1);
  strcat(key, src);                             // key = key1 + src
  input_not_return_cnt = 0;
  key_p = 0;
  getchar();
  key_len = strlen(key);
  for ( i = 0; i < key_len; ++i )
  {
    if ( key[key_p % key_len] > 64 && key[key_p % key_len] <= 90 )// key 大写字母->小写 
      key[i] = key[key_p % key_len] + 32;
    ++key_p;
  }
  printf("Please input your flag:");
  while ( 1 )                                   // 此时key_p = key_len
  {
    input = getchar();
    if ( input == 10 )                          // 换行
      break;
    if ( input == 32 )                          // 空格
    {
      ++input_not_return_cnt;
    }
    else
    {
      if ( input <= 96 || input > 122 )
      {
        if ( input > 64 && input <= 90 )        // 大写字母
        {
          str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97;
          ++key_p;
        }
      }
      else                                      // 小写字母
      {
        str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97;
        ++key_p;
      }
      if ( !(key_p % key_len) )
        putchar(32);                            // v3是key长度的倍数时输出空格
      ++input_not_return_cnt;
    }

key1和key3双击找到
在这里插入图片描述
在这里插入图片描述
v9和src显示的是整形,右键选择char得到字符串,需要翻转一下,可能是大端小端的问题,卡了我很久()

可以看到加密算法与位置有关,不好分析,但可能的选择很少,只有大小写字母,于是枚举

#include 
#include 
#include 
using namespace std;


string text = "killshadow";
string key = "adsfkndcls";
char str2[104];
char input;

int input_not_return_cnt = 0;
int key_len = key.size();
int key_p = key_len;

void trans()
{
	while ( 1 )                                   // 此时key_p = key_len
	  {
	    input = getchar();
	    if ( input == 10 )                          // 换行
	      break;
	    if ( input == 32 )                          // 空格
	    {
	      ++input_not_return_cnt;
	    }
	    else
	    {
	      if ( input <= 96 || input > 122 )
	      {
	        if ( input > 64 && input <= 90 )        // 大写字母
	        {
	          str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97;
	          ++key_p;
	        }
	      }
	      else                                      // 小写字母
	      {
	        str2[input_not_return_cnt] = (input - 39 - key[key_p % key_len] + 97) % 26 + 97;
	        ++key_p;
	      }
	      if ( !(key_p % key_len) )
	        putchar(32);                            // v3是key长度的倍数时输出空格
	      ++input_not_return_cnt;
	    }
	  }
	cout << "#"<< str2 << "#" << endl;
}

int main()
{
	for (int i = 0; i < 10; i++)
	{
//		for (int j = 0; j < 27; j++)
//		{
//			char put = 'a' + j;
//			if (text[i] == (put - 39 - key[i % key_len] + 97) % 26 + 97)
//			{
//				cout << put;
//				break;
//			}
//		} 
		for (int j = 0; j < 27; j++)
		{
			char put = 'A' + j;
			if (text[i] == (put - 39 - key[i % key_len] + 97) % 26 + 97)
			{
				cout << put;
				break;
			}
		}
	}
	
	//trans();
	
  	return 0;
} 

虽然输入允许空格,但加空格会变复杂,我选择先不加看看能不能出(

写了大小写两块,发现都有合法的,不知道是不是我哪里看漏了

efxkwoxzti
KLDQCUDFZO

但是只有大写是正确的flag

你可能感兴趣的:(reverse,CTF,逆向工程)