PACTF_2017: ETA

Category: Points: 60 Description:

If this script were to finish, what would it output? MacOS Linux

Hint:

Try doing a bit of dynamic binary analysis. Read the registers!

Write-up

This challenge is much easier with a proper x64-86 decompiler like IDA or Hopper. The function we are looking at here, is the get_primes() function.

int _Z10get_primesm(long arg0) { var_38 = arg0; var_40 = rsi; rdi = var_38; rax = std::vector<unsigned long, std::allocator<unsigned long> >::vector(); var_20 = operator new[]((var_40 >> 0x3) + 0x1); rax = memset(var_20, 0xff, (var_40 >> 0x3) + 0x1); for (var_28 = 0x2; var_28 <= var_40; var_28 = var_28 + 0x1) { if ((SAR(sign_extend_64(*(int8_t *)(var_20 + (var_28 >> 0x3)) & 0xff), (var_28 & 0x7)) & 0x1) != 0x0) { rsi = var_28; rax = std::vector<unsigned long, std::allocator<unsigned long> >::push_back(var_38); for (var_18 = var_28 + var_28; var_18 <= var_40; var_18 = var_18 + var_28) { *(int8_t *)(var_20 + (var_18 >> 0x3)) = *(int8_t *)((var_18 >> 0x3) + var_20) & 0xff & !(0x1 << (var_18 & 0x7)); } } } if (var_20 != 0x0) { rax = operator delete[](var_20); } rax = var_38; rbx = stack[2046]; rsp = rsp + 0x48; rbp = stack[2047]; return rax; }

We need to look closer at the part of the pseudocode that will give us the solution.

for (var_28 = 0x2; var_28 <= var_40; var_28 = var_28 + 0x1) {

The base idea of this part of the code, refers to how it's actually looking for THE largest prime number that's smaller than var_40, which is 2147483644. With some clever searching, the largest prime number smaller than 2147483644 is, 2147483629.

Therefore, the flag is 2147483629.