# Special Instructions---**Points:** 262 | **Solves:** 61/653 | **Category:** Reversing
Execute this file and get the flag.
References: Assembly samples for many architectureshttp://kozos.jp/books/asm/cross-gcc494-v1.0.zip
See the assembly samples.
```$ unzip cross-gcc494-v1.0.zip$ cd cross-gcc494/sample$ ls *.d```
See the sample programs running on GDB simulator.
```$ cd cross-gcc494/exec$ ls *.d```
[Download](runme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7be)
---
[Bahasa Indonesia](#bahasa-indonesia)
## EnglishWe were given an ELF 32-bit with unknown architecture.```sh$ file runme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7berunme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7be: ELF 32-bit MSB executable, *unknown arch 0xdf* version 1 (SYSV), statically linked, not stripped```
Basic recon using `strings`, we found the architecture is `moxie`.```sh$ strings runme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7be,.U70123456789abcdefThis program uses special instructions.SETRSEED: (Opcode:0x16)	RegA -> SEEDGETRAND: (Opcode:0x17)	xorshift32(SEED) -> SEED	SEED -> RegAGCC: (GNU) 4.9.4moxie-elf.c...```
We couldn't disassemble it with `objdump` or `IDA`. We decided to make our own [simple disassembler](disas_moxie.py) by reading [this documentation](http://moxielogic.org/blog/pages/architecture.html).```$ python disas_moxie.pyfunction main0x136c:    06 18    push $sp, $r60x136e:    91 18    dec $sp, 0x240x1370:    01 20    ldi.l $r0, 0x92d68ca20x1376:    03 00    jsra set_random_seed0x137c:    01 80    ldi.l $r6, puts0x1382:    01 20    ldi.l $r0, 0x10x1388:    01 30    ldi.l $r1, "This program uses special instructions.\n\n"0x138e:    19 80    jsr $r60x1390:    01 20    ldi.l $r0, 0x10x1396:    01 30    ldi.l $r1, "SETRSEED: (Opcode:0x16)\n"0x139c:    19 80    jsr $r60x139e:    01 20    ldi.l $r0, 0x10x13a4:    01 30    ldi.l $r1, "    RegA -> SEED\n\n"0x13aa:    19 80    jsr $r60x13ac:    01 20    ldi.l $r0, 0x10x13b2:    01 30    ldi.l $r1, "GETRAND: (Opcode:0x17)\n"0x13b8:    19 80    jsr $r60x13ba:    01 20    ldi.l $r0, 0x10x13c0:    01 30    ldi.l $r1, "    xorshift32(SEED) -> SEED\n"0x13c6:    19 80    jsr $r60x13c8:    01 20    ldi.l $r0, 0x10x13ce:    01 30    ldi.l $r1, "    SEED -> RegA\n\n"0x13d4:    19 80    jsr $r60x13d6:    01 20    ldi.l $r0, flag0x13dc:    01 30    ldi.l $r1, randval0x13e2:    03 00    jsra decode0x13e8:    02 32    mov $r1, $r00x13ea:    01 20    ldi.l $r0, 0x10x13f0:    19 80    jsr $r60x13f2:    01 20    ldi.l $r0, 0x10x13f8:    01 30    ldi.l $r1, "\n"0x13fe:    19 80    jsr $r60x1400:    2e 22    xor $r0, $r00x1402:    03 00    jsra exit
function decode0x136c:    06 18    push $sp, $r60x136e:    06 19    push $sp, $r70x1370:    06 1a    push $sp, $r80x1372:    06 1b    push $sp, $r90x1374:    06 1c    push $sp, $r100x1376:    06 1d    push $sp, $r110x1378:    91 18    dec $sp, 0x240x137a:    02 d2    mov $r11, $r00x137c:    1c 42    ld.b $r2, ($r0)0x137e:    2e 22    xor $r0, $r00x1380:    0e 42    cmp $r2, $r00x1382:    c0 12    beq 0x???0x1384:    02 a3    mov $r8, $r10x1386:    02 9d    mov $r7, $r110x1388:    01 c0    ldi.l $r10, get_random_value0x138e:    1c 8a    ld.b $r6, ($r8)0x1390:    2e 22    xor $r0, $r00x1392:    19 c0    jsr $r100x1394:    2e 82    xor $r6, $r00x1396:    1c 29    ld.b $r0, ($r7)0x1398:    2e 82    xor $r6, $r00x139a:    1e 98    st.b ($r7), $r60x139c:    89 01    inc $r7, 0x10x139e:    8a 01    inc $r8, 0x10x13a0:    1c 39    ld.b $r1, ($r7)0x13a2:    2e 22    xor $r0, $r00x13a4:    0e 32    cmp $r1, $r00x13a6:    c7 f3    bne 0x???0x13a8:    02 2d    mov $r0, $r110x13aa:    02 e0    mov $r12, $fp0x13ac:    9e 18    dec $r12, 0x240x13ae:    07 ed    pop $r12, $r110x13b0:    07 ec    pop $r12, $r100x13b2:    07 eb    pop $r12, $r90x13b4:    07 ea    pop $r12, $r80x13b6:    07 e9    pop $r12, $r70x13b8:    07 e8    pop $r12, $r60x13ba:    04 00    ret
function set_random_seed0x136c:    16 20    ???0x136e:    04 00    ret
function get_random_value0x136c:    17 20    ???0x136e:    04 00    ret
flag: 6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00randval: 3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108```
The pseudocode roughly looks like this.```pythonflag = "6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00"randval = "3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108"def main():  set_random_seed(0x92d68ca2)  puts("...")  puts(decode(flag, randval))
def decode(flag, randval):  i = 0  while flag[i]:    flag[i] ^= randval[i] ^ get_random_value()    i += 1  return flag```
Function `set_random_seed` and `get_random_value` are compiled with special instructions. From strings inside the binary, we know that:```SETRSEED: (Opcode:0x16)	RegA -> SEEDGETRAND: (Opcode:0x17)	xorshift32(SEED) -> SEED	SEED -> RegA```
We tried several `xorshift32` implementations (there are many variants in the internet), then we got the flag using this script.```pythonimport numpy as np
state = np.uint32(0x92d68ca2)def xorshift():    global state    state ^= np.uint32(state << 13);    state ^= np.uint32(state >> 17);    state ^= np.uint32(state << 15);    return np.uint32(state);
flag = "6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00".decode("hex")r = "3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108".decode("hex")
s = ""for i, c in enumerate(flag):    if c == "\x00":        break    xorshift()    s += chr((ord(c) ^ ord(r[i]) ^ state) & 0xff)print s```
Flag: `SECCON{MakeSpecialInstructions}`
## Bahasa IndonesiaKami diberikan sebuah file ELF 32-bit dengan arsitektur yang tidak diketahui.```sh$ file runme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7berunme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7be: ELF 32-bit MSB executable, *unknown arch 0xdf* version 1 (SYSV), statically linked, not stripped```
Dengan menggunakan `strings`, kita mendapatkan bahwa arsitekturnya adalah `moxie`.```sh$ strings runme_f3abe874e1d795ffb6a3eed7898ddcbcd929b7be,.U70123456789abcdefThis program uses special instructions.SETRSEED: (Opcode:0x16)	RegA -> SEEDGETRAND: (Opcode:0x17)	xorshift32(SEED) -> SEED	SEED -> RegAGCC: (GNU) 4.9.4moxie-elf.c...```
Kami tidak dapat melakukan disassemble dengan `objdump` atau `IDA`, sehingga kami memutuskan untuk membuat sendiri [disassembler-nya](disas_moxie.py) dengan membaca [dokumentasi ini](http://moxielogic.org/blog/pages/architecture.html).```$ python disas_moxie.pyfunction main0x136c:    06 18    push $sp, $r60x136e:    91 18    dec $sp, 0x240x1370:    01 20    ldi.l $r0, 0x92d68ca20x1376:    03 00    jsra set_random_seed0x137c:    01 80    ldi.l $r6, puts0x1382:    01 20    ldi.l $r0, 0x10x1388:    01 30    ldi.l $r1, "This program uses special instructions.\n\n"0x138e:    19 80    jsr $r60x1390:    01 20    ldi.l $r0, 0x10x1396:    01 30    ldi.l $r1, "SETRSEED: (Opcode:0x16)\n"0x139c:    19 80    jsr $r60x139e:    01 20    ldi.l $r0, 0x10x13a4:    01 30    ldi.l $r1, "    RegA -> SEED\n\n"0x13aa:    19 80    jsr $r60x13ac:    01 20    ldi.l $r0, 0x10x13b2:    01 30    ldi.l $r1, "GETRAND: (Opcode:0x17)\n"0x13b8:    19 80    jsr $r60x13ba:    01 20    ldi.l $r0, 0x10x13c0:    01 30    ldi.l $r1, "    xorshift32(SEED) -> SEED\n"0x13c6:    19 80    jsr $r60x13c8:    01 20    ldi.l $r0, 0x10x13ce:    01 30    ldi.l $r1, "    SEED -> RegA\n\n"0x13d4:    19 80    jsr $r60x13d6:    01 20    ldi.l $r0, flag0x13dc:    01 30    ldi.l $r1, randval0x13e2:    03 00    jsra decode0x13e8:    02 32    mov $r1, $r00x13ea:    01 20    ldi.l $r0, 0x10x13f0:    19 80    jsr $r60x13f2:    01 20    ldi.l $r0, 0x10x13f8:    01 30    ldi.l $r1, "\n"0x13fe:    19 80    jsr $r60x1400:    2e 22    xor $r0, $r00x1402:    03 00    jsra exit
function decode0x136c:    06 18    push $sp, $r60x136e:    06 19    push $sp, $r70x1370:    06 1a    push $sp, $r80x1372:    06 1b    push $sp, $r90x1374:    06 1c    push $sp, $r100x1376:    06 1d    push $sp, $r110x1378:    91 18    dec $sp, 0x240x137a:    02 d2    mov $r11, $r00x137c:    1c 42    ld.b $r2, ($r0)0x137e:    2e 22    xor $r0, $r00x1380:    0e 42    cmp $r2, $r00x1382:    c0 12    beq 0x???0x1384:    02 a3    mov $r8, $r10x1386:    02 9d    mov $r7, $r110x1388:    01 c0    ldi.l $r10, get_random_value0x138e:    1c 8a    ld.b $r6, ($r8)0x1390:    2e 22    xor $r0, $r00x1392:    19 c0    jsr $r100x1394:    2e 82    xor $r6, $r00x1396:    1c 29    ld.b $r0, ($r7)0x1398:    2e 82    xor $r6, $r00x139a:    1e 98    st.b ($r7), $r60x139c:    89 01    inc $r7, 0x10x139e:    8a 01    inc $r8, 0x10x13a0:    1c 39    ld.b $r1, ($r7)0x13a2:    2e 22    xor $r0, $r00x13a4:    0e 32    cmp $r1, $r00x13a6:    c7 f3    bne 0x???0x13a8:    02 2d    mov $r0, $r110x13aa:    02 e0    mov $r12, $fp0x13ac:    9e 18    dec $r12, 0x240x13ae:    07 ed    pop $r12, $r110x13b0:    07 ec    pop $r12, $r100x13b2:    07 eb    pop $r12, $r90x13b4:    07 ea    pop $r12, $r80x13b6:    07 e9    pop $r12, $r70x13b8:    07 e8    pop $r12, $r60x13ba:    04 00    ret
function set_random_seed0x136c:    16 20    ???0x136e:    04 00    ret
function get_random_value0x136c:    17 20    ???0x136e:    04 00    ret
flag: 6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00randval: 3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108```
Pseudocode-nya kira-kira seperti ini.```pythonflag = "6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00"randval = "3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108"def main():  set_random_seed(0x92d68ca2)  puts("...")  puts(decode(flag, randval))
def decode(flag, randval):  i = 0  while flag[i]:    flag[i] ^= randval[i] ^ get_random_value()    i += 1  return flag```
Fungsi `set_random_seed` dan `get_random_value` dikompilasi dengan instruksi spesial. Dari string di dalam binary, kita mendapat hint bahwa:```SETRSEED: (Opcode:0x16)	RegA -> SEEDGETRAND: (Opcode:0x17)	xorshift32(SEED) -> SEED	SEED -> RegA```
Kami mencoba beberapa implementasi `xorshift32` (di internet ada beberapa varian fungsi tersebut), kemudian kami mendapat flag dengan script ini.```pythonimport numpy as np
state = np.uint32(0x92d68ca2)def xorshift():    global state    state ^= np.uint32(state << 13);    state ^= np.uint32(state >> 17);    state ^= np.uint32(state << 15);    return np.uint32(state);
flag = "6d72c3e2cf95549db6ac0384c3c23593c3d77ce2ddd4ac5e99c9a534de064e00".decode("hex")r = "3d05dc31d18aaf2996facb1b01ece2f715706cf47ea19e0e01f9c24cbaa0a108".decode("hex")
s = ""for i, c in enumerate(flag):    if c == "\x00":        break    xorshift()    s += chr((ord(c) ^ ord(r[i]) ^ state) & 0xff)print s```
Flag: `SECCON{MakeSpecialInstructions}`