Rating: 4.0

given an executable binary, description suggested to run it on AmigaOS... and hell, after running it, I was like "damn, damn, and damn!!!!! trolls!", because setting up an emulator was challenging for me... (maybe it should've not been, but for me it was)

it was a 68k (some variants) architecture, made for amiga, but... it had nothing to do with **running** it!

after learning 68k arch, I went for static analysis, used IDA since it supported the arch, read the code, and following is *sort of* what I found about it:
```
#include <stdio.h>
#include <string.h>

char enc_chx[] =
{ 0x8B
, 0x84
, 0x9A
, 0x9B
, 0x9A
, 0xB1
, 0xD6
, 0xAF
, 0x93
, 0xB2
, 0x81
, 0x8C
, 0x84
, 0xAB
, 0x9D
, 0x9C
, 0x8E
, 0xB9
, 0xB0
, 0xD9
, 0xA8
, 0xA4
, 0x9C
, 0x81
, 0x85
, 0xA0
, 0xA6
, 0xB4
, 0x87
, 0x9A
, 0xBB
, 0x92
, 0x96
, 0xAD
, 0x8C
, 0xD7
, 0xB0
, 0x8D
, 0x97
};

char enc_idx[] =
{
0x16
, 0xC
, 0x24
, 0x17
, 0x13
, 0x19
, 0x7
, 0x9
, 0xE
, 0x23
, 0x5
, 0x1
, 0x18
, 0x21
, 0xD
, 0x10
, 0x12
, 0x1F
, 0x1A
, 0x1E
, 0x22
, 0x0
, 0xF
, 0xB
, 0x8
, 0x15
, 0x11
, 0x2
, 0x1D
, 0x1C
, 0x26
, 0x3
, 0x4
, 0x25
, 0x14
, 0x20
, 0x6
, 0x1B
, 0xA
};

void retry_flag() {
int var_1, var_2;
int var_7, var_8;

for (int i=0; i < 31; i++) {
var_7 = rand() % 26; // called some func I didn't understand, but it was about modulo
var_8 = rand() % 26; // dunno... :/

var_1 = enc_idx[var_7];
var_2 = enc_chx[var_7];

enc_idx[var_7] = enc_idx[var_8];
enc_chx[var_7] = enc_chx[var_8];

enc_idx[var_8] = var_1;
enc_chx[var_8] = var_2;
}
}

int check_flag() {
char var_1;

var_1 = enc_idx[0];
if (var_1 & 1 != 0)
return 0;

for (int i=2; i < 39; i += 2) {
if (enc_idx[i] < var_1)
return 0;

var_1 = enc_idx[i];

if (var_1 & 1 != 0)
return 0;
}

var_1 = enc_idx[1];
if (var_1 & 1 == 0)
return 0;

for (int i=3; i < 39; i += 2) {
if (enc_idx[i] > var_1)
return 0;

var_1 = enc_idx[i];

if (var_1 & 1 == 0)
return 0;
}

return 1;
}

void decrypt_flag(char* dest) {
char flag[0x64] = {0}; // uses bzero to do it

for (int i=0; i < 39; i++) {
flag[i] = (~enc_chx[i]) ^ i;
}

strcpy(dest, flag);
}
```

it was something like that ^, not so accurate, but enough I assume...

the `main` function didn't do much, just setting up the GUI, timer driver(??), looping after when a button is called to update a gui text element to "calculating the flag...", calling `check_flag`, if it returned 1 then calls `decrypt_flag` and shows the result, otherwise just calls the `retry_flag` and loops...

at this point I just patched the binary as to `check_flag` would return 1 immidately... and of course it didn't work as, later I found, `enc_ch` wasn't ordered well...

let's start with the `check_flag`. it checks odd indexes and the even indexes... and it would be better if I had renamed `var_1` to `last`, since each time in the loop, it checks if the last two times last index (index i-2) is lower than current for odd indexes and greater for even indexes... and also checks if odd indexes hold odd numbers, and even indexes hold even numbers...

so... even indexes should hold even numbers in descending order, and odd indexes hold odd numbers in ascending order... very straightforward... and we can write a code to rearrange deterministically...

and looking at `retry_flag`, it swaps `enc_idx[var_7]` and `enc_ch[var_7]` with `enc_idx[var_8]` and `enc_ch[var_8]` where var_7 and var_8 are random indexes...

it clears that each `enc_idx` belongs to an `enc_ch` at the same index (`enc_idx[i]` => `enc_ch[i]`). thus we can simply rearrange the `enc_ch` too while we rearrange `enc_idx` according to the rules we saw in `check_flag` function...

but wait! look at values at `enc_idx`!! there are no duplicates of course AND that's a set of numbers from 0 to 38, including all numbers!

we don't need to rearrange the numbers because those will be contigous... `38, 1, 36, 2, 34, ..... 35, 2, 37, 0` as evens are in reverse order...

determining the reverse of an index is simple: `38 - enc_idx[i]` for even ones...

so: `enc_flag[ (enc_idx[i] & 1) ? enc_idx[i] : 38 - enc_idx[i] ] = enc_ch[i]`

and `decrypt_flag` doesn't need any comments...

solve.c : ```
#include <stdio.h>
#include <string.h>

typedef unsigned char uchar;

uchar enc_chx[] = {
0x8B, 0x84, 0x9A, 0x9B, 0x9A, 0xB1, 0xD6, 0xAF, 0x93, 0xB2,
0x81, 0x8C, 0x84, 0xAB, 0x9D, 0x9C, 0x8E, 0xB9, 0xB0, 0xD9,
0xA8, 0xA4, 0x9C, 0x81, 0x85, 0xA0, 0xA6, 0xB4, 0x87, 0x9A,
0xBB, 0x92, 0x96, 0xAD, 0x8C, 0xD7, 0xB0, 0x8D, 0x97
};

uchar enc_idx[] = {
0x16, 0xC, 0x24, 0x17, 0x13, 0x19, 0x7, 0x9, 0xE, 0x23,
0x5, 0x1, 0x18, 0x21, 0xD, 0x10, 0x12, 0x1F, 0x1A, 0x1E,
0x22, 0x0, 0xF, 0xB, 0x8, 0x15, 0x11, 0x2, 0x1D, 0x1C,
0x26, 0x3, 0x4, 0x25, 0x14, 0x20, 0x6, 0x1B, 0xA
};

void rearrange_enc(uchar* dest) {
for (int i=0; i < 39; i++) {
int idx = enc_idx[i];

if ((idx & 1) == 0)
idx = 38 - idx;

dest[idx] = enc_chx[i];
}
}

void decrypt_flag(uchar* dest, uchar* src) {
for (int i=0; i < 39; i++) {
dest[i] = (~src[i]) ^ i;
}
}

int main() {
uchar flag[40] = {0};
uchar enc[40] = {0};

rearrange_enc(enc);
decrypt_flag(flag, enc);

printf("flag: %s\n", flag);

return 0;
}
```

run and get the flag: `DrgnS{...YouCouldHaveJustWaitedYouKnow}`