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

disassemble.py 9.4KB

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