/ analysis / emu / check-state.py
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()