# RISC 8bit CPU

## Description

The SFT0 CPU is a secure processor designed to store encryption key. Find out how the processor works and get the key.

{% file src="<https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-9328c6afa0c6a39a7faa3c60d87345e7646e06bb%2Fmanual.pdf?alt=media>" %}
manual.pdf
{% endfile %}

{% file src="<https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-0388c638a2afd8d9d9912abdec41c3a026bb189b%2From.bin?alt=media>" %}
rom.bin
{% endfile %}

## Solution

We're given the specifications for this custom processor. This one is pretty simple - there are 3 registers (A, B and C), a program counter (PC) and a 1-bit flag register.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-a7d9d9d166450f3695f395f72adb91c986cab940%2FScreenshot%202021-08-30%20at%201.40.29%20PM.png?alt=media)

We're told that the address space is from 0x0000 to 0xFFFF. Furthermore, the PC starts from 0x1000:

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-cd97217b16c988cded21559697b9dbf7f21fc8bf%2FScreenshot%202021-08-30%20at%201.41.53%20PM.png?alt=media)

We're given the ROM to be loaded at 0x0000, and we need to write an emulator that parses and executes the following instructions.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-bf676f8fae59e6e82ac9f9647b3d6f3bec42a352%2FScreenshot%202021-08-30%20at%201.42.26%20PM.png?alt=media)

We can simply represent the memory space as an array, access 4 bytes at a time, and parse the instructions based on the specification above. Initially, I ran into some errors because I forgot to always take the lower 8 bits after an arithmetic operation. The rest is just a bunch of if-else statements!

```python
ROM = "40 18 2C ... 09 09 09"

registers = [0 for _ in range(3)]

pc = 0x1000     # Program Counter
fr = 0          # Flag Register

rom = [int(x, 16) for x in ROM.split()]
memory = rom + [0 for _ in range(0xffff + 1 - len(rom))]

done = False
while not done:

    curr_instruction = memory[pc:pc+4]
    pc += 4

    if curr_instruction[0] == 0:
        # print(f"ADD R{curr_instruction[1]}, {curr_instruction[3]}")

        registers[curr_instruction[1]] += curr_instruction[3]

    elif curr_instruction[0] == 1:
        # print(f"XOR R{curr_instruction[1]}, {curr_instruction[3]}")

        registers[curr_instruction[1]] ^= curr_instruction[3]
    
    elif curr_instruction[0] == 2:
        # print(f"AND R{curr_instruction[1]}, {curr_instruction[3]}")

        registers[curr_instruction[1]] &= curr_instruction[3]
    
    elif curr_instruction[0] == 3:
        # print(f"OR R{curr_instruction[1]}, {curr_instruction[3]}")

        registers[curr_instruction[1]] |= curr_instruction[3]

    elif curr_instruction[0] == 4:
        # print(f"LD R{curr_instruction[1]}, {curr_instruction[3]}")

        registers[curr_instruction[1]] = curr_instruction[3]
    
    elif curr_instruction[0] == 5:
        # print(f"MOV R{curr_instruction[1]}, R{curr_instruction[3]}")

        registers[curr_instruction[1]] = registers[curr_instruction[3]]

    elif curr_instruction[0] == 6:

        addr = 256 * curr_instruction[2] + curr_instruction[3]

        # print(f"LDR R{curr_instruction[1]}, {addr}")

        registers[curr_instruction[1]] = memory[addr]

    elif curr_instruction[0] == 7:
        # print(f"LDR R{curr_instruction[1]}")

        addr = 256 * registers[1] + registers[2]
        registers[curr_instruction[1]] = memory[addr]
    
    elif curr_instruction[0] == 8:
        
        addr = 256 * curr_instruction[2] + curr_instruction[3]

        # print(f"STR R{curr_instruction[1]}, {addr}")

        memory[addr] = registers[curr_instruction[1]]

    elif curr_instruction[0] == 9:
        # print(f"STR R{curr_instruction[1]}")

        addr = 256 * registers[1] + registers[2]      
        memory[addr] = registers[curr_instruction[1]]

    elif curr_instruction[0] == 0x0A:
        # print(f"PUT R{curr_instruction[1]}")

        print(chr(registers[curr_instruction[1]]), end='')
    
    elif curr_instruction[0] == 0x0B:
        
        addr = 256 * curr_instruction[2] + curr_instruction[3]

        # print(f"JMP {addr}")

        pc = addr

    elif curr_instruction[0] == 0x0C:

        addr = 256 * curr_instruction[2] + curr_instruction[3]

        # print(f"JNZ {addr}")

        if fr == 0:
            pc = addr + 4
    
    elif curr_instruction[0] == 0x0D:
        
        addr = 256 * curr_instruction[2] + curr_instruction[3]

        # print(f"JZ {addr}")

        if fr == 1:
            pc = addr + 4

    elif curr_instruction[0] == 0x0E:
        # print(f"CMPEQ R{curr_instruction[1]}, {curr_instruction[3]}")

        if registers[curr_instruction[1]] == curr_instruction[3]:
            fr = 1
        
        else:
            fr = 0
    
    elif curr_instruction[1] == 0x44:
        # print("HLT")

        done = True
    
    elif curr_instruction[1] == 0x33:
        # print("NOP")
        pass

    else:
        raise ValueError(f"Unrecognized instruction {curr_instruction}")
    
    # 8-bit
    for i in range(len(registers)):
        if registers[i] >= 256:
            registers[i] -= 256
    
    # 16-bit
    if pc >= 65536:
        pc -= 65536
```

The flag is `YauzaCTF{s0_s3cr3t_y3t_s0_fr33}`.

![](https://3167364547-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MX1bWRlBzHpEPe1TYDD%2Fuploads%2Fgit-blob-72eca912832b7efdb7f20bc6974bac1de4619aa9%2Fimage.png?alt=media)
