[BMZCTF20220101-reverse] checkin

有了第一题的经验就可以开始自己处理第2题了

这个不用处理就能反编译。

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v4[2]; // [esp+1Ah] [ebp-16Eh] BYREF
  _BYTE v5[34]; // [esp+1Ch] [ebp-16Ch] BYREF
  int v6; // [esp+3Eh] [ebp-14Ah]
  char Str[50]; // [esp+42h] [ebp-146h] BYREF
  int v8[26]; // [esp+74h] [ebp-114h] BYREF
  _DWORD v9[40]; // [esp+DCh] [ebp-ACh] BYREF
  int i; // [esp+17Ch] [ebp-Ch]

  __main();
  puts("Please input:");
  scanf("%s", Str);
  if ( strlen(Str) != 33
    || Str[0] != 102
    || Str[1] != 108
    || Str[2] != 97
    || Str[3] != 103
    || Str[4] != 123
    || Str[32] != 125 )
  {
    printf("you are wrong!!!");
    exit(0);
  }
  memset(v9, 0, sizeof(v9));
  v9[0] = 12864;
  v9[1] = 5522;
  v9[2] = 10710;
  v9[3] = 6924;
  v9[4] = 788;
  v9[5] = 10715;
  v9[6] = 10008;
  v9[7] = 13022;
  v9[8] = 15893;
  v9[9] = 9754;
  v9[10] = 7946;
  v9[11] = 7490;
  v9[12] = 5636;
  v9[13] = 13477;
  v9[14] = 2198;
  v9[15] = 5861;
  v9[16] = 5799;
  v9[17] = 5259;
  v9[18] = 6464;
  v9[19] = 6171;
  v9[20] = 2269;
  v9[21] = 9251;
  v9[22] = 8315;
  v9[23] = 2989;
  v9[24] = -199;
  v9[25] = 2680;
  LPL(Str, v8);
  for ( i = 0; i <= 25; ++i )
  {
    if ( v8[i] != v9[i] )
    {
      printf("try again!!!");
      exit(0);
    }
  }
  putchar(10);
  v6 = 0;
  memset(v5, 0, 4 * (((v4 - v5 + 40) & 0xFFFFFFFC) >> 2));
  v4[0] = 12;
  v4[1] = -93;
  v5[0] = -91;
  v5[1] = 120;
  v5[2] = 113;
  v5[3] = -75;
  v5[4] = 71;
  v5[5] = -86;
  v5[6] = 37;
  v5[7] = 69;
  v5[8] = 126;
  v5[9] = 42;
  v5[10] = 97;
  v5[11] = -6;
  v5[12] = -27;
  v5[13] = -44;
  v5[14] = -53;
  v5[15] = -18;
  v5[16] = 46;
  v5[17] = 120;
  v5[18] = -72;
  v5[19] = 124;
  v5[20] = 52;
  v5[21] = -53;
  v5[22] = 102;
  v5[23] = 29;
  v5[24] = 56;
  v5[25] = -26;
  v5[26] = -65;
  v5[27] = 98;
  v5[28] = 119;
  v5[29] = -81;
  v5[30] = 41;
  v5[31] = -18;
  v5[32] = 123;
  v5[33] = 59;
  LCK(v8, v4);
  putchar(10);
  system("PAUSE");
  return 0;
}

这里程序基本分3段

  1. 读入flag后查包裹,略过
  2. 作一个巨复杂的运行,每6字节一组,经过运算核对,都打算用sage了,可看了后边!!
  3. 当第2步运算结果v8和v9完全相同时检查第3项,那么就没必要从头开始了,因为v9==v8所以这个东西已经给了
  4. 第3步就是把flag还原打印出来
int __cdecl LCK(int *a1, char *a2)
{
  int j; // [esp+18h] [ebp-10h]
  int i; // [esp+1Ch] [ebp-Ch]

  puts("The final flag is:");
  printf("flag{");
  for ( i = 0; i <= 35; ++i )
    a2[i] ^= LOBYTE(a1[i % 26]);
  a2[23] = 102;
  for ( j = 0; j <= 35; ++j )
    putchar(a2[j]);
  return putchar(125);
}

用个省事的办法,直接复制

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int LCK(int *a1, char *a2)
{
  int j; // [esp+18h] [ebp-10h]
  int i; // [esp+1Ch] [ebp-Ch]

  puts("The final flag is:");
  printf("flag{");
  for ( i = 0; i <= 35; ++i )
    a2[i] ^= (char)(a1[i % 26]);
  a2[23] = 102;
  for ( j = 0; j <= 35; ++j )
    putchar(a2[j]);
  return putchar(125);
}

int main()
{
   int v9[40];
   int i,j,kk;
   char Str[50]; // [esp+42h] [ebp-146h] BYREF
   int v8[26]; // [esp+74h] [ebp-114h] BYREF
   char v4[2];
   char v5[34];
 
  v9[0] = 12864;
  v9[1] = 5522;
  v9[2] = 10710;
  v9[3] = 6924;
  v9[4] = 788;
  v9[5] = 10715;
  v9[6] = 10008;
  v9[7] = 13022;
  v9[8] = 15893;
  v9[9] = 9754;
  v9[10] = 7946;
  v9[11] = 7490;
  v9[12] = 5636;
  v9[13] = 13477;
  v9[14] = 2198;
  v9[15] = 5861;
  v9[16] = 5799;
  v9[17] = 5259;
  v9[18] = 6464;
  v9[19] = 6171;
  v9[20] = 2269;
  v9[21] = 9251;
  v9[22] = 8315;
  v9[23] = 2989;
  v9[24] = -199;
  v9[25] = 2680;
  
  v4[0] = 12;
  v4[1] = -93;
  v5[0] = -91;
  v5[1] = 120;
  v5[2] = 113;
  v5[3] = -75;
  v5[4] = 71;
  v5[5] = -86;
  v5[6] = 37;
  v5[7] = 69;
  v5[8] = 126;
  v5[9] = 42;
  v5[10] = 97;
  v5[11] = -6;
  v5[12] = -27;
  v5[13] = -44;
  v5[14] = -53;
  v5[15] = -18;
  v5[16] = 46;
  v5[17] = 120;
  v5[18] = -72;
  v5[19] = 124;
  v5[20] = 52;
  v5[21] = -53;
  v5[22] = 102;
  v5[23] = 29;
  v5[24] = 56;
  v5[25] = -26;
  v5[26] = -65;
  v5[27] = 98;
  v5[28] = 119;
  v5[29] = -81;
  v5[30] = 41;
  v5[31] = -18;
  v5[32] = 123;
  v5[33] = 59;
  
  LCK(v9, v4);
  return 0;
}
bmzctf2021$ ./a.out
The final flag is:
flag{L1sten_t0_the_s1lence_Of_extinct10n!}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值