XCTF_asong_WP

确实恶心。
本题的整体逻辑是通过输入的字符串变换that_girl文件,再把变换的数据写入out文件。属于已知密文求明文。

整体逻辑是通过对that_girl文本文件进行词频分析。

  1. 将输入的字符串转换为对应词频数组v1。
  2. 对v1进行类似与a=b,b=c,c=a 的元素顺序交换,记为v2。
  3. 将整个v2视为一整个二进制流循环左移3位,记为v3。
  4. 将v3写入out文件

解密脚本如下:

#include <stdio.h>
#include<stdlib.h>
#include <windows.h>
#include<map>
using namespace std;
unsigned int sub_400936(char a1)
{
  unsigned int result; // rax

  result = (unsigned int)(a1 - 10);
  switch ( a1 )
  {
    case 10:
      result = (unsigned int)(a1 + 35);
      break;
    case 32:
    case 33:
    case 34:
      result = (unsigned int)(a1 + 10);
      break;
    case 39:
      result = (unsigned int)(a1 + 2);
      break;
    case 44:
      result = (unsigned int)(a1 - 4);
      break;
    case 46:
      result = (unsigned int)(a1 - 7);
      break;
    case 58:
    case 59:
      result = (unsigned int)(a1 - 21);
      break;
    case 63:
      result = (unsigned int)(a1 - 27);
      break;
    case 95:
      result = (unsigned int)(a1 - 49);
      break;
    default:
      if ( a1 <= 0x2F || a1 > 0x30 )
      {
        if ( a1 <= '@' || a1 > 'Z' )
        {
          if ( a1 > '`' && a1 <= 'z' )          // a-z
            result = (unsigned int)(a1 - 87);
        }
        else
        {
          result = (unsigned int)(a1 - 55);     // A-Z
        }
      }
      else
      {
        result = (unsigned int)(a1 - 48);       // 0
      }
      break;
  }
  return result;
}
char find_ch(int p , int* f)
{
  char ch = 'a';
  while(ch != 'z'+1)
  {
    if(f[sub_400936(ch)] == p)
      return ch;
    ch++;
  }
  if(f[sub_400936('_')] == p)
    return '_';
  if(f[sub_400936('\'')] == p)
    return '\'';
  return 0;
}                           //经观察发现文本文件只有这几个字符
unsigned char ida_chars[] =
{
  0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00,
  0x18, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00,
  0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
  0x12, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x08, 0x00,
  0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00,
  0x17, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x04, 0x00,
  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x00,
  0x13, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x14, 0x00,
  0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00,
  0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x24, 0x00,
  0x00, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
  0x1D, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x1F, 0x00,
  0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00,
  0x1A, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x23, 0x00,
  0x00, 0x00
};																//38

int main(int argc, char const *argv[])
{
	 unsigned char p[] ={0xec,0x29,0xe3,0x41,0xe1,0xf7,0xaa,0x1d,0x29,0xed,0x29,0x99,0x39,0xf3,0xb7,0xa9,0xe7,0xac,0x2b,0xb7,0xab,0x40,0x9f,0xa9,0x31,0x35,0x2c,0x29,0xef,0xa8,0x3d,0x4b,0xb0,0xe9,0xe1,0x68,0x7b,0x41};
    unsigned char s[38] = {0};
    int temp=p[37]&0x7;
    for(int i=0;i<38;i++)
    {
        s[i]=(temp<<5)|(p[i]>>3);
        temp=p[i]&0x7;
    }		//整体循环位移


////////////////////////////////////////////////
	int* dword_6020A0 = (int*)ida_chars;
  map<int,int>find_index;
  int i;
  for(i = 0 ; i < 38 ; i++)
  {
    find_index[dword_6020A0[i]] = i;
  }

  temp = s[1];
  i = 1;
  int j;
  for(j = 0 ; j < 37 ; j++)
  {
    s[i] = s[find_index[i]];
    i = find_index[i];
  }
  s[i] = temp;
//////////////////////////////////////////////////

  int* rate = (int*)malloc(1000*sizeof(int));   //词频数组
  memset(rate , 0 , 1000* sizeof(int));
  FILE* fd = fopen("that_girl" , "r");
  char ch;
  while((ch = fgetc(fd)) != EOF)
  {
    rate[sub_400936(ch)]++;
  }
/////////////////////////////////////////////////// a->10  z->35   _->46  '->41
for( i = 0 ; i < 38 ; i++)
{
  printf("%c",find_ch(s[i] , rate));
}

	return 0;
}

发布了25 篇原创文章 · 获赞 13 · 访问量 2977

猜你喜欢

转载自blog.csdn.net/qq_43445167/article/details/104140685