zomg we haz imagez 4 saves! (color are screwed sometimes :|)

This commit is contained in:
Giuseppe (LemonBoy) 2009-06-24 12:02:36 +02:00
parent 6135cc068a
commit 3681a0fd1d
4 changed files with 87 additions and 102 deletions

105
disc.py
View File

@ -8,28 +8,6 @@ from common import *
class WOD: #WiiOpticalDisc 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): class discHeader(Struct):
__endian__ = Struct.BE __endian__ = Struct.BE
def __format__(self): def __format__(self):
@ -84,11 +62,12 @@ class WOD: #WiiOpticalDisc
ret += 'Found %i channels (table at 0x%x)\n' % (self.channelsCount, self.chansTableOffset) ret += 'Found %i channels (table at 0x%x)\n' % (self.channelsCount, self.chansTableOffset)
ret += '\n' ret += '\n'
ret += 'Partition %i opened (type 0x%x) at 0x%x\n' % (self.partitionOpen, self.partitionType, self.partitionOffset) ret += 'Partition %i opened (type 0x%x) at 0x%x\n' % (self.partitionOpen, self.partitionType, self.partitionOffset)
ret += '%s' % self.partitionHdr ret += 'Partition name : %s' % self.partitionHdr
ret += 'Partition key %s\n' % hexdump(self.partitionKey) ret += 'Partition key : %s\n' % hexdump(self.partitionKey)
ret += 'Tmd at 0x%x (%x)\n' % (self.tmdOffset, self.tmdSize) ret += 'Partition IOS : IOS%i\n' % self.partitionIos
ret += 'main.dol at 0x%x (%x)\n' % (self.dolOffset, self.dolSize) ret += 'Partition tmd : 0x%x (%x)\n' % (self.tmdOffset, self.tmdSize)
ret += 'FST at 0x%x (%x)\n' % (self.fstSize, self.fstOffset) 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) ret += '%s\n' % (self.appLdr)
return ret return ret
@ -119,7 +98,7 @@ class WOD: #WiiOpticalDisc
blockStart = offset / 0x7C00 blockStart = offset / 0x7C00
blockLen = (align(size, 0x7C00)) / 0x7C00 blockLen = (align(size, 0x7C00)) / 0x7C00
for x in range(blockStart, blockStart + blockLen): for x in range(blockStart, blockLen):
try: try:
self.markedBlocks.index(blockStart + x) self.markedBlocks.index(blockStart + x)
except: except:
@ -242,7 +221,7 @@ class WOD: #WiiOpticalDisc
newFile.size = size newFile.size = size
newFile.nameOff = nameOff newFile.nameOff = nameOff
fstDir.addChild(newFile) fstDir.addChild(newFile)
#self.markContent(fileOffset, size) self.markContent(fileOffset, size)
return i+1 return i+1
def openPartition(self, index): def openPartition(self, index):
@ -327,59 +306,27 @@ class WOD: #WiiOpticalDisc
def getPartitionMainDol(self): def getPartitionMainDol(self):
return self.readPartition (self.dolOffset, self.dolSize) 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 == ""): self.buildDate = self.buffer[:0xa]
fn = os.path.dirname(self.f) + "/" + os.path.basename(self.f).replace(".", "_") + "_out" self.fileCount = struct.unpack('I', self.buffer[0x13:0x13 + 4])[0]
try:
origdir = os.getcwd()
os.mkdir(fn)
except:
pass
os.chdir(fn)
self.fp.seek(0x18) out += 'This update partition was built on %s and has %i files\n\n' % (self.buildDate, self.fileCount)
if(struct.unpack(">I", self.fp.read(4))[0] != 0x5D1C9EA3): out += '[File] [Type] [File name %30s] [Title description ]\n\n' % ''
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])
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) return out
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

View File

@ -4,6 +4,8 @@ from Struct import Struct
from common import * from common import *
from title import * from title import *
from TPL import *
from PIL import Image
class Savegame(): class Savegame():
class savegameHeader(Struct): 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 += '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 += 'Found %i files for %i bytes\n' % (self.bkHdr.filesCount, self.bkHdr.filesSize)
ret += 'Total size : %i bytes\n' % self.bkHdr.totalSize ret += 'Total size : %i bytes\n' % self.bkHdr.totalSize
ret += 'This save is %i blocks wise' % (self.bkHdr.totalSize / 0x20000)
return ret return ret
@ -196,43 +199,60 @@ class Savegame():
self.fileStartOffset = self.fd.tell() self.fileStartOffset = self.fd.tell()
def eraseWiiMac(self):
self.fd.seek(0xF128)
print self.fd.write('\x00' * 6)
def getBanner(self): 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): def getIcon(self, index):
if index < 0 or index > 7 or index > self.iconCount: if index < 0 or index > 7 or index > self.iconCount:
return -1 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): try:
self.fd.seek(0xF128) os.mkdir(os.path.dirname(self.f) + '/' + self.bkHdr.gameId)
print self.fd.write('\x00' * 6) 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): def getIconsCount(self):
return self.iconCount return self.iconCount
def getSaveString(self, string): def getSaveString(self, string):
if string == 'GAMEID': if string == 'id':
return self.bkHdr.gameId return self.bkHdr.gameId
elif string == 'GAMETITLE': elif string == 'title':
return self.bnr.gameTitle return self.bnr.gameTitle
elif string == 'GAMESUBTITLE': elif string == 'subtitle':
return self.bnr.gameSubTitle 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): def getFilesCount(self):
return self.bkHdr.filesCount return self.bkHdr.filesCount

9
tests/testLOC.py Normal file
View 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
View 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()