5.5 KiB
Architecture
Pasticciotto uses the Harvard Architecture meaning its code is separated from its data and also from its stack. This allowed me to materialize my idea for the PoliCTF challenge: I could run the code the partecipants assembled without any hassle!
There are 8 general purpose registers (R0
to S3
) with S0 -> S3
being "scratch" ones. There is a RP
register (Return Pointer) and obviously the IP
(Instruction Pointer).
Opcode encryption
The VM needs a decryption key to run: the opcodes are "encrypted" with the key by the assembler. The encryption algorithm is the RC4
key scheduling shuffle. Once the values are shuffled, the opcodes
are assigned according to their definition order.
key_ba = bytearray(key, 'utf-8')
# RC4 KSA! :-P
arr = [i for i in range(256)]
j = 0
for i in range(len(arr)):
j = (j + arr[i] + key_ba[i % len(key)]) % len(arr)
arr[i], arr[j] = arr[j], arr[i]
for i, o in enumerate(ops):
o.set_value(arr[i])
Instruction set
The instruction set I come out wants to be "RISC"-oriented but I have to admit that it is more "CISC"-oriented (Confusing Instruction Set Computer).
Also, since I decided that every instruction had to be 4 chars long, some name adaptation may have encountered some quality issue... (yes, POP
, I'm looking at you)
The syntax used is the Intel one!
There three types of instructions:
- with 2 operands (imm2reg, reg2imm, byt2reg, reg2reg)
- with 1 operand
- with no operand at all (single)
MOVI
Full name: MOVe Immediate to register
Usage: MOVI R0, 0x00
Effect: R0 contains the value 0x00
MOVR
Full name: MOVe Register to register
Usage: MOVR R1, R0
Effect: R0 is copied into R1
LODI
Full name: LOaD Immediate offset @ data section to register
Usage: LODI R0, 0x0
Effect: R0 contains data[0x0]
LODR
Full name: LOaD offset in Register @ data section to register
Usage: LODR R1, R0
Effect: R1 contains data[R1]
STRI
Full name: SToRe @ immediate offset in data section from register
Usage: STRI 0x0, R0
Effect: data[0x0] contains R0
STRR
Full name: SToRe @ offset of Register in data section from register
Usage: STRR R1, R0
Effect: data[R1] contains R0
ADDI
Full name: ADD Immediate to register
Usage: ADDI R0, 0x1
Effect: R0 is incremented by 0x1
ADDR
Full name: ADD Register to register
Usage: ADDR R1, R0
Effect: R1 is incremented by R0
SUBI
Full name: SUBstract Immediate from register
Usage: SUBI R0, 0x1
Effect: R0 is decremented by 0x1
SUBR
Full name: SUBstract Register from register
Usage: SUBR R1, R0
Effect: R1 is decremented by R0
ANDB
Full name:
Usage:
Effect:
ANDW
Full name:
Usage:
Effect:
ANDR
Full name:
Usage:
Effect:
YORB
Full name:
Usage:
Effect:
YORW
Full name:
Usage:
Effect:
YORR
Full name:
Usage:
Effect:
XORB
Full name:
Usage:
Effect:
XORW
Full name:
Usage:
Effect:
XORR
Full name:
Usage:
Effect:
NOTR
Full name:
Usage:
Effect:
MULI
Full name:
Usage:
Effect:
MULR
Full name:
Usage:
Effect:
DIVI
Full name:
Usage:
Effect:
DIVR
Full name:
Usage:
Effect:
SHLI
Full name:
Usage:
Effect:
SHLR
Full name:
Usage:
Effect:
SHRI
Full name:
Usage:
Effect:
SHRR
Full name:
Usage:
Effect:
PUSH
Full name:
Usage:
Effect:
POOP
Full name:
Usage:
Effect:
CMPB
Full name:
Usage:
Effect:
CMPW
Full name:
Usage:
Effect:
CMPR
Full name:
Usage:
Effect:
JMPI
Full name: JuMP to Immediate
Usage: JMPI 0x00
Effect: Unconditional jump to 0x00
JMPR
Full name: JuMP to Register
Usage: JMPR R0
Effect: Unconditional jump to R0
JPAI
Full name: JumP if Above to Immediate
Usage: JPAI 0x00
Effect: Jumps to code[0x00] according to last comparison
JPAR
Full name: JumP if Above to Register
Usage: JPAR R0
Effect: Jumps to code[R0] according to last comparison
JPBI
Full name: JumP if Below or equal to Immediate
Usage: JPBI 0x00
Effect: Jumps to code[0x00] according to last comparison
JPBR
Full name: JumP if Below or equal to Register
Usage: JPBR R0
Effect: Jumps to code[R0] according to last comparison
JPEI
Full name: JumP if Equal to Immediate
Usage: JPEI 0x00
Effect: Jumps to code[0x00] according to last comparison
JPER
Full name: JumP if Equal to Register
Usage: JPER R0
Effect: Jumps to code[R0] according to last comparison
JPNI
Full name: JumP if Not equal to Immediate
Usage: JPNI 0x00
Effect: Jumps to code[0x00] according to last comparison
JPNR
Full name: JumP if Not equal to Register
Usage: JPNR R0
Effect: Jumps to code[R0] according to last comparison
CALL
Full name: CALL function
Usage: CALL *function*
Effect: Saves the next instruction address into RP and jumps to the start of the function
RETN
Full name: RETurN
Usage: RETN
Effect: Restores the RP into the IP and jumps to the IP
SHIT
Full name: Well...
Usage: SHIT
Effect: Halts the execution
NOPE
Full name: NOP(e)
Usage: NOPE
Effect: Does nothing for an instruction
GRMN
Full name: GeRMaNo
Usage: GRMN
Effect: Sets every register (excluding IP and RP) to GG
DEBG
Full name: DEBuG
Usage: DEBG
Effect: Prints the status of every register and the flags