## Special Device File (Reverse)
### Solution
This challenge is similar to [Special Instruction](./spins.md), but the binary is AArch64 ELF, thus we can use decompiler this time.
```cint __cdecl __noreturn main(int argc, const char **argv, const char **envp){  unsigned int fd; // w21 MAPDST  char *flag_buf; // x0  __int64 seed; // [xsp+28h] [xbp-8h]
  seed = 0x139408DCBBF7A44LL;  fd = _open("/dev/xorshift64", 1LL, 0LL);  _write();  _close(fd);  fd = _open("/dev/xorshift64", 0LL, 0LL);  flag_buf = decode(&flag, &randval, fd);  puts(1LL, flag_buf);  puts(1LL, "\n");  _close(fd);  exit(0LL);}
char *__fastcall decode(char *flag, char *key, unsigned int rng){  char *p; // x21  __int64 i; // x3
  if ( *flag )  {    p = flag;    i = 0LL;    do    {      *p ^= get_random_value(rng) ^ key[i];      ++i;      ++p    }    while ( flag[i] );  }  return flag;}```
It's pretty simple. In `main` it will open `/dev/xorshift64`, write something then close it, IDA didn't correctly infer the argument here, we can assume it writes `0x139408DCBBF7A44LL` to the device, which is the seed of the RNG.
And then, in the `decode` function, a global encrypted `flag`(`0x1800`) will perform XOR with `randval`(`0x1820`) and `get_random_value`. Simply extract these bytes and simulate the RNG, then we can decrypt the flag.
Again, I spent many time on finding the correct version of xorshift64, and finally found it on [Japanese Wikipedia](https://ja.wikipedia.org/wiki/Xorshift).
```python#!/usr/bin/env python3
seed = 0x139408DCBBF7A44mask = 0xFFFFFFFFFFFFFFFF
def get_rand():    global seed    seed ^= (seed << 13) & mask    seed ^= (seed >> 7) & mask    seed ^= (seed << 17) & mask    return seed
with open('runme', 'rb') as f:    f.seek(0x1800)    flag = f.read(0x20)    f.seek(0x1820)    randval = f.read(0x20)
for i in range(32):    r = get_rand()    print(chr((flag[i] ^ randval[i] ^ r) & 0xFF), end="")```
The flag is `SECCON{UseTheSpecialDeviceFile}`