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

Строки:

На этот раз что-то интересное. Перейду сразу к 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;
Ляпота:

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

Анализ 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}
Флаг получен

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))]();
}
Который и отвечает за вызов нужных функций из списка указателей на функции. А если ты все таки решишь разобрать код
