Guest User

Untitled

a guest
Jun 21st, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.56 KB | None | 0 0
  1. import os, hashlib, struct, subprocess, fnmatch, shutil, urllib, array
  2. import wx
  3. import png
  4.  
  5. from Crypto.Cipher import AES
  6. from Struct import Struct
  7.  
  8. from common import *
  9.  
  10.  
  11. class WOD: #WiiOpticalDisc
  12. class fsentry:
  13. name = ""
  14. parent = None
  15.  
  16. def __init__(self, name, parent):
  17. self.name = ""
  18. if(parent != None):
  19. self.parent = parent
  20. def path(self):
  21. return parent.path() + "/" + name
  22.  
  23. class fsdir(fsentry):
  24. def __init__(self, name, parent):
  25. fsentry.__init__(self, name, parent)
  26.  
  27. class fsfile(fsentry):
  28. size = 0
  29. offset = 0
  30.  
  31. class discHeader(Struct):
  32. __endian__ = Struct.BE
  33. def __format__(self):
  34. self.discId = Struct.string(1)
  35. self.gameCode = Struct.string(2)
  36. self.region = Struct.string(1)
  37. self.makerCode = Struct.uint16
  38. self.h = Struct.uint8
  39. self.version = Struct.uint8
  40. self.audioStreaming = Struct.uint8
  41. self.streamingBufSize = Struct.uint8
  42. self.unused = Struct.uint8[14]
  43. self.magic = Struct.uint32
  44. self.title = Struct.string(64)
  45. self.hashVerify = Struct.uint8
  46. self.h3verify = Struct.uint8
  47.  
  48. def __str__(self):
  49. ret = ''
  50. ret += '%s [%s%s%s]\n' % (self.discHdr.title, self.discHdr.discId, self.discHdr.gameCode, self.discHdr.region)
  51. if self.discHdr.region == 'P':
  52. ret += 'Region : PAL\n'
  53. elif self.discHdr.region == 'E':
  54. ret += 'Region : NTSC\n'
  55. elif self.discHdr.region == 'J':
  56. ret += 'Region : JAPANESE\n'
  57. ret += 'Version 0x%x Maker %i Audio streaming %x\n' % (self.discHdr.version, self.discHdr.makerCode, self.discHdr.audioStreaming)
  58. ret += 'Hash verify flag 0x%x H3 verify flag : 0x%x\n' % (self.discHdr.hashVerify, self.discHdr.h3verify)
  59. ret += 'Found %i partitions (table at 0x%x)\n' % (self.partitionCount, self.partsTableOffset)
  60. ret += 'Found %i channels (table at 0x%x)\n' % (self.channelsCount, self.chansTableOffset)
  61. ret += 'Partition %i opened (type 0x%x) at 0x%x)\n' % (self.partitionOpen, self.partitionType, self.partitionOffset)
  62. ret += 'Tmd at 0x%x\n' % self.tmdOffset
  63. ret += 'main.dol at 0x%x fst at 0x%x (%ib)' % (self.dolOffset, self.fstSize, self.fstOffset)
  64.  
  65. return ret
  66.  
  67. def __init__(self, f):
  68. self.f = f
  69. self.fp = open(f, 'rb')
  70.  
  71. self.discHdr = self.discHeader().unpack(self.fp.read(0x400))
  72. if self.discHdr.magic != 0x5D1C9EA3:
  73. raise Exception('Wrong disc magic')
  74.  
  75. self.fp.seek(0x40000)
  76.  
  77. self.partitionCount = 1 + struct.unpack(">I", self.fp.read(4))[0]
  78. self.partsTableOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
  79.  
  80. self.channelsCount = struct.unpack(">I", self.fp.read(4))[0]
  81. self.chansTableOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
  82.  
  83. self.partitionOpen = -1
  84. self.partitionOffset = -1
  85. self.partitionType = -1
  86.  
  87. def openPartition(self, index):
  88. if index > self.partitionCount:
  89. raise ValueError('Partition index too big')
  90.  
  91. self.partitionOpen = index
  92.  
  93. self.partitionOffset = self.partsTableOffset + (8 * self.partitionOpen)
  94.  
  95. self.fp.seek(self.partsTableOffset + (8 * self.partitionOpen))
  96.  
  97. self.partitionOffset = struct.unpack(">I", self.fp.read(4))[0] << 2
  98. self.partitionType = struct.unpack(">I", self.fp.read(4))[0]
  99.  
  100. self.fp.seek(self.partitionOffset + 0x2A4)
  101.  
  102. self.tmdSize = struct.unpack(">I", self.fp.read(4))[0]
  103. self.tmdOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
  104.  
  105. self.certsSize = struct.unpack(">I", self.fp.read(4))[0]
  106. self.certsOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
  107.  
  108. self.H3TableOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
  109.  
  110. self.dataOffset = struct.unpack(">I", self.fp.read(4))[0] >> 2
  111. self.dataSize = struct.unpack(">I", self.fp.read(4))[0] >> 2
  112.  
  113. self.fp.seek(self.partitionOffset)
  114. open('partHeader.bin', 'w+b').write(self.fp.read(0x440))
  115.  
  116. self.fp.seek(self.partitionOffset + 0x420)
  117.  
  118. self.dolOffset = 4 * struct.unpack(">I", self.fp.read(4))[0]
  119.  
  120. self.fstOffset = 4 * struct.unpack(">I", self.fp.read(4))[0]
  121. self.fstSize = 4 * struct.unpack(">I", self.fp.read(4))[0]
  122.  
  123. def getIsoBootmode(self):
  124. if self.discHdr.discId == 'R' or self.discHdr.discId == '_':
  125. return 2
  126. elif self.discHdr.discId == '0':
  127. return 1
  128.  
  129. def getOpenedPartition(self):
  130. return self.partitionOpen
  131.  
  132. def getOpenedPartitionOffset(self):
  133. return self.partitionOffset
  134.  
  135. def getOpenedPartitionType(self):
  136. return self.partitionType
  137.  
  138. def getPartitionsCount(self):
  139. return self.partitionCount
  140.  
  141. def getChannelsCount(self):
  142. return self.channelsCount
  143.  
  144. def getPartitionCerts(self):
  145. self.fp.seek(self.partitionOffset + self.certsOffset)
  146. return self.fp.read(self.certsSize)
  147.  
  148. def getPartitionH3Table(self):
  149. self.fp.seek(self.partitionOffset + self.H3TableOffset)
  150. return self.fp.read(0x18000)
  151.  
  152. def getPartitionTmd(self):
  153. self.fp.seek(self.partitionOffset + self.tmdOffset)
  154. return self.fp.read(self.tmdSize)
  155.  
  156. def getPartitionTik(self):
  157. self.fp.seek(self.partitionOffset)
  158. return self.fp.read(0x2A4)
  159.  
  160. def getPartitionApploader(self):
  161. self.fp.seek(self.partitionOffset + 0x2440)
  162. print '%s' % hexdump(self.fp.read(32))
  163. self.fp.seek(self.partitionOffset + 0x2460)
  164.  
  165.  
  166. def extractPartition(self, index, fn = ""):
  167.  
  168. if(fn == ""):
  169. fn = os.path.dirname(self.f) + "/" + os.path.basename(self.f).replace(".", "_") + "_out"
  170. try:
  171. origdir = os.getcwd()
  172. os.mkdir(fn)
  173. except:
  174. pass
  175. os.chdir(fn)
  176.  
  177. self.fp.seek(0x18)
  178. if(struct.unpack(">I", self.fp.read(4))[0] != 0x5D1C9EA3):
  179. self.fp.seek(-4, 1)
  180. raise ValueError("Not a valid Wii Disc (GC not supported)! Magic: %08x" % struct.unpack(">I", self.fp.read(4))[0])
  181.  
  182. self.fp.seek(partitionoffs)
  183.  
  184. tikdata = self.fp.read(0x2A3)
  185. open("tik").write(tikdata)
  186. self.tik = Ticket("tik")
  187. self.titlekey = self.tik.getTitleKey()
  188.  
  189. tmdsz = struct.unpack(">I", self.fp.read(4))[0]
  190. tmdoffs = struct.unpack(">I", self.fp.read(4))[0]
  191.  
  192. certsz = struct.unpack(">I", self.fp.read(4))[0]
  193. certoffs = struct.unpack(">I", self.fp.read(4))[0]
  194.  
  195. h3offs = struct.unpack(">I", self.fp.read(4))[0] << 2
  196. h3sz = 0x18000
  197.  
  198. dataoffs = struct.unpack(">I", self.fp.read(4))[0] << 2
  199. datasz = struct.unpack(">I", self.fp.read(4))[0] << 2
  200. if(tmdoffs != self.fp.tell()):
  201. raise ValueError("TMD is in wrong place, something is fucked...wtf?")
  202.  
  203. tmddata = self.fp.read(tmdsz)
  204. open("tmd").write(tmddata)
  205.  
  206. self.tmd = TMD("tmd")
  207.  
  208.  
  209. print tmd.getIOSVersion()
  210.  
  211.  
  212. fst.seek(dataoffs)
  213.  
  214.  
  215.  
  216. os.chdir("..")
  217. def _recurse(self, parent, names, recursion):
  218. if(recursion == 0):
  219. pass
Add Comment
Please, Sign In to add comment