Введите «магическое число», и приложение выведет флаг.

Solution

Ввести магическое число. Это я люблю

IMG

Строки:

IMG

На этот раз что-то интересное. Перейду сразу к Flag{. Опа. printflag. Начну ее разбор:

Анализ printflag

Погнали:

  int32_t printflag()

  {
      void* gsbase;
      int32_t eax = *(uint32_t*)((char*)gsbase + 0x14);
      int32_t var_38;
      __builtin_strcpy(&var_38, "This is my string.Possible this is flag");
      size_t eax_1 = strlen(&var_38);
      int32_t var_78 = 0;
      int32_t (* var_70)() = function1;
      int32_t (* var_6c)() = function2;
      int32_t (* var_68)() = function3;
      int32_t (* var_64)() = function4;
      int32_t (* var_60)() = function5;
      int32_t (* var_5c)() = function6;
      int32_t (* var_58)() = function7;
      int32_t (* var_54)() = function8;
      int32_t (* var_50)() = function9;
      int32_t (* var_4c)() = function10;
      int32_t (* var_48)() = function11;
      int32_t (* var_44)() = function12;
      int32_t (* var_40)() = function13;
      int32_t (* var_3c)() = function14;
      printf("Flag{");
      
      for (int32_t i = 0; i < eax_1; i += 1)
      {
          uint32_t eax_4 = (uint32_t)*(uint8_t*)(i + &var_38);
          int32_t* edx_1;
          (uint16_t)edx_1 = (int16_t)(uint8_t)eax_4;
          int32_t edx_2;
          (uint16_t)edx_2 = (edx_1 * 0xffffff93) >> 8;
          int32_t ecx_1;
          (uint8_t)ecx_1 = (edx_2 + eax_4) >> 3;
          uint32_t edx_4;
          (uint8_t)edx_4 = (uint8_t)eax_4 >> 7;
          int32_t edx_6 = (ecx_1 - edx_4) * 2;
          (&var_70)[(int32_t)((uint8_t)eax_4 - ((char)(edx_6 << 3) - (uint8_t)edx_6))]();
      }
      
      puts("}");
      int32_t result = eax ^ *(uint32_t*)((char*)gsbase + 0x14);
      
      if (!result)
          return result;
      
      __stack_chk_fail();
      /* no return */
  }

Мда:

int32_t var_78 = 0;
      int32_t (* var_70)() = function1;
      int32_t (* var_6c)() = function2;
      int32_t (* var_68)() = function3;
      int32_t (* var_64)() = function4;
      int32_t (* var_60)() = function5;
      int32_t (* var_5c)() = function6;
      int32_t (* var_58)() = function7;
      int32_t (* var_54)() = function8;
      int32_t (* var_50)() = function9;
      int32_t (* var_4c)() = function10;
      int32_t (* var_48)() = function11;
      int32_t (* var_44)() = function12;
      int32_t (* var_40)() = function13;
      int32_t (* var_3c)() = function14;

Ляпота:

IMG

Разбирать это лень. Вот честно. Гляну main

IMG

Анализ main

Тут выглядит все гораздо проще:

  int32_t main(int32_t argc, char** argv, char** envp)
  {
      void* const __return_addr_1 = __return_addr;
      int32_t* var_c = &argc;
      char** argv_1 = argv;
      void* gsbase;
      int32_t eax_1 = *(uint32_t*)((char*)gsbase + 0x14);
      int32_t var_1c;
      __isoc99_scanf("%d", &var_1c);
      var_1c();
      
      if (eax_1 == *(uint32_t*)((char*)gsbase + 0x14))
          return 0xc;
      
      __stack_chk_fail();
      /* no return */
  }

Мы считываем число с клавиатуры, а далее запускаем функцию по адресу, который мы ввели. Так и сделаю.

Адрес нужной функции в памяти - 0x0804867f. Число мы вводим в десятичном представлении, поэтому переведу его: 134514303.

Запустим:

root@5270b5becd96:/rev# ./task4
134514303
Flag{17845845ca54538d65be4481b45578458455be6}

Флаг получен

IMG

Flag{17845845ca54538d65be4481b45578458455be6}

Как видите, не всегда нужно разбирать запутанные функции. По сути, вот тут у нас некий генератор последовательности:

      for (int32_t i = 0; i < len; i += 1)
      {
          uint32_t pos = (uint32_t)*(uint8_t*)(i + &flag);
          int32_t* edx_1;
          (uint16_t)edx_1 = (int16_t)(uint8_t)pos;
          int32_t edx_2;
          (uint16_t)edx_2 = (edx_1 * 0xffffff93) >> 8;
          int32_t ecx_1;
          (uint8_t)ecx_1 = (edx_2 + pos) >> 3;
          uint32_t edx_4;
          (uint8_t)edx_4 = (uint8_t)pos >> 7;
          int32_t edx_6 = (ecx_1 - edx_4) * 2;
          funcs_p[(int32_t)((uint8_t)pos - ((char)(edx_6 << 3) - (uint8_t)edx_6))]();
      }

Который и отвечает за вызов нужных функций из списка указателей на функции. А если ты все таки решишь разобрать код

IMG