check-state.py
1 #!/usr/bin/env python3 2 3 from mcu import Operation, Microcontroller 4 5 getc = [ord(c) for c in reversed("5\n23\n42\n13\nY\n")] 6 7 def putc(c): 8 c = int(mcu.mem.a) 9 if c & 0x80: # unescaping in case we come from putc_raw 10 c = 0x40 | (c & 0x3f) 11 #print(f"putc({repr(chr(c))})") 12 print(chr(c), end="") 13 14 thingies = { 15 0x1f52: "T0", 16 0x1f94: "T1", 17 0x1fde: "T2", 18 0x2021: "T3", 19 0x1f9f: "1!", 20 0x1fca: "1.", 21 0x2007: "2.", 22 0x2010: "2!", 23 0x204e: "3.", 24 0x2052: "3!", 25 0x1f80: "0.", 26 0x1f52: "0!" 27 } 28 29 pois = { 30 #0x1e7f, # state1 31 #0x1e61, # state0 32 0x1f2c, # nscw1 33 #0x1e5c, # cv 34 #0x1e8c, # nscw0 35 #*thingies.keys(), 36 #0x1f38, # nibble_swap_ctrl 37 #0x1f41, # cb[nsi>>1] 38 #0x2072, # cb 39 0x2087, # end of box perm 40 #0x20cf, 0x2099, # cb 41 #0x20f2, # cb 42 #0x1cf7, 43 #0x1b77, 44 #0x1b42, 45 #0x1b45, 46 } 47 48 mcu = Microcontroller() 49 def run(mcu, end, trace): 50 isns = 0 51 while mcu.pc not in end: 52 isns+=1 53 op = Operation(mcu.rom[int(mcu.pc)]) 54 op.args = mcu.rom[int(mcu.pc + 1):int(mcu.pc + len(op))] 55 56 if int(mcu.pc) in pois: 57 if int(mcu.pc) == 0x1e5c: 58 print(f"cv: ", end='') 59 for i in range(7): 60 print(f"{mcu.mem._data[0x35+i]:02x}", end='') 61 elif int(mcu.pc) == 0x1e61: 62 print(f"state0: ", end='') 63 for i in range(8): 64 print(f"{mcu.xmem._data[0x7f41+i]:02x}", end='') 65 elif int(mcu.pc) == 0x1e7f: 66 print(f"state1: ", end='') 67 for i in range(8): 68 print(f"{mcu.xmem._data[0x7f41+i]:02x}", end='') 69 elif int(mcu.pc) == 0x1e8c: 70 print(f"nscw0: ", end='') 71 for i in range(4): 72 print(f"{mcu.mem._data[0x29+i]:02x}", end='') 73 elif int(mcu.pc) == 0x1f2c: 74 print(f"nscw1: ", end='') 75 for i in range(4): 76 print(f"{mcu.mem._data[0x29+i]:02x}", end='') 77 print("\ncb: ", end='') 78 for i in range(8): 79 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 80 elif int(mcu.pc) in thingies: 81 print(f"thingy: {mcu.mem._data[0x27]:02x} {thingies[int(mcu.pc)]}", end='') 82 elif int(mcu.pc) == 0x1f38: 83 print(f"nibble_swap_ctrl: {mcu.mem._data[0x29]:02x}", end='') 84 elif int(mcu.pc) == 0x1f41: 85 x = (int(mcu.mem._data[0x28] + 0x5a) >> 1) | ((0xa5 < mcu.mem._data[0x28]) << 7) 86 print(f"nsi: {x:02x} {mcu.mem._data[x]:02x}", end='') 87 elif int(mcu.pc) == 0x2072: 88 print("cb: ",end='') 89 for i in range(8): 90 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 91 elif int(mcu.pc) == 0x2087: 92 print("eobp cb: ",end='') 93 for i in range(8): 94 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 95 elif int(mcu.pc) == 0x2099: 96 print("fbp cb: ",end='') 97 for i in range(8): 98 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 99 elif int(mcu.pc) == 0x20cf: 100 print("ns cb: ",end='') 101 for i in range(8): 102 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 103 elif int(mcu.pc) == 0x20f2: 104 print("sbox cb: ",end='') 105 for i in range(8): 106 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 107 print() 108 if trace: 109 print(f"{isns:5} {int(mcu.pc):04x} {str(op):<30} | " 110 f"{int(mcu.mem.a):02x} " 111 f"{int(mcu.mem.r0):02x} " 112 f"{int(mcu.mem.r1):02x} " 113 f"{int(mcu.mem.r2):02x} " 114 f"{int(mcu.mem.dptr):04x} " 115 f"{int(mcu.mem[0xd0]) & 0xfe:02x} " 116 f"{int(mcu.mem[0xd1]):02x} ", end='') 117 for i in range(23): 118 if i>0 and i % 4==0: print(" ", end='') 119 print(f"{mcu.mem._data[0x25+i]:02x}", end='') 120 print() 121 122 if op.opcode == 0x12: # lcall 123 if op.args == [0x03,0x7a]: # putc 124 putc(mcu.mem.a) 125 mcu.pc += len(op) 126 continue 127 elif op.args == [0x05,0x65]: # getc 128 if trace: 129 print("getc()") 130 mcu.pc += len(op) 131 #mcu.mem.a = ord(input('')[0]) 132 mcu.mem.a = getc.pop() 133 continue 134 if op.opcode == 0x2: # jmp 135 if op.args == [0x03,0x7a]: # putc 136 putc(mcu.mem.a) 137 mcu._exec_34() # ret 138 continue 139 elif op.args == [0x05,0x65]: # getc 140 if trace: 141 print("getc()") 142 #mcu.mem.a = ord(input('')[0]) 143 mcu.mem.a = getc.pop() 144 mcu._exec_34() # ret 145 continue 146 147 # catch putc if not jmp/call 148 if int(mcu.pc)==0x37a: 149 putc(mcu.mem.a) 150 mcu._exec_34() # ret 151 continue 152 153 mcu.next_cycle() 154 if trace: 155 print() 156 print("end, total insn", isns) 157 return isns 158 159 # reset 160 mcu.reset_ram() 161 162 # load rom image 163 with open('SBT.rom','rb') as fd: 164 code = fd.read() 165 for i, b in enumerate(code): 166 mcu.rom[i] = b 167 168 # init key 169 # this is the 15 byte "key" AAAAAAAAAAAAAAA 170 for i in range(15): mcu.rom[0x72d7+i] = 0x1 171 172 mcu.pc = 0x1af0 # we skip the query to print the output at 1aed 173 #for i,c in enumerate("BAMLK GAFFJ EDBCP\xfe"): 174 #for i,c in enumerate("HCAMM MBKJO DGCNC\xfe"): 175 for i,c in enumerate("LEEIC BIIKY DBCFE DPKLB ECILE\xfe"): 176 #for i,c in enumerate("JDMNJ AEJHP CPBLO JPJDD BEDNG\xfe"): 177 mcu.xmem[0x3000+i]=(ord(c) & 0x3f) if c!='\xfe' else 0xfe 178 mcu.mem[0x42]=0x30 179 mcu.mem[0x43]=0x00 180 mcu.mem.r5=1 181 182 mcu.mem[0x4a]=0x00 183 mcu.mem[0x4b]=0x00 184 mcu.mem[0x4c]=0x00 185 186 steps = run(mcu, [0x20f9], False) 187 print 188 189 print("cipherblock ", end='') 190 for i in range(8): 191 print(f"{mcu.mem._data[0x2d+i]:02x}", end='') 192 print() 193 194 print("ctrl_var ", end='') 195 for i in range(7): 196 print(f"{mcu.mem._data[0x35+i]:02x}", end='') 197 print() 198 199 print("state ", end='') 200 for i in range(7): 201 print(f"{mcu.xmem._data[0x7f41+i]:02x}", end='') 202 print()