stUpiidhax, the Wii U 5.5.2 exploit (based on JSTypeHax) http://stupiid.ovh/

disassemble.py 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. condition_table_true = ["lt", "gt", "eq"]
  2. condition_table_false = ["ge", "le", "ne"]
  3. trap_condition_table = {
  4. 1: "lgt",
  5. 2: "llt",
  6. 4: "eq",
  7. 5: "lge",
  8. 8: "gt",
  9. 12: "ge",
  10. 16: "lt",
  11. 20: "le",
  12. 31: "u"
  13. }
  14. spr_table = {
  15. 8: "lr",
  16. 9: "ctr"
  17. }
  18. def decodeI(value):
  19. return (value >> 2) & 0xFFFFFF, (value >> 1) & 1, value & 1
  20. def decodeB(value):
  21. return (value >> 21) & 0x1F, (value >> 16) & 0x1F, (value >> 2) & 0x3FFF, (value >> 1) & 1, value & 1
  22. def decodeD(value):
  23. return (value >> 21) & 0x1F, (value >> 16) & 0x1F, value & 0xFFFF
  24. def decodeX(value):
  25. return (value >> 21) & 0x1F, (value >> 16) & 0x1F, (value >> 11) & 0x1F, (value >> 1) & 0x3FF, value & 1
  26. def extend_sign(value, bits=16):
  27. if value & 1 << (bits - 1):
  28. value -= 1 << bits
  29. return value
  30. def ihex(value):
  31. return "-" * (value < 0) + "0x" + hex(value).lstrip("-0x").rstrip("L").zfill(1).upper()
  32. def decodeCond(BO, BI):
  33. #TODO: Better condition code
  34. if BO == 20: return ""
  35. if BO & 1: return "?"
  36. if BI > 2: return "?"
  37. if BO == 4: return condition_table_false[BI]
  38. if BO == 12: return condition_table_true[BI]
  39. return "?"
  40. def loadStore(value, regtype="r"):
  41. D, A, d = decodeD(value)
  42. d = extend_sign(d)
  43. return "%s%i, %s(r%i)" %(regtype, D, ihex(d), A)
  44. def loadStoreX(D, A, B, pad):
  45. if pad: return "<invalid>"
  46. return "r%i, %s, r%i" %(D, ("r%i" %A) if A else "0", B)
  47. def add(D, A, B, Rc):
  48. return "add%s" %("." * Rc), "r%i, r%i, r%i" %(D, A, B)
  49. def addi(value, addr):
  50. D, A, SIMM = decodeD(value)
  51. SIMM = extend_sign(SIMM)
  52. if A == 0:
  53. return "li", "r%i, %s" %(D, ihex(SIMM))
  54. return "addi", "r%i, r%i, %s" %(D, A, ihex(SIMM))
  55. def addic(value, addr):
  56. D, A, SIMM = decodeD(value)
  57. SIMM = extend_sign(SIMM)
  58. return "addic", "r%i, r%i, %s" %(D, A, ihex(SIMM))
  59. def addic_(value, addr):
  60. D, A, SIMM = decodeD(value)
  61. SIMM = extend_sign(SIMM)
  62. return "addic.", "r%i, r%i, %s" %(D, A, ihex(SIMM))
  63. def addis(value, addr):
  64. D, A, SIMM = decodeD(value)
  65. SIMM = extend_sign(SIMM)
  66. if A == 0:
  67. return "lis", "r%i, %s" %(D, ihex(SIMM))
  68. return "addis", "r%i, r%i, %s" %(D, A, ihex(SIMM))
  69. def and_(S, A, B, Rc):
  70. return "and%s" % ("." * Rc), "r%i, r%i, r%i" % (A, S, B)
  71. def b(value, addr):
  72. LI, AA, LK = decodeI(value)
  73. LI = extend_sign(LI, 24) * 4
  74. if AA:
  75. dst = LI
  76. else:
  77. dst = addr + LI
  78. return "b%s%s" %("l" * LK, "a" * AA), ihex(dst)
  79. def bc(value, addr):
  80. BO, BI, BD, AA, LK = decodeB(value)
  81. LI = extend_sign(LK, 14) * 4
  82. instr = "b" + decodeCond(BO, BI)
  83. if LK: instr += "l"
  84. if AA:
  85. instr += "a"
  86. dst = LI
  87. else:
  88. dst = addr + LI
  89. return instr, ihex(dst)
  90. def bcctr(BO, BI, pad, LK):
  91. if pad: return "<invalid>"
  92. instr = "b" + decodeCond(BO, BI) + "ctr"
  93. if LK:
  94. instr += "l"
  95. return instr
  96. def bclr(BO, BI, pad, LK):
  97. if pad: return "<invalid>"
  98. instr = "b" + decodeCond(BO, BI) + "lr"
  99. if LK:
  100. instr += "l"
  101. return instr
  102. def cmp(cr, A, B, pad):
  103. if pad: return "<invalid>"
  104. if cr & 3:
  105. return "<invalid>"
  106. return "cmp", "cr%i, r%i, r%i" %(cr >> 2, A, B)
  107. def cmpi(value, addr):
  108. cr, A, SIMM = decodeD(value)
  109. SIMM = extend_sign(SIMM)
  110. if cr & 3:
  111. return "<invalid>"
  112. return "cmpwi", "cr%i, r%i, %s" %(cr >> 2, A, ihex(SIMM))
  113. def cmpl(cr, A, B, pad):
  114. if pad: return "<invalid>"
  115. if cr & 3:
  116. return "<invalid>"
  117. return "cmplw", "cr%i, r%i, r%i" %(cr >> 2, A, B)
  118. def cmpli(value, addr):
  119. cr, A, UIMM = decodeD(value)
  120. if cr & 3:
  121. return "<invalid>"
  122. return "cmplwi", "cr%i, r%i, %s" %(cr >> 2, A, ihex(UIMM))
  123. def cntlzw(S, A, pad, Rc):
  124. if pad: return "<invalid>"
  125. return "cntlzw%s" %("." * Rc), "r%i, r%i" %(A, S)
  126. def dcbst(pad1, A, B, pad2):
  127. if pad1 or pad2: return "<invalid>"
  128. return "dcbst", "r%i, r%i" %(A, B)
  129. def fmr(D, pad, B, Rc):
  130. if pad: return "<invalid>"
  131. return "fmr%s" %("." * Rc), "f%i, f%i" %(D, B)
  132. def fneg(D, pad, B, Rc):
  133. if pad: return "<invalid>"
  134. return "fneg%s" %("." * Rc), "f%i, f%i" %(D, B)
  135. def mfspr(D, sprLo, sprHi, pad):
  136. if pad: return "<invalid>"
  137. sprnum = (sprHi << 5) | sprLo
  138. if sprnum not in spr_table:
  139. spr = "?"
  140. else:
  141. spr = spr_table[sprnum]
  142. return "mf%s" %spr, "r%i" %D
  143. def mtspr(S, sprLo, sprHi, pad):
  144. if pad: return "<invalid>"
  145. sprnum = (sprHi << 5) | sprLo
  146. if sprnum not in spr_table:
  147. spr = ihex(sprnum)
  148. else:
  149. spr = spr_table[sprnum]
  150. return "mt%s" %spr, "r%i" %S
  151. def lbz(value, addr): return "lbz", loadStore(value)
  152. def lfd(value, addr): return "lfd", loadStore(value, "f")
  153. def lfs(value, addr): return "lfs", loadStore(value, "f")
  154. def lmw(value, addr): return "lmw", loadStore(value)
  155. def lwz(value, addr): return "lwz", loadStore(value)
  156. def lwzu(value, addr): return "lwzu", loadStore(value)
  157. def lwarx(D, A, B, pad): return "lwarx", loadStoreX(D, A, B, pad)
  158. def lwzx(D, A, B, pad): return "lwzx", loadStoreX(D, A, B, pad)
  159. def or_(S, A, B, Rc):
  160. if S == B:
  161. return "mr%s" %("." * Rc), "r%i, r%i" %(A, S)
  162. return "or%s" %("." * Rc), "r%i, r%i, r%i" %(A, S, B)
  163. def ori(value, addr):
  164. S, A, UIMM = decodeD(value)
  165. if UIMM == 0:
  166. return "nop"
  167. return "ori", "r%s, r%s, %s" %(A, S, ihex(UIMM))
  168. def oris(value, addr):
  169. S, A, UIMM = decodeD(value)
  170. return "oris", "r%s, r%s, %s" %(A, S, ihex(UIMM))
  171. def rlwinm(value, addr):
  172. S, A, SH, M, Rc = decodeX(value)
  173. MB = M >> 5
  174. ME = M & 0x1F
  175. dot = "." * Rc
  176. if SH == 0 and MB == 0 and ME == 31:
  177. return "nop"
  178. if MB == 0 and ME == 31 - SH:
  179. return "slwi%s" %dot, "r%i, r%i, %i" %(A, S, SH)
  180. if ME == 31 and SH == 32 - MB:
  181. return "srwi%s" %dot, "r%i, r%i, %i" %(A, S, MB)
  182. if MB == 0 and ME < 31:
  183. return "extlwi%s" %dot, "r%i, r%i, %i,%i" %(A, S, ME + 1, SH)
  184. #extrwi
  185. if MB == 0 and ME == 31:
  186. if SH >= 16:
  187. return "rotlwi%s" %dot, "r%i, r%i, %i" %(A, S, SH)
  188. return "rotrwi%s" %dot, "r%i, r%i, %i" %(A, S, 32 - SH)
  189. if SH == 0 and ME == 31:
  190. return "clrlwi%s" %dot, "r%i, r%i, %i" %(A, S, MB)
  191. if SH == 0 and MB == 0:
  192. return "clrrwi%s" %dot, "r%i, r%i, %i" %(A, S, 31 - ME)
  193. #clrlslwi
  194. return "rlwinm%s" %dot, "r%i, r%i, %i,%i,%i" %(A, S, SH, MB, ME)
  195. def sc(value, addr):
  196. if value & 0x3FFFFFF != 2:
  197. return "<invalid>"
  198. return "sc"
  199. def stb(value, addr): return "stb", loadStore(value)
  200. def stfd(value, addr): return "stfd", loadStore(value, "f")
  201. def stfs(value, addr): return "stfs", loadStore(value, "f")
  202. def stfsu(value, addr): return "stfsu", loadStore(value, "f")
  203. def stmw(value, addr): return "stmw", loadStore(value)
  204. def stw(value, addr): return "stw", loadStore(value)
  205. def stwu(value, addr): return "stwu", loadStore(value)
  206. def stbx(S, A, B, pad): return "stbx", loadStoreX(S, A, B, pad)
  207. def stwx(S, A, B, pad): return "stwx", loadStoreX(S, A, B, pad)
  208. def stwcx(S, A, B, pad): return "stwcx", loadStoreX(S, A, B, pad ^ 1)
  209. def tw(TO, A, B, pad):
  210. if pad: return "<invalid>"
  211. if TO == 31 and A == 0 and B == 0:
  212. return "trap"
  213. if TO not in trap_condition_table:
  214. condition = "?"
  215. else:
  216. condition = trap_condition_table[TO]
  217. return "tw%s" %condition, "r%i, r%i" %(A, B)
  218. opcode_table_ext1 = {
  219. 16: bclr,
  220. 528: bcctr
  221. }
  222. opcode_table_ext2 = {
  223. 0: cmp,
  224. 4: tw,
  225. 20: lwarx,
  226. 23: lwzx,
  227. 26: cntlzw,
  228. 28: and_,
  229. 32: cmpl,
  230. 54: dcbst,
  231. 150: stwcx,
  232. 151: stwx,
  233. 215: stbx,
  234. 266: add,
  235. 339: mfspr,
  236. 444: or_,
  237. 467: mtspr
  238. }
  239. opcode_table_float_ext1 = {
  240. 40: fneg,
  241. 72: fmr
  242. }
  243. def ext1(value, addr):
  244. DS, A, B, XO, Rc = decodeX(value)
  245. if not XO in opcode_table_ext1:
  246. return "ext1 - %s" %bin(XO)
  247. return opcode_table_ext1[XO](DS, A, B, Rc)
  248. def ext2(value, addr):
  249. DS, A, B, XO, Rc = decodeX(value)
  250. if not XO in opcode_table_ext2:
  251. return "ext2 - %s" %bin(XO)
  252. return opcode_table_ext2[XO](DS, A, B, Rc)
  253. def float_ext1(value, addr):
  254. D, A, B, XO, Rc = decodeX(value)
  255. if not XO in opcode_table_float_ext1:
  256. return "float_ext1 - %s" %bin(XO)
  257. return opcode_table_float_ext1[XO](D, A, B, Rc)
  258. opcode_table = {
  259. 10: cmpli,
  260. 11: cmpi,
  261. 12: addic,
  262. 13: addic_,
  263. 14: addi,
  264. 15: addis,
  265. 16: bc,
  266. 17: sc,
  267. 18: b,
  268. 19: ext1,
  269. 21: rlwinm,
  270. 24: ori,
  271. 25: oris,
  272. 31: ext2,
  273. 32: lwz,
  274. 33: lwzu,
  275. 34: lbz,
  276. 36: stw,
  277. 37: stwu,
  278. 38: stb,
  279. 46: lmw,
  280. 47: stmw,
  281. 48: lfs,
  282. 50: lfd,
  283. 52: stfs,
  284. 53: stfsu,
  285. 54: stfd,
  286. 63: float_ext1
  287. }
  288. def disassemble(value, address):
  289. opcode = value >> 26
  290. if opcode not in opcode_table:
  291. return "???"
  292. instr = opcode_table[opcode](value, address)
  293. if type(instr) == str:
  294. return instr
  295. return instr[0] + " " * (10 - len(instr[0])) + instr[1]