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
.