mirror of
https://github.com/grp/Wii.py.git
synced 2025-06-18 23:05:48 -04:00
Merge git@github.com:icefire/Wii.py
This commit is contained in:
commit
8d928288dc
105
disc.py
105
disc.py
@ -8,28 +8,6 @@ from common import *
|
||||
|
||||
|
||||
class WOD: #WiiOpticalDisc
|
||||
class fsentry:
|
||||
name = ""
|
||||
type = 0
|
||||
parent = None
|
||||
offset = 0
|
||||
lenght = 0
|
||||
|
||||
def __init__(self, name, type, parent, offset, len):
|
||||
self.name = ""
|
||||
if(parent != None):
|
||||
self.parent = parent
|
||||
def path(self):
|
||||
return parent.path() + "/" + name
|
||||
|
||||
class fsdir(fsentry):
|
||||
def __init__(self, name, parent):
|
||||
fsentry.__init__(self, name, parent)
|
||||
|
||||
class fsfile(fsentry):
|
||||
size = 0
|
||||
offset = 0
|
||||
|
||||
class discHeader(Struct):
|
||||
__endian__ = Struct.BE
|
||||
def __format__(self):
|
||||
@ -84,11 +62,12 @@ class WOD: #WiiOpticalDisc
|
||||
ret += 'Found %i channels (table at 0x%x)\n' % (self.channelsCount, self.chansTableOffset)
|
||||
ret += '\n'
|
||||
ret += 'Partition %i opened (type 0x%x) at 0x%x\n' % (self.partitionOpen, self.partitionType, self.partitionOffset)
|
||||
ret += '%s' % self.partitionHdr
|
||||
ret += 'Partition key %s\n' % hexdump(self.partitionKey)
|
||||
ret += 'Tmd at 0x%x (%x)\n' % (self.tmdOffset, self.tmdSize)
|
||||
ret += 'main.dol at 0x%x (%x)\n' % (self.dolOffset, self.dolSize)
|
||||
ret += 'FST at 0x%x (%x)\n' % (self.fstSize, self.fstOffset)
|
||||
ret += 'Partition name : %s' % self.partitionHdr
|
||||
ret += 'Partition key : %s\n' % hexdump(self.partitionKey)
|
||||
ret += 'Partition IOS : IOS%i\n' % self.partitionIos
|
||||
ret += 'Partition tmd : 0x%x (%x)\n' % (self.tmdOffset, self.tmdSize)
|
||||
ret += 'Partition main.dol : 0x%x (%x)\n' % (self.dolOffset, self.dolSize)
|
||||
ret += 'Partition FST : 0x%x (%x)\n' % (self.fstSize, self.fstOffset)
|
||||
ret += '%s\n' % (self.appLdr)
|
||||
|
||||
return ret
|
||||
@ -242,7 +221,7 @@ class WOD: #WiiOpticalDisc
|
||||
newFile.size = size
|
||||
newFile.nameOff = nameOff
|
||||
fstDir.addChild(newFile)
|
||||
#self.markContent(fileOffset, size)
|
||||
self.markContent(fileOffset, size)
|
||||
return i+1
|
||||
|
||||
def openPartition(self, index):
|
||||
@ -283,6 +262,8 @@ class WOD: #WiiOpticalDisc
|
||||
self.appLdr = self.Apploader().unpack(self.readPartition (0x2440, 32))
|
||||
self.partitionHdr = self.discHeader().unpack(self.readPartition (0x0, 0x400))
|
||||
|
||||
self.partitionIos = TMD(self.getPartitionTmd()).getIOSVersion() & 0x00ffffff
|
||||
|
||||
def getFst(self):
|
||||
fstBuf = self.readPartition(self.fstOffset, self.fstSize)
|
||||
return fstBuf
|
||||
@ -327,59 +308,27 @@ class WOD: #WiiOpticalDisc
|
||||
def getPartitionMainDol(self):
|
||||
return self.readPartition (self.dolOffset, self.dolSize)
|
||||
|
||||
def extractPartition(self, index, fn = ""):
|
||||
class updateInf():
|
||||
def __init__(self, f):
|
||||
self.buffer = open(f, 'r+b').read()
|
||||
def __str__(self):
|
||||
out = ''
|
||||
|
||||
if(fn == ""):
|
||||
fn = os.path.dirname(self.f) + "/" + os.path.basename(self.f).replace(".", "_") + "_out"
|
||||
try:
|
||||
origdir = os.getcwd()
|
||||
os.mkdir(fn)
|
||||
except:
|
||||
pass
|
||||
os.chdir(fn)
|
||||
self.buildDate = self.buffer[:0xa]
|
||||
self.fileCount = struct.unpack('I', self.buffer[0x13:0x13 + 4])[0]
|
||||
|
||||
self.fp.seek(0x18)
|
||||
if(struct.unpack(">I", self.fp.read(4))[0] != 0x5D1C9EA3):
|
||||
self.fp.seek(-4, 1)
|
||||
raise ValueError("Not a valid Wii Disc (GC not supported)! Magic: %08x" % struct.unpack(">I", self.fp.read(4))[0])
|
||||
out += 'This update partition was built on %s and has %i files\n\n' % (self.buildDate, self.fileCount)
|
||||
out += '[File] [Type] [File name %30s] [Title description ]\n\n' % ''
|
||||
|
||||
self.fp.seek(partitionoffs)
|
||||
for x in range(self.fileCount):
|
||||
updateEntry = self.buffer[0x2f + x * 0x200:0x2f + (x + 1) * 0x200]
|
||||
titleType = ord(updateEntry[0])
|
||||
titleFile = updateEntry[0x1:0x1 + 0x50]
|
||||
titleFile = titleFile[:titleFile.find('\x00')]
|
||||
titleName = updateEntry[0x1 + 0x50:0x1 + 0x50 + 0x40]
|
||||
titleName = titleName[:titleName.find('\x00')]
|
||||
out += '[%04i] [0x%02x] [%40s] [%20s]\n' % (x, titleType, titleFile, titleName)
|
||||
|
||||
tikdata = self.fp.read(0x2A3)
|
||||
open("tik").write(tikdata)
|
||||
self.tik = Ticket("tik")
|
||||
self.titlekey = self.tik.getTitleKey()
|
||||
|
||||
tmdsz = struct.unpack(">I", self.fp.read(4))[0]
|
||||
tmdoffs = struct.unpack(">I", self.fp.read(4))[0]
|
||||
|
||||
certsz = struct.unpack(">I", self.fp.read(4))[0]
|
||||
certoffs = struct.unpack(">I", self.fp.read(4))[0]
|
||||
|
||||
h3offs = struct.unpack(">I", self.fp.read(4))[0] << 2
|
||||
h3sz = 0x18000
|
||||
|
||||
dataoffs = struct.unpack(">I", self.fp.read(4))[0] << 2
|
||||
datasz = struct.unpack(">I", self.fp.read(4))[0] << 2
|
||||
if(tmdoffs != self.fp.tell()):
|
||||
raise ValueError("TMD is in wrong place, something is fucked...wtf?")
|
||||
|
||||
tmddata = self.fp.read(tmdsz)
|
||||
open("tmd").write(tmddata)
|
||||
|
||||
self.tmd = TMD("tmd")
|
||||
|
||||
|
||||
print tmd.getIOSVersion()
|
||||
|
||||
|
||||
fst.seek(dataoffs)
|
||||
|
||||
|
||||
|
||||
os.chdir("..")
|
||||
def _recurse(self, parent, names, recursion):
|
||||
if(recursion == 0):
|
||||
pass
|
||||
return out
|
||||
|
||||
|
||||
|
66
savedata.py
66
savedata.py
@ -4,6 +4,8 @@ from Struct import Struct
|
||||
|
||||
from common import *
|
||||
from title import *
|
||||
from TPL import *
|
||||
from PIL import Image
|
||||
|
||||
class Savegame():
|
||||
class savegameHeader(Struct):
|
||||
@ -108,6 +110,7 @@ class Savegame():
|
||||
ret += 'Wii MAC address %02x:%02x:%02x:%02x:%02x:%02x\n' % (self.bkHdr.wiiMacAddr[0], self.bkHdr.wiiMacAddr[1], self.bkHdr.wiiMacAddr[2], self.bkHdr.wiiMacAddr[3], self.bkHdr.wiiMacAddr[4], self.bkHdr.wiiMacAddr[5])
|
||||
ret += 'Found %i files for %i bytes\n' % (self.bkHdr.filesCount, self.bkHdr.filesSize)
|
||||
ret += 'Total size : %i bytes\n' % self.bkHdr.totalSize
|
||||
ret += 'This save is %i blocks wise' % (self.bkHdr.totalSize / 0x20000)
|
||||
|
||||
return ret
|
||||
|
||||
@ -196,43 +199,60 @@ class Savegame():
|
||||
|
||||
self.fileStartOffset = self.fd.tell()
|
||||
|
||||
def eraseWiiMac(self):
|
||||
self.fd.seek(0xF128)
|
||||
print self.fd.write('\x00' * 6)
|
||||
|
||||
def getBanner(self):
|
||||
return self.bnr.banner
|
||||
try:
|
||||
os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
|
||||
except:
|
||||
pass
|
||||
|
||||
os.chdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
|
||||
|
||||
return Image.fromstring("RGBA", (192, 64), TPL('').RGB5A3((192, 64), self.bnr.banner)).save('banner', 'png')
|
||||
|
||||
def getIcon(self, index):
|
||||
if index < 0 or index > 7 or index > self.iconCount:
|
||||
return -1
|
||||
if index == 0:
|
||||
return self.bnr.icon0
|
||||
if index == 1:
|
||||
return self.bnr.icon1
|
||||
if index == 2:
|
||||
return self.bnr.icon2
|
||||
if index == 3:
|
||||
return self.bnr.icon3
|
||||
if index == 4:
|
||||
return self.bnr.icon4
|
||||
if index == 5:
|
||||
return self.bnr.icon5
|
||||
if index == 6:
|
||||
return self.bnr.icon6
|
||||
if index == 7:
|
||||
return self.bnr.icon7
|
||||
|
||||
def eraseWiiMac(self):
|
||||
self.fd.seek(0xF128)
|
||||
print self.fd.write('\x00' * 6)
|
||||
try:
|
||||
os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
|
||||
except:
|
||||
pass
|
||||
|
||||
os.chdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
|
||||
|
||||
if index == 0:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon0)).save('icon' + str(index), 'png')
|
||||
if index == 1:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon1)).save('icon' + str(index), 'png')
|
||||
if index == 2:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon2)).save('icon' + str(index), 'png')
|
||||
if index == 3:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon3)).save('icon' + str(index), 'png')
|
||||
if index == 4:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon4)).save('icon' + str(index), 'png')
|
||||
if index == 5:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon5)).save('icon' + str(index), 'png')
|
||||
if index == 6:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon6)).save('icon' + str(index), 'png')
|
||||
if index == 7:
|
||||
return Image.fromstring("RGBA", (48, 48), TPL('').RGB5A3((48, 48), self.bnr.icon7)).save('icon' + str(index), 'png')
|
||||
|
||||
def getIconsCount(self):
|
||||
return self.iconCount
|
||||
|
||||
def getSaveString(self, string):
|
||||
if string == 'GAMEID':
|
||||
if string == 'id':
|
||||
return self.bkHdr.gameId
|
||||
elif string == 'GAMETITLE':
|
||||
elif string == 'title':
|
||||
return self.bnr.gameTitle
|
||||
elif string == 'GAMESUBTITLE':
|
||||
elif string == 'subtitle':
|
||||
return self.bnr.gameSubTitle
|
||||
elif string == 'mac':
|
||||
return self.bkHdr.wiiMacAddr[0] + ':' + self.bkHdr.wiiMacAddr[1] + ':' + self.bkHdr.wiiMacAddr[2] + ':' + self.bkHdr.wiiMacAddr[3] + ':' + self.bkHdr.wiiMacAddr[4] + ':' + self.bkHdr.wiiMacAddr[5]
|
||||
|
||||
def getFilesCount(self):
|
||||
return self.bkHdr.filesCount
|
||||
|
30
tests/fakesign.py
Normal file
30
tests/fakesign.py
Normal file
@ -0,0 +1,30 @@
|
||||
from disc import *
|
||||
from title import *
|
||||
from Struct import Struct
|
||||
import os
|
||||
|
||||
def fakesignPartition(self, iso, index)
|
||||
iso = WOD(iso)
|
||||
iso.openPartition(index)
|
||||
fstBuf = iso.getFst() "
|
||||
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'appldr.bin', 'w+b')
|
||||
fn.write(iso.getPartitionApploader()) #saved to cwd/GAMEID/PARTITION/file
|
||||
fn.close()
|
||||
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'h3.bin', 'w+b')
|
||||
fn.write(iso.getPartitionH3Table())
|
||||
fn.close()
|
||||
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'main.dol', 'w+b')
|
||||
fn.write(iso.getPartitionMainDol())
|
||||
fn.close()
|
||||
fn = open(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + 'fst.bin', 'w+b')
|
||||
fn.write(fstBuf)
|
||||
fn.close()
|
||||
fileNumber = struct.unpack(">I", fstBuf[0x8:0xc])[0]
|
||||
fileObject = iso.fstObject("", iso)
|
||||
iso.parseFst(fstBuf, fstBuf[12 * fileNumber:], 0, fileObject)
|
||||
fileObject.write(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/")
|
||||
fileObject.close()
|
||||
isoTik = Ticket(iso.getPartitionTik())
|
||||
isoTik.dump(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + "tik")
|
||||
isoTMD = TMD(iso.getPartitionTmd())
|
||||
isoTMD.dump(os.getcwd() + "/" + iso.discHdr.discId + iso.discHdr.gameCode + iso.discHdr.region + "/" + "PART" + index + "/" + "tmd")
|
9
tests/testLOC.py
Normal file
9
tests/testLOC.py
Normal file
@ -0,0 +1,9 @@
|
||||
from formats import locDat
|
||||
|
||||
sdLoc = locDat('/home/giuseppe/Scrivania/sysmenu/loc.dat')
|
||||
|
||||
print '%s' % sdLoc
|
||||
|
||||
#concorsiMii = sdLoc.getTitle(0, 0, 0)
|
||||
sdLoc.delTitle(0, 0, 0)
|
||||
|
9
tests/testSAVE.py
Normal file
9
tests/testSAVE.py
Normal file
@ -0,0 +1,9 @@
|
||||
from savedata import *
|
||||
|
||||
save = Savegame('/home/giuseppe/Scrivania/data' + str(4) + '.bin')
|
||||
save.analyzeHeader()
|
||||
print '%s' % save
|
||||
save.getBanner()
|
||||
for i in range(save.getIconsCount()):
|
||||
save.getIcon(i)
|
||||
save.extractFiles()
|
Loading…
Reference in New Issue
Block a user