WIP: Quick and dirty python3 port

This commit is contained in:
Hector Martin 2021-03-17 23:53:31 +09:00
parent a8e5f6c0f7
commit cad274a7fb
41 changed files with 2399 additions and 2387 deletions

View File

@ -14,14 +14,14 @@ export ALAMEDA := $(CURDIR)/../../pywii/Alameda
export PNG2TPL := $(CURDIR)/tools/png2tpl$(EXE) export PNG2TPL := $(CURDIR)/tools/png2tpl$(EXE)
export MKBNS := $(CURDIR)/tools/mkbns$(EXE) export MKBNS := $(CURDIR)/tools/mkbns$(EXE)
export LZ77 := $(CURDIR)/tools/lz77$(EXE) export LZ77 := $(CURDIR)/tools/lz77$(EXE)
export ADDIMD5 := python2 $(CURDIR)/tools/addimd5.py export ADDIMD5 := python3 $(CURDIR)/tools/addimd5.py
export ARCPACK := python2 $(PYWII)/arcpack.py export ARCPACK := python3 $(PYWII)/arcpack.py
export SOX := sox export SOX := sox
all: channel.imet all: channel.imet
channel.imet: build/data.arc names.txt tools/join-imet.py channel.imet: build/data.arc names.txt tools/join-imet.py
python2 tools/join-imet.py $@ build/data.arc build/icon.arc build/banner.arc build/sound.bns names.txt python3 tools/join-imet.py $@ build/data.arc build/icon.arc build/banner.arc build/sound.bns names.txt
build/data.arc : build/data/meta/icon.bin build/data/meta/banner.bin build/data/meta/sound.bin build/data.arc : build/data/meta/icon.bin build/data/meta/banner.bin build/data/meta/sound.bin
$(ARCPACK) $@ build/data $(ARCPACK) $@ build/data
@ -45,9 +45,9 @@ build/%.raw : sound/%.wav
$(SOX) $< -r 32000 -c 2 -e signed-integer -b 16 -t raw $@ $(SOX) $< -r 32000 -c 2 -e signed-integer -b 16 -t raw $@
testi : channel.imet testi : channel.imet
python2 $(ALAMEDA)/Alameda.py channel.imet icon python3 $(ALAMEDA)/Alameda.py channel.imet icon
testb : channel.imet testb : channel.imet
python2 $(ALAMEDA)/Alameda.py channel.imet banner python3 $(ALAMEDA)/Alameda.py channel.imet banner
$(PNG2TPL): tools/*.c $(PNG2TPL): tools/*.c
$(MAKE) -C tools png2tpl$(EXE) $(MAKE) -C tools png2tpl$(EXE)

View File

@ -19,7 +19,7 @@ endif
../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS) : mk$(TYPE).py ../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS) : mk$(TYPE).py
@[ ! -d ../build/$(TYPE)/arc/anim ] && mkdir -p ../build/$(TYPE)/arc/anim || true @[ ! -d ../build/$(TYPE)/arc/anim ] && mkdir -p ../build/$(TYPE)/arc/anim || true
@[ ! -d ../build/$(TYPE)/arc/blyt ] && mkdir -p ../build/$(TYPE)/arc/blyt || true @[ ! -d ../build/$(TYPE)/arc/blyt ] && mkdir -p ../build/$(TYPE)/arc/blyt || true
python2 mk$(TYPE).py ../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS) python3 mk$(TYPE).py ../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS)
../build/$(TYPE).arc : $(TPLS) ../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS) ../build/$(TYPE).arc : $(TPLS) ../build/$(TYPE)/arc/blyt/$(TYPE).brlyt $(ANIMS)
$(ARCPACK) ../build/$(TYPE).arc ../build/$(TYPE) $(ARCPACK) ../build/$(TYPE).arc ../build/$(TYPE)

View File

@ -244,7 +244,7 @@ class BubbleInstance:
for i in tps: for i in tps:
if len(i.Triplets) > 0: if len(i.Triplets) > 0:
if i.Triplets[-1][0] >= self.Start: if i.Triplets[-1][0] >= self.Start:
print "WTF at %s: %f >= %f"%(self.Picture.Name,i.Triplets[-1][0],self.Start) print("WTF at %s: %f >= %f"%(self.Picture.Name,i.Triplets[-1][0],self.Start))
raise RuntimeError("We Have A Problem") raise RuntimeError("We Have A Problem")
brlan.Anim[self.Picture.Name][Brlan.A_COORD][Brlan.C_X].Triplets.append((self.Start, self.X, 0)) brlan.Anim[self.Picture.Name][Brlan.A_COORD][Brlan.C_X].Triplets.append((self.Start, self.X, 0))
@ -293,15 +293,15 @@ class BubbleCollection:
#print "Freeing instance: [%f-%f]"%(user.Start,user.End) #print "Freeing instance: [%f-%f]"%(user.Start,user.End)
tis[i] = pic, None tis[i] = pic, None
def printinstances(self): def printinstances(self):
print "Type Instances:" print("Type Instances:")
for tid, tis in enumerate(self.TypeInstances): for tid, tis in enumerate(self.TypeInstances):
print " Type Instances for type %d (%s):"%(tid, self.BubbleTypes[tid][0].Name) print(" Type Instances for type %d (%s):"%(tid, self.BubbleTypes[tid][0].Name))
for i, ti in enumerate(tis): for i, ti in enumerate(tis):
pic, user = ti pic, user = ti
if user is None: if user is None:
print " %d: Picture %s, free"%(i,pic.Name) print(" %d: Picture %s, free"%(i,pic.Name))
else: else:
print " %d: Picture %s, user: %s [%f-%f]"%(i,pic.Name,repr(user),user.Start,user.End) print(" %d: Picture %s, user: %s [%f-%f]"%(i,pic.Name,repr(user),user.Start,user.End))
def render(self): def render(self):
for t,c in self.BubbleTypes: for t,c in self.BubbleTypes:
t.makemat(self.Brlyt) t.makemat(self.Brlyt)
@ -330,9 +330,9 @@ class BubbleCollection:
i.render(self.Brlan) i.render(self.Brlan)
#self.printinstances() #self.printinstances()
print "Fake Start",fakeStart print("Fake Start",fakeStart)
print "Loop Start",loopStart print("Loop Start",loopStart)
print "Loop End",loopEnd print("Loop End",loopEnd)
col = BubbleCollection(brlyt, brlan, bubblepane) col = BubbleCollection(brlyt, brlan, bubblepane)
col.addtype(BubbleType("abubble1", 48, 48),1) col.addtype(BubbleType("abubble1", 48, 48),1)
@ -374,10 +374,10 @@ for i in col.Instances:
col.render() col.render()
brldata = brlyt.Pack() brldata = brlyt.Pack()
open(sys.argv[1],"w").write(brldata) open(sys.argv[1],"wb").write(brldata)
bradata = brlan.Pack(loopStart) bradata = brlan.Pack(loopStart)
open(sys.argv[2],"w").write(bradata) open(sys.argv[2],"wb").write(bradata)
bradata = brlan.Pack(loopStart, loopEnd) bradata = brlan.Pack(loopStart, loopEnd)
open(sys.argv[3],"w").write(bradata) open(sys.argv[3],"wb").write(bradata)

View File

@ -111,7 +111,7 @@ brlyt.RootPane.Add(tit)
brldata = brlyt.Pack() brldata = brlyt.Pack()
open(sys.argv[1],"w").write(brldata) open(sys.argv[1],"wb").write(brldata)
brlan = Brlan() brlan = Brlan()
@ -177,6 +177,6 @@ brlan.Anim['shadow'][Brlan.A_COORD][Brlan.C_X].repsimple(0, 960, 2, -45, -0.1, 4
bradata = brlan.Pack(60*16) bradata = brlan.Pack(60*16)
for a,b,c in brlan.Anim['waveb'][Brlan.A_COORD][Brlan.C_X].Triplets: for a,b,c in brlan.Anim['waveb'][Brlan.A_COORD][Brlan.C_X].Triplets:
print a,b,c print(a,b,c)
open(sys.argv[2],"w").write(bradata) open(sys.argv[2],"wb").write(bradata)

View File

@ -1,12 +1,12 @@
import md5, sys, struct import hashlib, sys, struct
data= open(sys.argv[1]).read() data= open(sys.argv[1], "rb").read()
digest = md5.new(data).digest() digest = hashlib.md5(data).digest()
hdr = struct.pack(">4sI8x","IMD5",len(data)) hdr = struct.pack(">4sI8x",b"IMD5",len(data))
f2 = open(sys.argv[2],"w") f2 = open(sys.argv[2],"wb")
f2.write(hdr) f2.write(hdr)
f2.write(digest) f2.write(digest)
f2.write(data) f2.write(data)

View File

@ -1,8 +1,8 @@
import os, sys, struct, md5 import os, sys, struct, hashlib
output, datafile, iconarc, bannerarc, soundbns, namesfile = sys.argv[1:] output, datafile, iconarc, bannerarc, soundbns, namesfile = sys.argv[1:]
data = open(datafile,"r").read() data = open(datafile,"rb").read()
names={} names={}
@ -11,7 +11,7 @@ for i in open(namesfile,"r"):
while b[-1] == "\n": while b[-1] == "\n":
b = b[:-1] b = b[:-1]
b = b.replace("\\n","\n") b = b.replace("\\n","\n")
names[a] = b.decode("utf-8") names[a] = b
def getsize(x): def getsize(x):
return os.stat(x).st_size return os.stat(x).st_size
@ -20,29 +20,29 @@ def pad(x,l):
if len(x) > l: if len(x) > l:
raise ValueError("%d > %d",len(x),l) raise ValueError("%d > %d",len(x),l)
n = l-len(x) n = l-len(x)
return x + "\x00"*n return x + b"\x00"*n
imet = "\x00"*0x40 imet = b"\x00"*0x40
imet += struct.pack(">4sIIIIII","IMET",0x600,3,getsize(iconarc),getsize(bannerarc),getsize(soundbns),1) imet += struct.pack(">4sIIIIII",b"IMET",0x600,3,getsize(iconarc),getsize(bannerarc),getsize(soundbns),1)
for i in ["jp", "en", "de", "fr", "sp", "it", "nl", "cn", None, "ko"]: for i in ["jp", "en", "de", "fr", "sp", "it", "nl", "cn", None, "ko"]:
try: try:
imet += pad(names[i].encode("UTF-16BE"),0x54) imet += pad(names[i].encode("UTF-16BE"),0x54)
except KeyError: except KeyError:
imet += "\x00"*0x54 imet += b"\x00"*0x54
imet += "\x00"*(0x600 - len(imet)) imet += b"\x00"*(0x600 - len(imet))
imet = imet[:-16] + md5.new(imet).digest() imet = imet[:-16] + hashlib.md5(imet).digest()
open(output,"w").write(imet) open(output,"wb").write(imet)
f = open(sys.argv[1],"w") f = open(sys.argv[1],"wb")
f.write(imet) f.write(imet)
f.write(data) f.write(data)
fsize = f.tell() fsize = f.tell()
if (fsize % 20) != 0: if (fsize % 20) != 0:
f.write("\x00"*(20-(fsize%20))) f.write(b"\x00"*(20-(fsize%20)))
f.close() f.close()

View File

@ -33,7 +33,7 @@ DIR_LIBS = \
$(DEVKITPRO)/libogc/lib/wii \ $(DEVKITPRO)/libogc/lib/wii \
$(DEVKITPRO)/portlibs/ppc/lib $(DEVKITPRO)/portlibs/ppc/lib
LIBS = mxml freetype png bz2 z db fat wiiuse bte ogc m LIBS = mxml freetype png z db fat wiiuse bte ogc m
MACHDEP = -g -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float MACHDEP = -g -DGEKKO -mrvl -mcpu=750 -meabi -mhard-float
CFLAGS = $(MACHDEP) -Os -Wall -DBASE_ADDR=$(BASE_ADDR) $(DIR_INCLUDES:%=-I%) CFLAGS = $(MACHDEP) -Os -Wall -DBASE_ADDR=$(BASE_ADDR) $(DIR_INCLUDES:%=-I%)

View File

@ -17,20 +17,20 @@ import pywii as wii
def LZ77Decompress(data): def LZ77Decompress(data):
inp = 0 inp = 0
dlen = len(data) dlen = len(data)
data += '\0' * 16 data += b'\0' * 16
ret = [] ret = []
while inp < dlen: while inp < dlen:
bitmask = ord(data[inp]) bitmask = data[inp]
inp += 1 inp += 1
for i in xrange(8): for i in range(8):
if bitmask & 0x80: if bitmask & 0x80:
rep = ord(data[inp]) rep = data[inp]
repLength = (rep >> 4) + 3 repLength = (rep >> 4) + 3
inp += 1 inp += 1
repOff = ord(data[inp]) | ((rep & 0x0F) << 8) repOff = data[inp] | ((rep & 0x0F) << 8)
inp += 1 inp += 1
assert repOff <= len(ret) assert repOff <= len(ret)
@ -44,13 +44,13 @@ def LZ77Decompress(data):
bitmask <<= 1 bitmask <<= 1
return ''.join(ret) return bytes(ret)
class U8(object): class U8(object):
class U8Header(Struct): class U8Header(Struct):
__endian__ = Struct.BE __endian__ = Struct.BE
def __format__(self): def __format__(self):
self.Tag = Struct.string(4) self.Tag = Struct.uint32
self.RootNode = Struct.uint32 self.RootNode = Struct.uint32
self.HeaderSize = Struct.uint32 self.HeaderSize = Struct.uint32
self.DataOffset = Struct.uint32 self.DataOffset = Struct.uint32
@ -76,7 +76,8 @@ class U8(object):
u8.unpack(data[pos:pos+len(u8)]) u8.unpack(data[pos:pos+len(u8)])
pos += len(u8) pos += len(u8)
assert u8.Tag == 'U\xAA8-' print(hex(u8.Tag))
assert u8.Tag == 0x55aa382d
pos += u8.RootNode - 0x20 pos += u8.RootNode - 0x20
root = self.U8Node() root = self.U8Node()
@ -84,7 +85,7 @@ class U8(object):
pos += len(root) pos += len(root)
children = [] children = []
for i in xrange(root.Size - 1): for i in range(root.Size - 1):
child = self.U8Node() child = self.U8Node()
child.unpack(data[pos:pos+len(child)]) child.unpack(data[pos:pos+len(child)])
pos += len(child) pos += len(child)
@ -98,7 +99,7 @@ class U8(object):
path = ['.'] path = ['.']
pathDepth = [root.Size - 1] pathDepth = [root.Size - 1]
for offset,child in enumerate(children): for offset,child in enumerate(children):
name = stringTable[child.NameOffset:].split('\0', 1)[0] name = stringTable[child.NameOffset:].split(b'\0', 1)[0].decode("ascii")
if child.Type == 0x0100: if child.Type == 0x0100:
path.append(name) path.append(name)
pathDepth.append(child.Size-offset-1) pathDepth.append(child.Size-offset-1)
@ -136,7 +137,7 @@ def IMD5(data):
assert imd5.Tag == 'IMD5' assert imd5.Tag == 'IMD5'
pos = len(imd5) pos = len(imd5)
if data[pos:pos+4] == 'LZ77': if data[pos:pos+4] == b'LZ77':
return LZ77Decompress(data[pos+8:]) return LZ77Decompress(data[pos+8:])
else: else:
return data[pos:] return data[pos:]
@ -145,7 +146,7 @@ class TPL(object):
class TPLHeader(Struct): class TPLHeader(Struct):
__endian__ = Struct.BE __endian__ = Struct.BE
def __format__(self): def __format__(self):
self.Magic = Struct.string(4) self.Magic = Struct.uint32
self.Count = Struct.uint32 self.Count = Struct.uint32
self.Size = Struct.uint32 self.Size = Struct.uint32
@ -188,10 +189,10 @@ class TPL(object):
header.unpack(data[:len(header)]) header.unpack(data[:len(header)])
pos = len(header) pos = len(header)
assert header.Magic == '\x00\x20\xAF\x30' assert header.Magic == 0x0020AF30
assert header.Size == 0xc assert header.Size == 0xc
for i in xrange(header.Count): for i in range(header.Count):
offs = self.TexOffsets() offs = self.TexOffsets()
offs.unpack(data[pos:pos+len(offs)]) offs.unpack(data[pos:pos+len(offs)])
pos += len(offs) pos += len(offs)
@ -221,26 +222,27 @@ class TPL(object):
elif format == 14: elif format == 14:
rgba = self.S3TC(data[texHeader.DataOff:], texHeader.Size) rgba = self.S3TC(data[texHeader.DataOff:], texHeader.Size)
else: else:
print 'Unknown texture format', format print('Unknown texture format', format)
if rgba == None: if rgba == None:
rgba = '\0\0\0\0' * texHeader.Size[0] * texHeader.Size[1] rgba = b'\0\0\0\0' * texHeader.Size[0] * texHeader.Size[1]
image = ImageData(texHeader.Size[1], texHeader.Size[0], 'RGBA', rgba) image = ImageData(texHeader.Size[1], texHeader.Size[0], 'RGBA', rgba)
print format print(format)
return image return image
def I4(self, data, (y, x)): def I4(self, data, xxx_todo_changeme):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 8): for i in range(0, y, 8):
for j in xrange(0, x, 8): for j in range(0, x, 8):
ofs = 0 ofs = 0
for k in xrange(8): for k in range(8):
off = min(x - j, 8) off = min(x - j, 8)
for sub in xrange(0, off, 2): for sub in range(0, off, 2):
texel = ord(data[inp]) texel = data[inp]
high, low = texel >> 4, texel & 0xF high, low = texel >> 4, texel & 0xF
if (outp + ofs + sub) < (x*y): if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = (high << 4) | (high << 20) | (high << 12) | 0xFF<<24 out[outp + ofs + sub] = (high << 4) | (high << 20) | (high << 12) | 0xFF<<24
@ -256,19 +258,20 @@ class TPL(object):
outp += off outp += off
outp += x * 7 outp += x * 7
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def I8(self, data, (y, x)): def I8(self, data, xxx_todo_changeme1):
out = [0 for i in xrange(x * y*2)] (y, x) = xxx_todo_changeme1
out = [0 for i in range(x * y*2)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 4): for j in range(0, x, 4):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 4) off = min(x - j, 4)
for sub in xrange(off): for sub in range(off):
texel = ord(data[inp]) texel = data[inp]
out[outp + ofs + sub] = (texel << 24) | (texel << 16) | (texel << 8) | 0xFF out[outp + ofs + sub] = (texel << 24) | (texel << 16) | (texel << 8) | 0xFF
inp += 1 inp += 1
@ -277,19 +280,20 @@ class TPL(object):
outp += off outp += off
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def IA4(self, data, (y, x)): def IA4(self, data, xxx_todo_changeme2):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme2
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 8): for j in range(0, x, 8):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 8) off = min(x - j, 8)
for sub in xrange(off): for sub in range(off):
texel = ord(data[inp]) texel = data[inp]
alpha, inte = texel >> 4, texel & 0xF alpha, inte = texel >> 4, texel & 0xF
if (outp + ofs + sub) < (x*y): if (outp + ofs + sub) < (x*y):
out[outp + ofs + sub] = (inte << 4) | (inte << 12) | (inte << 20) | (alpha << 28) out[outp + ofs + sub] = (inte << 4) | (inte << 12) | (inte << 20) | (alpha << 28)
@ -300,18 +304,19 @@ class TPL(object):
outp += off outp += off
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def IA8(self, data, (y, x)): def IA8(self, data, xxx_todo_changeme3):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme3
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 4): for j in range(0, x, 4):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 4) off = min(x - j, 4)
for sub in xrange(off): for sub in range(off):
if (outp + ofs + sub) < (x*y): if (outp + ofs + sub) < (x*y):
texel = Struct.uint16(data[inp:inp + 2], endian='>') texel = Struct.uint16(data[inp:inp + 2], endian='>')
p = (texel & 0xFF) p = (texel & 0xFF)
@ -326,18 +331,19 @@ class TPL(object):
outp += off outp += off
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def RGB565(self, data, (y, x)): def RGB565(self, data, xxx_todo_changeme4):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme4
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 4): for j in range(0, x, 4):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 4) off = min(x - j, 4)
for sub in xrange(off): for sub in range(off):
if (outp + ofs + sub) < (x*y): if (outp + ofs + sub) < (x*y):
texel = Struct.uint16(data[inp:inp + 2], endian='>') texel = Struct.uint16(data[inp:inp + 2], endian='>')
p = ((texel >> 11) & 0x1F) << 3 p = ((texel >> 11) & 0x1F) << 3
@ -352,18 +358,19 @@ class TPL(object):
outp += off outp += off
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def RGB5A3(self, data, (y, x)): def RGB5A3(self, data, xxx_todo_changeme5):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme5
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 4): for j in range(0, x, 4):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 4) off = min(x - j, 4)
for sub in xrange(off): for sub in range(off):
texel = Struct.uint16(data[inp:inp + 2], endian='>') texel = Struct.uint16(data[inp:inp + 2], endian='>')
if texel & 0x8000: if texel & 0x8000:
p = ((texel >> 10) & 0x1F) << 3 p = ((texel >> 10) & 0x1F) << 3
@ -384,18 +391,19 @@ class TPL(object):
outp += off outp += off
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def RGBA8(self, data, (y, x)): def RGBA8(self, data, xxx_todo_changeme6):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme6
out = [0 for i in range(x * y)]
outp = 0 outp = 0
inp = 0 inp = 0
for i in xrange(0, y, 4): for i in range(0, y, 4):
for j in xrange(0, x, 4): for j in range(0, x, 4):
ofs = 0 ofs = 0
for k in xrange(4): for k in range(4):
off = min(x - j, 4) off = min(x - j, 4)
for sub in xrange(off): for sub in range(off):
texel = Struct.uint16(data[inp:inp + 2], endian='>')<<16 texel = Struct.uint16(data[inp:inp + 2], endian='>')<<16
texel |= Struct.uint16(data[inp+32:inp + 34], endian='>') texel |= Struct.uint16(data[inp+32:inp + 34], endian='>')
if (outp + ofs + sub) < (x*y): if (outp + ofs + sub) < (x*y):
@ -408,7 +416,7 @@ class TPL(object):
inp += 32 inp += 32
outp += x * 3 outp += x * 3
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
def unpack_rgb565(self,texel): def unpack_rgb565(self,texel):
b = (texel&0x1f)<<3 b = (texel&0x1f)<<3
@ -420,24 +428,25 @@ class TPL(object):
return (0xff<<24) | (b<<16) | (g<<8) | r return (0xff<<24) | (b<<16) | (g<<8) | r
def icolor(self,a,b,fa,fb,fc): def icolor(self,a,b,fa,fb,fc):
c = 0 c = 0
for i in xrange(0,32,8): for i in range(0,32,8):
xa = (a>>i)&0xff xa = (a>>i)&0xff
xb = (b>>i)&0xff xb = (b>>i)&0xff
xc = min(255,max(0,int((xa*fa + xb*fb)/fc))) xc = min(255,max(0,int((xa*fa + xb*fb)/fc)))
c |= xc<<i c |= xc<<i
return c return c
def S3TC(self, data, (y, x)): def S3TC(self, data, xxx_todo_changeme7):
out = [0 for i in xrange(x * y)] (y, x) = xxx_todo_changeme7
out = [0 for i in range(x * y)]
TILE_WIDTH = 8 TILE_WIDTH = 8
TILE_HEIGHT = 8 TILE_HEIGHT = 8
inp = 0 inp = 0
outp = 0 outp = 0
for i in xrange(0, y, TILE_HEIGHT): for i in range(0, y, TILE_HEIGHT):
for j in xrange(0, x, TILE_WIDTH): for j in range(0, x, TILE_WIDTH):
maxw = min(x - j,TILE_WIDTH) maxw = min(x - j,TILE_WIDTH)
for k in xrange(2): for k in range(2):
for l in xrange(2): for l in range(2):
rgb = [0,0,0,0] rgb = [0,0,0,0]
texel1 = Struct.uint16(data[inp:inp + 2], endian='>') texel1 = Struct.uint16(data[inp:inp + 2], endian='>')
texel2 = Struct.uint16(data[inp + 2:inp + 4], endian='>') texel2 = Struct.uint16(data[inp + 2:inp + 4], endian='>')
@ -452,7 +461,7 @@ class TPL(object):
rgb[3] = 0 rgb[3] = 0
# color selection (00, 01, 10, 11) # color selection (00, 01, 10, 11)
cm = map(ord,data[inp+4:inp+8]) cm = list(data[inp+4:inp+8])
ofs = l*4 ofs = l*4
for n in range(4): for n in range(4):
if (ofs + outp)<(x*y): if (ofs + outp)<(x*y):
@ -471,7 +480,7 @@ class TPL(object):
outp += maxw - x * 8 outp += maxw - x * 8
outp += x * (TILE_HEIGHT - 1) outp += x * (TILE_HEIGHT - 1)
return ''.join(Struct.uint32(p) for p in out) return b''.join(Struct.uint32(p) for p in out)
class Object(object): class Object(object):
def __init__(self, name): def __init__(self, name):
@ -554,7 +563,7 @@ class ItemList(object):
pos = 8 pos = 8
count = self.__unpkcnt__(data[pos:]) count = self.__unpkcnt__(data[pos:])
pos = self.__getlistoff__(data[pos:]) pos = self.__getlistoff__(data[pos:])
for i in xrange(count): for i in range(count):
off = Struct.uint32(data[pos:pos+4], endian='>') + self.OFFSET off = Struct.uint32(data[pos:pos+4], endian='>') + self.OFFSET
if i == (count-1): if i == (count-1):
next = len(data) next = len(data)
@ -568,11 +577,11 @@ class ItemList(object):
def pack(self,extra=None): def pack(self,extra=None):
extradata = "" extradata = b""
if extra is not None: if extra is not None:
extradata = extra.pack() extradata = extra.pack()
data = "" data = b""
offsets = [] offsets = []
@ -583,9 +592,9 @@ class ItemList(object):
listlen = len(self.Items) * self.LSIZE listlen = len(self.Items) * self.LSIZE
head = self.__mkheader__() head = self.__mkheader__()
outdata = "" outdata = b""
if self.IS_ATOM: if self.IS_ATOM:
outdata += self.FOURCC + Struct.uint32((len(extradata) + listlen + len(data) + 8 + len(head) + 3) &(~3), endian='>') outdata += self.FOURCC.encode("ascii") + Struct.uint32((len(extradata) + listlen + len(data) + 8 + len(head) + 3) &(~3), endian='>')
outdata += head outdata += head
dataoff = len(outdata) + listlen - self.OFFSET dataoff = len(outdata) + listlen - self.OFFSET
@ -594,18 +603,18 @@ class ItemList(object):
for n in offsets: for n in offsets:
outdata += Struct.uint32(n + dataoff, endian='>') outdata += Struct.uint32(n + dataoff, endian='>')
if self.LSIZE > 4: if self.LSIZE > 4:
outdata += (self.LSIZE-4)*"\x00" outdata += (self.LSIZE-4)*b"\x00"
outdata += data outdata += data
outdata += extradata outdata += extradata
if len(outdata)%4 != 0: if len(outdata)%4 != 0:
outdata += (4-len(outdata)%4)*"\x00" outdata += (4-len(outdata)%4)*b"\x00"
return outdata return outdata
def __mkheader__(self): def __mkheader__(self):
return Struct.uint16(len(self.Items), endian='>') + "\x00\x00" return Struct.uint16(len(self.Items), endian='>') + b"\x00\x00"
def __unpkcnt__(self, data): def __unpkcnt__(self, data):
return Struct.uint16(data[0:2], endian='>') return Struct.uint16(data[0:2], endian='>')
@ -668,12 +677,12 @@ class Brlyt(object):
ItemList.__init__(self, data) ItemList.__init__(self, data)
def unpack_item(self, i, data): def unpack_item(self, i, data):
fn = data.split('\0', 1)[0] fn = data.split(b'\0', 1)[0].decode("ascii")
print fn print(fn)
tex = TPL(self.Archive.Files['./arc/timg/' + fn.lower()]).Textures[0] tex = TPL(self.Archive.Files['./arc/timg/' + fn.lower()]).Textures[0]
self.Items.append(Brlyt.BrlytTexture(fn, tex)) self.Items.append(Brlyt.BrlytTexture(fn, tex))
def pack_item(self, i, item): def pack_item(self, i, item):
return item.Name + "\0" return item.Name.encode("ascii") + b"\0"
class BrlytMAT1(ItemList): class BrlytMAT1(ItemList):
LSIZE = 4 LSIZE = 4
@ -709,20 +718,20 @@ class Brlyt(object):
self.m_8 = bool((value>>27) & 1) self.m_8 = bool((value>>27) & 1)
def show(self): def show(self):
print "Flags: %08x"%self.value print("Flags: %08x"%self.value)
print "ReserveGXMem(" print("ReserveGXMem(")
print " r4 =",self.NumTextures print(" r4 =",self.NumTextures)
print " r5 =",self.NumCoords print(" r5 =",self.NumCoords)
print " r6 =",self.m_2 print(" r6 =",self.m_2)
print " r7 =",self.m_3 print(" r7 =",self.m_3)
print " r8 =",self.m_4 print(" r8 =",self.m_4)
print " r9 =",self.m_5 print(" r9 =",self.m_5)
print " r10 =",self.m_6 print(" r10 =",self.m_6)
print " 0x8(%sp) =",self.m_7 print(" 0x8(%sp) =",self.m_7)
print " 0xC(%sp) =",self.m_8 print(" 0xC(%sp) =",self.m_8)
print " 0x10(%sp) =",self.m_9 print(" 0x10(%sp) =",self.m_9)
print " 0x14(%sp) =",self.m_10 print(" 0x14(%sp) =",self.m_10)
print ")" print(")")
def pack(self): def pack(self):
val = 0 val = 0
@ -743,7 +752,7 @@ class Brlyt(object):
__endian__ = Struct.BE __endian__ = Struct.BE
def __format__(self): def __format__(self):
self.Name = Struct.string(0x14) self.Name = Struct.string(0x14, stripNulls=True)
self.Color1 = Struct.uint16[4] self.Color1 = Struct.uint16[4]
self.Color2 = Struct.uint16[4] self.Color2 = Struct.uint16[4]
self.Color3 = Struct.uint16[4] self.Color3 = Struct.uint16[4]
@ -822,63 +831,63 @@ class Brlyt(object):
for i in range(self.FlagData.NumTextures): for i in range(self.FlagData.NumTextures):
texid = Struct.uint16(data[ptr:ptr+2], endian='>') texid = Struct.uint16(data[ptr:ptr+2], endian='>')
texcs = Struct.uint8(data[ptr+2], endian='>') texcs = data[ptr+2]
texct = Struct.uint8(data[ptr+3], endian='>') texct = data[ptr+3]
print " * Texture: %04x %d %d"%(texid,texcs,texct) print(" * Texture: %04x %d %d"%(texid,texcs,texct))
self.Textures.append((texid,texcs,texct)) self.Textures.append((texid,texcs,texct))
ptr += 4 ptr += 4
for i in range(self.FlagData.NumCoords): for i in range(self.FlagData.NumCoords):
dat = [] dat = []
for j in range(5): for j in range(5):
dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>')) dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>'))
print " * Coords: [",', '.join(["%f"%x for x in dat]),"]" print(" * Coords: [",', '.join(["%f"%x for x in dat]),"]")
ptr += 0x14 ptr += 0x14
self.TextureCoords.append(dat) self.TextureCoords.append(dat)
for i in range(self.FlagData.m_2): for i in range(self.FlagData.m_2):
dat = Struct.uint32(data[ptr:ptr+4], endian='>') dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthB.append(dat) self.SthB.append(dat)
print " * SthB: %08x"%dat print(" * SthB: %08x"%dat)
ptr += 0x04 ptr += 0x04
if self.FlagData.m_7: if self.FlagData.m_7:
self.SthI = Struct.uint32(data[ptr:ptr+4], endian='>') self.SthI = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthI: %08x"%self.SthI print(" SthI: %08x"%self.SthI)
ptr += 0x04 ptr += 0x04
if self.FlagData.m_8: if self.FlagData.m_8:
self.SthJ = Struct.uint32(data[ptr:ptr+4], endian='>') self.SthJ = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthJ: %08x"%self.SthJ print(" SthJ: %08x"%self.SthJ)
ptr += 0x04 ptr += 0x04
if self.FlagData.m_4: if self.FlagData.m_4:
self.SthC = Struct.uint32(data[ptr:ptr+4], endian='>') self.SthC = Struct.uint32(data[ptr:ptr+4], endian='>')
print " SthC: %08x"%self.SthC print(" SthC: %08x"%self.SthC)
ptr += 0x04 ptr += 0x04
for i in range(self.FlagData.m_6): for i in range(self.FlagData.m_6):
dat = [] dat = []
for j in range(5): for j in range(5):
dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>')) dat.append(Struct.float(data[ptr+j*4:ptr+j*4+4], endian='>'))
self.SthD.append(dat) self.SthD.append(dat)
print " * SthD: [",', '.join(["%f"%x for x in dat]),"]" print(" * SthD: [",', '.join(["%f"%x for x in dat]),"]")
ptr += 0x14 ptr += 0x14
for i in range(self.FlagData.m_5): for i in range(self.FlagData.m_5):
dat = Struct.uint32(data[ptr:ptr+4], endian='>') dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthE.append(dat) self.SthE.append(dat)
print " * SthE: %08x"%dat print(" * SthE: %08x"%dat)
ptr += 0x04 ptr += 0x04
for i in range(self.FlagData.m_3): for i in range(self.FlagData.m_3):
dat = [] dat = []
for j in range(4): for j in range(4):
dat.append(Struct.uint32(data[ptr+j*4:ptr+j*4+4], endian='>')) dat.append(Struct.uint32(data[ptr+j*4:ptr+j*4+4], endian='>'))
self.SthF.append(dat) self.SthF.append(dat)
print " * SthF: [",', '.join(["%08x"%x for x in dat]),"]" print(" * SthF: [",', '.join(["%08x"%x for x in dat]),"]")
ptr += 0x10 ptr += 0x10
if self.FlagData.m_9: if self.FlagData.m_9:
dat = Struct.uint32(data[ptr:ptr+4], endian='>') dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthG = dat self.SthG = dat
print " SthG: %08x"%dat print(" SthG: %08x"%dat)
ptr += 0x04 ptr += 0x04
if self.FlagData.m_10: if self.FlagData.m_10:
dat = Struct.uint32(data[ptr:ptr+4], endian='>') dat = Struct.uint32(data[ptr:ptr+4], endian='>')
self.SthH = dat self.SthH = dat
print " SthH: %08x"%dat print(" SthH: %08x"%dat)
ptr += 0x04 ptr += 0x04
#assert ptr == len(data) #assert ptr == len(data)
@ -903,7 +912,7 @@ class Brlyt(object):
hdr = Brlyt.BrlytMatHeader() hdr = Brlyt.BrlytMatHeader()
hdr.Name = self.Name + "\x00"*(0x14-len(self.Name)) hdr.Name = self.Name.encode("ascii") + b"\x00"*(0x14-len(self.Name))
hdr.Color1 = self.Color1 hdr.Color1 = self.Color1
hdr.Color2 = self.Color2 hdr.Color2 = self.Color2
hdr.Color3 = self.Color3 hdr.Color3 = self.Color3
@ -947,7 +956,7 @@ class Brlyt(object):
StdAtom.__format__(self) StdAtom.__format__(self)
self.Flags = Struct.uint16 self.Flags = Struct.uint16
self.Alpha = Struct.uint16 self.Alpha = Struct.uint16
self.Name = Struct.string(0x18) self.Name = Struct.string(0x18, stripNulls=True)
self.Coords = Struct.float[10] self.Coords = Struct.float[10]
class BrlytPIC1(BrlytPAN1): class BrlytPIC1(BrlytPAN1):
@ -979,17 +988,17 @@ class Brlyt(object):
pos = 0 pos = 0
header = self.BrlytHeader() header = self.BrlytHeader()
header.unpack(data[:len(header)]) header.unpack(data[:len(header)])
print "BRLYT header:" print("BRLYT header:")
wii.chexdump(data[:len(header)]) wii.chexdump(data[:len(header)])
print " unk1: %08x"%header.Unk print(" unk1: %08x"%header.Unk)
print " unkc: %08x"%header.UnkCount print(" unkc: %08x"%header.UnkCount)
pos += len(header) pos += len(header)
print " %d atoms"%header.AtomCount print(" %d atoms"%header.AtomCount)
assert header.Magic == 'RLYT' assert header.Magic == 'RLYT'
for i in xrange(header.AtomCount): for i in range(header.AtomCount):
atom = StdAtom() atom = StdAtom()
atom.unpack(data[pos:pos+len(atom)]) atom.unpack(data[pos:pos+len(atom)])
@ -1011,7 +1020,7 @@ class Brlyt(object):
elif atom.FourCC == "grp1": elif atom.FourCC == "grp1":
self.GRP1(atomdata) self.GRP1(atomdata)
else: else:
print "Unknown FOURCC:",atom.FourCC print("Unknown FOURCC:",atom.FourCC)
wii.chexdump(atomdata) wii.chexdump(atomdata)
pos += atom.Size pos += atom.Size
@ -1024,7 +1033,7 @@ class Brlyt(object):
atom = Brlyt.BrlytPIC1() atom = Brlyt.BrlytPIC1()
else: else:
atom = Brlyt.BrlytPAN1() atom = Brlyt.BrlytPAN1()
atom.Name = object.Name + "\x00"*(0x18-len(object.Name)) atom.Name = object.Name.encode("ascii") + b"\x00"*(0x18-len(object.Name))
atom.Alpha = int(object.Alpha * 256) atom.Alpha = int(object.Alpha * 256)
atom.Flags = object.Flags atom.Flags = object.Flags
atom.Coords = object.Coords atom.Coords = object.Coords
@ -1032,17 +1041,17 @@ class Brlyt(object):
atom.Flags2 = object.Flags2 atom.Flags2 = object.Flags2
atom.Material = object.Material atom.Material = object.Material
atom.unk = object.Unk atom.unk = object.Unk
atom.MaterialCoords = sum(map(list,object.MaterialCoords),[]) atom.MaterialCoords = sum(list(map(list,object.MaterialCoords)),[])
data = atom.pack() data = atom.pack()
if len(object.Children) > 0: if len(object.Children) > 0:
atoms += 2 atoms += 2
data += "pas1\x00\x00\x00\x08" data += b"pas1\x00\x00\x00\x08"
for child in object.Children: for child in object.Children:
ac, dc = self._PackObject(child) ac, dc = self._PackObject(child)
data += dc data += dc
atoms += ac atoms += ac
data += "pae1\x00\x00\x00\x08" data += b"pae1\x00\x00\x00\x08"
return atoms, data return atoms, data
else: else:
raise ValueError("Unknown object: "+repr(object)) raise ValueError("Unknown object: "+repr(object))
@ -1055,7 +1064,7 @@ class Brlyt(object):
header.Magic = "RLYT" header.Magic = "RLYT"
header.AtomCount = 0 header.AtomCount = 0
data = "" data = b""
data += self.mkLYT1() data += self.mkLYT1()
header.AtomCount+=1 header.AtomCount+=1
@ -1070,7 +1079,7 @@ class Brlyt(object):
header.AtomCount += atoms header.AtomCount += atoms
#uuugly. TODO: fix this crap. #uuugly. TODO: fix this crap.
data += "grp1\x00\x00\x00\x1cRootGroup\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" data += b"grp1\x00\x00\x00\x1cRootGroup\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
header.AtomCount += 1 header.AtomCount += 1
header.Size = len(data) + len(header) header.Size = len(data) + len(header)
@ -1098,7 +1107,7 @@ class Brlyt(object):
lyt1.unpack(data) lyt1.unpack(data)
self.Width = lyt1.Width self.Width = lyt1.Width
self.Height = lyt1.Height self.Height = lyt1.Height
print "LYT1: %f x %f, flag %d"%(self.Width, self.Height, lyt1.Flag) print("LYT1: %f x %f, flag %d"%(self.Width, self.Height, lyt1.Flag))
self.Renderer.Create(int(self.Width), int(self.Height)) self.Renderer.Create(int(self.Width), int(self.Height))
def TXL1(self, data): def TXL1(self, data):
@ -1107,13 +1116,13 @@ class Brlyt(object):
i.create_texture() i.create_texture()
def ApplyMask(self, image, mask): def ApplyMask(self, image, mask):
print "Making mask:",image,mask print("Making mask:",image,mask)
print image.width,image.height,mask.width,mask.height print(image.width,image.height,mask.width,mask.height)
if image.height != mask.height or image.width != mask.width: if image.height != mask.height or image.width != mask.width:
raise ValueError("Mask dimensions must be equal to mask dimensions") raise ValueError("Mask dimensions must be equal to mask dimensions")
newdata = [0 for x in xrange(image.height * image.width * 4)] newdata = [0 for x in range(image.height * image.width * 4)]
for pix in xrange(image.height * image.width): for pix in range(image.height * image.width):
newdata[pix*4 + 0] = image.data[pix*4 + 0] newdata[pix*4 + 0] = image.data[pix*4 + 0]
newdata[pix*4 + 1] = image.data[pix*4 + 1] newdata[pix*4 + 1] = image.data[pix*4 + 1]
newdata[pix*4 + 2] = image.data[pix*4 + 2] newdata[pix*4 + 2] = image.data[pix*4 + 2]
@ -1136,8 +1145,8 @@ class Brlyt(object):
wii.chexdump(data) wii.chexdump(data)
pane = Brlyt.BrlytPAN1() pane = Brlyt.BrlytPAN1()
pane.unpack(data) pane.unpack(data)
p = Pane(pane.Name.split('\0',1)[0], pane.Flags, pane.Alpha/256.0, pane.Coords) p = Pane(pane.Name, pane.Flags, pane.Alpha/256.0, pane.Coords)
print 'Pane %s (flags %04x, alpha %f): ' % (p.Name, pane.Flags, pane.Alpha),pane.Coords print('Pane %s (flags %04x, alpha %f): ' % (p.Name, pane.Flags, pane.Alpha),pane.Coords)
self._addpane(p) self._addpane(p)
def PAS1(self, data): def PAS1(self, data):
@ -1145,11 +1154,11 @@ class Brlyt(object):
if self.CurPane is None: if self.CurPane is None:
raise ValueError("No current pane!") raise ValueError("No current pane!")
self.PanePath.append(self.CurPane) self.PanePath.append(self.CurPane)
print "Pane start:",'.'.join(map(str,self.PanePath)) print("Pane start:",'.'.join(map(str,self.PanePath)))
self.CurPane = None self.CurPane = None
def PAE1(self, data): def PAE1(self, data):
print "Pane end:",'.'.join(map(str,self.PanePath)) print("Pane end:",'.'.join(map(str,self.PanePath)))
self.PanePath = self.PanePath[:-1] self.PanePath = self.PanePath[:-1]
def PIC1(self, data): def PIC1(self, data):
@ -1159,25 +1168,25 @@ class Brlyt(object):
mc = [] mc = []
for i in range(4): for i in range(4):
mc.append(pic.MaterialCoords[i*2:i*2+2]) mc.append(pic.MaterialCoords[i*2:i*2+2])
print mc print(mc)
p = Picture(pic.Name.split("\0",1)[0], pic.Flags, pic.Alpha/256.0, pic.Coords, pic.unk, pic.Material, pic.Flags2, mc) p = Picture(pic.Name, pic.Flags, pic.Alpha/256.0, pic.Coords, pic.unk, pic.Material, pic.Flags2, mc)
print repr(p.Name) print(repr(p.Name))
mat = self.Materials[pic.Material] mat = self.Materials[pic.Material]
if mat is not None: if mat is not None:
self._addpane(p) self._addpane(p)
else: else:
print 'Picture %s with null material!' print('Picture %s with null material!')
def GRP1(self, data): def GRP1(self, data):
wii.chexdump(data) wii.chexdump(data)
if len(data) < 0x1c: if len(data) < 0x1c:
pass pass
lang = data[0x8:0x18].split('\0', 1)[0] lang = data[0x8:0x18].split(b'\0', 1)[0]
nitems = Struct.uint16(data[0x18:0x1a], endian='>') nitems = Struct.uint16(data[0x18:0x1a], endian='>')
p = 0x1c p = 0x1c
items = [] items = []
for i in xrange(nitems): for i in range(nitems):
items.append(data[p:].split('\0', 1)[0]) items.append(data[p:].split(b'\0', 1)[0])
p += 0x10 p += 0x10
for i in items: for i in items:
try: try:
@ -1222,7 +1231,7 @@ class Brlan(object):
assert header.Magic == 'RLAN' assert header.Magic == 'RLAN'
for i in xrange(header.AtomCount): for i in range(header.AtomCount):
atom = StdAtom() atom = StdAtom()
atom.unpack(data[pos:pos+len(atom)]) atom.unpack(data[pos:pos+len(atom)])
atomdata = data[pos:pos+atom.Size] atomdata = data[pos:pos+atom.Size]
@ -1231,7 +1240,7 @@ class Brlan(object):
if atom.FourCC == 'pai1': if atom.FourCC == 'pai1':
self.PAI1(atomdata) self.PAI1(atomdata)
else: else:
print "Unknown animation atom: %s"%atom.FourCC print("Unknown animation atom: %s"%atom.FourCC)
class BrlanPAI1(ItemList): class BrlanPAI1(ItemList):
LSIZE=4 LSIZE=4
@ -1240,7 +1249,7 @@ class Brlan(object):
HDRLEN=12 HDRLEN=12
def unpack(self, data): def unpack(self, data):
self.FrameCount = Struct.uint16(data[8:10], endian='>') self.FrameCount = Struct.uint16(data[8:10], endian='>')
print self.FrameCount print(self.FrameCount)
ItemList.unpack(self, data) ItemList.unpack(self, data)
def __mkheader__(self): def __mkheader__(self):
hdr = Struct.uint16(self.FrameCount, endian='>') hdr = Struct.uint16(self.FrameCount, endian='>')
@ -1292,13 +1301,13 @@ class Brlan(object):
else: else:
ItemList.__init__(self, data) ItemList.__init__(self, data)
def unpack(self, data): def unpack(self, data):
self.Name = data[:0x14].split("\0",1)[0] self.Name = data[:0x14].split(b"\0",1)[0].decode("ascii")
print self.Name print(self.Name)
ItemList.unpack(self, data) ItemList.unpack(self, data)
def __mkheader__(self): def __mkheader__(self):
hdr = self.Name + "\x00" * (0x14-len(self.Name)) hdr = self.Name.encode("ascii") + b"\x00" * (0x14-len(self.Name))
hdr += Struct.uint8(len(self.Items), endian='>') hdr += Struct.uint8(len(self.Items), endian='>')
hdr += "\x00\x00\x00" hdr += b"\x00\x00\x00"
return hdr return hdr
def __unpkcnt__(self, data): def __unpkcnt__(self, data):
return Struct.uint8(data[0x14:0x15], endian='>') return Struct.uint8(data[0x14:0x15], endian='>')
@ -1330,7 +1339,7 @@ class Brlan(object):
self.item = 0 self.item = 0
def __iter__(self): def __iter__(self):
return self return self
def next(self): def __next__(self):
if self.item == len(self.cl.Items): if self.item == len(self.cl.Items):
raise StopIteration() raise StopIteration()
else: else:
@ -1344,13 +1353,13 @@ class Brlan(object):
else: else:
ItemList.__init__(self, data) ItemList.__init__(self, data)
def unpack(self, data): def unpack(self, data):
self.Type = data[0:4] self.Type = data[0:4].decode("ascii")
print " ",self.Type print(" ",self.Type)
ItemList.unpack(self, data) ItemList.unpack(self, data)
def __mkheader__(self): def __mkheader__(self):
hdr = self.Type hdr = self.Type.encode("ascii")
hdr += Struct.uint8(len(self.Items), endian='>') hdr += Struct.uint8(len(self.Items), endian='>')
hdr += "\x00\x00\x00" hdr += b"\x00\x00\x00"
return hdr return hdr
def __unpkcnt__(self, data): def __unpkcnt__(self, data):
return Struct.uint8(data[4:5], endian='>') return Struct.uint8(data[4:5], endian='>')
@ -1383,18 +1392,18 @@ class Brlan(object):
self.Unk = Struct.uint16(data[2:4], endian='>') self.Unk = Struct.uint16(data[2:4], endian='>')
count = Struct.uint16(data[4:6], endian='>') count = Struct.uint16(data[4:6], endian='>')
pos = Struct.uint32(data[8:12], endian='>') pos = Struct.uint32(data[8:12], endian='>')
print " ",self.Type print(" ",self.Type)
if self.Unk == 0x200: if self.Unk == 0x200:
print " Triplets:" print(" Triplets:")
for i in range(count): for i in range(count):
F = Struct.float(data[pos+0:pos+4], endian='>') F = Struct.float(data[pos+0:pos+4], endian='>')
P = Struct.float(data[pos+4:pos+8], endian='>') P = Struct.float(data[pos+4:pos+8], endian='>')
D = Struct.float(data[pos+8:pos+12], endian='>') D = Struct.float(data[pos+8:pos+12], endian='>')
print " %11f %11f %11f"%(F,P,D) print(" %11f %11f %11f"%(F,P,D))
self.Triplets.append((F,P,D)) self.Triplets.append((F,P,D))
pos += 12 pos += 12
else: else:
print " Unknown format: %04x"%self.Unk print(" Unknown format: %04x"%self.Unk)
def pack(self, offset): def pack(self, offset):
self.Triplets.sort(key=lambda x: x[0]) self.Triplets.sort(key=lambda x: x[0])
t = self.Triplets t = self.Triplets
@ -1411,7 +1420,7 @@ class Brlan(object):
out = Struct.uint16(self.Type, endian='>') out = Struct.uint16(self.Type, endian='>')
out += Struct.uint16(self.Unk, endian='>') out += Struct.uint16(self.Unk, endian='>')
out += Struct.uint16(len(self.Triplets), endian='>') out += Struct.uint16(len(self.Triplets), endian='>')
out += "\x00\x00" out += b"\x00\x00"
out += Struct.uint32(0xc, endian='>') out += Struct.uint32(0xc, endian='>')
for F,P,D in self.Triplets: for F,P,D in self.Triplets:
out += Struct.float(F-offset, endian='>') out += Struct.float(F-offset, endian='>')
@ -1511,7 +1520,7 @@ class Renderer(object):
def Create(self, width, height): def Create(self, width, height):
self.Width = width self.Width = width
self.Height = height self.Height = height
print "Render: %f x %f"%(self.Width,self.Height) print("Render: %f x %f"%(self.Width,self.Height))
self.Window = BannerWindow(self.Width, self.Height) self.Window = BannerWindow(self.Width, self.Height)
self.Window.set_exclusive_mouse(False) self.Window.set_exclusive_mouse(False)
@ -1523,7 +1532,7 @@ class Renderer(object):
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_BLEND) glEnable(GL_BLEND)
glEnable(GL_TEXTURE_2D) glEnable(GL_TEXTURE_2D)
clock.set_fps_limit(60) #clock.set_fps_limit(60)
def Render(self, item, wireframe=False): def Render(self, item, wireframe=False):
@ -1638,7 +1647,7 @@ class Renderer(object):
for set in self.Brlan.Anim: for set in self.Brlan.Anim:
for clss in set: for clss in set:
for anim in clss: for anim in clss:
#print set.Name, clss.Type, anim.Type, anim.calc(frame), frame #print(set.Name, clss.Type, anim.Type, anim.calc(frame), frame)
if clss.Type == Brlan.A_COORD: if clss.Type == Brlan.A_COORD:
self.Brlyt.Objects[set.Name].Coords[anim.Type] = anim.calc(frame) self.Brlyt.Objects[set.Name].Coords[anim.Type] = anim.calc(frame)
elif clss.Type == Brlan.A_PARM: elif clss.Type == Brlan.A_PARM:
@ -1647,8 +1656,8 @@ class Renderer(object):
def MainLoop(self, loop): def MainLoop(self, loop):
frame = 0 frame = 0
print "Starting mainloop: loop =",loop print("Starting mainloop: loop =",loop)
print "Length in frames:",self.Brlan.Anim.FrameCount print("Length in frames:",self.Brlan.Anim.FrameCount)
while not self.Window.has_exit: while not self.Window.has_exit:
self.Window.dispatch_events() self.Window.dispatch_events()
self.Window.clear() self.Window.clear()
@ -1660,17 +1669,17 @@ class Renderer(object):
self.Render(self.Brlyt.RootPane,False) self.Render(self.Brlyt.RootPane,False)
#self.Render(self.Brlyt.RootPane,True) #self.Render(self.Brlyt.RootPane,True)
#clock.tick() clock.tick()
self.Window.flip() self.Window.flip()
if self.Brlan is not None: if self.Brlan is not None:
self.Animate(frame) self.Animate(frame)
if frame >= self.Brlan.Anim.FrameCount: if frame >= self.Brlan.Anim.FrameCount:
if not loop: if not loop:
print "Animation done!" print("Animation done!")
return True return True
else: else:
print "Looping..." print("Looping...")
frame = -1 frame = -1
frame += 1 frame += 1
@ -1690,7 +1699,7 @@ class Alameda(object):
def __init__(self, fn, type='icon'): def __init__(self, fn, type='icon'):
renderer = Renderer() renderer = Renderer()
fp = file(fn, 'rb') fp = open(fn, 'rb')
imet = self.IMETHeader() imet = self.IMETHeader()
try: try:
@ -1703,7 +1712,7 @@ class Alameda(object):
imet.unpack(fp.read(len(imet))) imet.unpack(fp.read(len(imet)))
assert imet.IMET == 'IMET' assert imet.IMET == 'IMET'
print 'English title: %s' % imet.Names[1] print('English title: %s' % imet.Names[1])
root = U8(fp.read()) root = U8(fp.read())
@ -1722,14 +1731,15 @@ class Alameda(object):
else: else:
banner = U8(IMD5(root.Files['./meta/banner.bin'])) banner = U8(IMD5(root.Files['./meta/banner.bin']))
renderer.Brlyt = Brlyt(banner, banner.Files['./arc/blyt/banner.brlyt'], renderer) renderer.Brlyt = Brlyt(banner, banner.Files['./arc/blyt/banner.brlyt'], renderer)
loop = not banner.Files.has_key('./arc/anim/banner_start.brlan') loop = './arc/anim/banner_start.brlan' not in banner.Files
if not loop: if not loop:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner_start.brlan']) renderer.Brlan = Brlan(banner.Files['./arc/anim/banner_start.brlan'])
loop_anim = Brlan(banner.Files['./arc/anim/banner_loop.brlan'])
else: else:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner.brlan']) renderer.Brlan = Brlan(banner.Files['./arc/anim/banner.brlan'])
if renderer.MainLoop(loop) and type == 'banner' and not loop: if renderer.MainLoop(loop) and type == 'banner' and not loop:
renderer.Brlan = Brlan(banner.Files['./arc/anim/banner_loop.brlan']) renderer.Brlan = loop_anim
renderer.MainLoop(True) renderer.MainLoop(True)
if __name__=='__main__': if __name__=='__main__':

View File

@ -4,7 +4,7 @@ class StructType(tuple):
def __getitem__(self, value): def __getitem__(self, value):
return [self] * value return [self] * value
def __call__(self, value, endian='<'): def __call__(self, value, endian='<'):
if isinstance(value, str): if isinstance(value, bytes):
return struct.unpack(endian + tuple.__getitem__(self, 0), value[:tuple.__getitem__(self, 1)])[0] return struct.unpack(endian + tuple.__getitem__(self, 0), value[:tuple.__getitem__(self, 1)])[0]
else: else:
return struct.pack(endian + tuple.__getitem__(self, 0), value) return struct.pack(endian + tuple.__getitem__(self, 0), value)
@ -12,8 +12,8 @@ class StructType(tuple):
class StructException(Exception): class StructException(Exception):
pass pass
class Struct(object): class Struct:
__slots__ = ('__attrs__', '__baked__', '__defs__', '__endian__', '__next__', '__sizes__', '__values__') __slots__ = ('__attrs__', '__baked__', '__defs__', '__next__', '__sizes__', '__values__')
int8 = StructType(('b', 1)) int8 = StructType(('b', 1))
uint8 = StructType(('B', 1)) uint8 = StructType(('B', 1))
@ -49,7 +49,7 @@ class Struct(object):
else: else:
sys.settrace(self.__trace__) sys.settrace(self.__trace__)
func() func()
for name in func.func_code.co_varnames: for name in func.__code__.co_varnames:
value = self.__frame__.f_locals[name] value = self.__frame__.f_locals[name]
self.__setattr__(name, value) self.__setattr__(name, value)
@ -186,11 +186,13 @@ class Struct(object):
if len(temp) != size: if len(temp) != size:
raise StructException('Expected %i byte string, got %i' % (size, len(temp))) raise StructException('Expected %i byte string, got %i' % (size, len(temp)))
if stripNulls:
temp = temp.rstrip(b'\0')
if encoding != None: if encoding != None:
temp = temp.decode(encoding) temp = temp.decode(encoding)
else:
if stripNulls: temp = temp.decode("ascii")
temp = temp.rstrip('\0')
if attrs[0] == '*': if attrs[0] == '*':
name = attrs[1:] name = attrs[1:]
@ -231,7 +233,7 @@ class Struct(object):
def pack(self): def pack(self):
arraypos, arrayname = None, None arraypos, arrayname = None, None
ret = '' ret = b''
for i in range(len(self.__defs__)): for i in range(len(self.__defs__)):
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i] sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
@ -251,9 +253,11 @@ class Struct(object):
if encoding != None: if encoding != None:
temp = temp.encode(encoding) temp = temp.encode(encoding)
elif isinstance(temp, str):
temp = temp.encode("ascii")
temp = temp[:size] temp = temp[:size]
ret += temp + ('\0' * (size - len(temp))) ret += temp + (b'\0' * (size - len(temp)))
elif sdef == Struct: elif sdef == Struct:
if attrs[0] == '*': if attrs[0] == '*':
if arrayname != attrs: if arrayname != attrs:
@ -299,16 +303,16 @@ if __name__=='__main__':
self.hax = HaxStruct self.hax = HaxStruct
test = TestStruct() test = TestStruct()
test.unpack('\xEF\xBE\xAD\xDE\x00\x00\x80\x3Fdeadbeef\x04\x00\x00\x00test\xCA\xFE\xBA\xBE\xBE\xBA\xFE\xCA') test.unpack(b'\xEF\xBE\xAD\xDE\x00\x00\x80\x3Fdeadbeef\x04\x00\x00\x00test\xCA\xFE\xBA\xBE\xBE\xBA\xFE\xCA')
assert test.foo == 0xDEADBEEF assert test.foo == 0xDEADBEEF
assert test.bar == 1.0 assert test.bar == 1.0
assert test.baz == 'deadbeef' assert test.baz == b'deadbeef'
assert test.omg == 4 assert test.omg == 4
assert test.wtf == 'test' assert test.wtf == b'test'
assert test.hax.thing1 == 0xBEBAFECA assert test.hax.thing1 == 0xBEBAFECA
assert test.hax.thing2 == 0xCAFEBABE assert test.hax.thing2 == 0xCAFEBABE
print 'Tests successful' print('Tests successful')
""" """
@Struct.LE @Struct.LE

View File

@ -1,3 +1,3 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
from wii import * from .wii import *

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2 #!/usr/bin/python3
# Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org> # Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
# Copyright 2008 Hector Martin <marcan@marcansoft.com> # Copyright 2008 Hector Martin <marcan@marcansoft.com>
# Licensed under the terms of the GNU GPL, version 2 # Licensed under the terms of the GNU GPL, version 2
@ -12,11 +12,11 @@ except ImportError:
from Crypto.Util.number import bytes_to_long, long_to_bytes from Crypto.Util.number import bytes_to_long, long_to_bytes
# y**2 + x*y = x**3 + x + b # y**2 + x*y = x**3 + x + b
ec_b = "\x00\x66\x64\x7e\xde\x6c\x33\x2c\x7f\x8c\x09\x23\xbb\x58\x21"+\ ec_b = (b"\x00\x66\x64\x7e\xde\x6c\x33\x2c\x7f\x8c\x09\x23\xbb\x58\x21"+
"\x3b\x33\x3b\x20\xe9\xce\x42\x81\xfe\x11\x5f\x7d\x8f\x90\xad" b"\x3b\x33\x3b\x20\xe9\xce\x42\x81\xfe\x11\x5f\x7d\x8f\x90\xad")
def hexdump(s,sep=""): def hexdump(s,sep=""):
return sep.join(map(lambda x: "%02x"%ord(x),s)) return sep.join(["%02x"%ord(x) for x in s])
def bhex(s,sep=""): def bhex(s,sep=""):
return hexdump(long_to_bytes(s,30),sep) return hexdump(long_to_bytes(s,30),sep)
@ -41,20 +41,20 @@ class ByteArray(array):
else: else:
array.__setitem__(self, item, value & 0xFF) array.__setitem__(self, item, value & 0xFF)
def __long__(self): def __long__(self):
return bytes_to_long(self.tostring()) return bytes_to_long(self.tobytes())
def __str__(self): def __str__(self):
return ''.join(["%02x"%ord(x) for x in self.tostring()]) return ''.join(["%02x"%x for x in self.tobytes()])
def __repr__(self): def __repr__(self):
return "ByteArray('%s')"%''.join(["\\x%02x"%ord(x) for x in self.tostring()]) return "ByteArray('%s')"%''.join(["\\x%02x"%x for x in self.tobytes()])
class ELT_PY: class ELT_PY:
SIZEBITS=233 SIZEBITS=233
SIZE=(SIZEBITS+7)/8 SIZE=(SIZEBITS+7)/8
square = ByteArray("\x00\x01\x04\x05\x10\x11\x14\x15\x40\x41\x44\x45\x50\x51\x54\x55") square = ByteArray(b"\x00\x01\x04\x05\x10\x11\x14\x15\x40\x41\x44\x45\x50\x51\x54\x55")
def __init__(self, initializer=None): def __init__(self, initializer=None):
if isinstance(initializer, long) or isinstance(initializer, int): if isinstance(initializer, int) or isinstance(initializer, int):
self.d = ByteArray(long_to_bytes(initializer,self.SIZE)) self.d = ByteArray(long_to_bytes(initializer,self.SIZE))
elif isinstance(initializer, str): elif isinstance(initializer, bytes):
self.d = ByteArray(initializer) self.d = ByteArray(initializer)
elif isinstance(initializer, ByteArray): elif isinstance(initializer, ByteArray):
self.d = ByteArray(initializer) self.d = ByteArray(initializer)
@ -80,12 +80,12 @@ class ELT_PY:
return cmp(self.d,other.d) return cmp(self.d,other.d)
def __long__(self): def __long__(self):
return long(self.d) return int(self.d)
def __repr__(self): def __repr__(self):
return repr(self.d).replace("ByteArray","ELT") return repr(self.d).replace("ByteArray","ELT")
def __str__(self): def __bytes__(self):
return str(self.d) return bytes(self.d)
def __nonzero__(self): def __bool__(self):
for x in self.d: for x in self.d:
if x != 0: if x != 0:
return True return True
@ -184,21 +184,21 @@ class ELT_PY:
def __setitem__(self,item,value): def __setitem__(self,item,value):
self.d[item] = value self.d[item] = value
def tobignum(self): def tobignum(self):
return bytes_to_long(self.d.tostring()) return bytes_to_long(self.d.tobytes())
def tobytes(self): def tobytes(self):
return self.d.tostring() return self.d.tobytes()
class ELT_C(ELT_PY): class ELT_C(ELT_PY):
def __mul__(self,other): def __mul__(self,other):
if not isinstance(other,ELT): if not isinstance(other,ELT):
return NotImplemented return NotImplemented
return ELT(_ec.elt_mul(self.d.tostring(),other.d.tostring())) return ELT(_ec.elt_mul(self.d.tobytes(),other.d.tobytes()))
def __rdiv__(self,other): def __rdiv__(self,other):
if other != 1: if other != 1:
return ELT_PY.__rdiv__(self,other) return ELT_PY.__rdiv__(self,other)
return ELT(_ec.elt_inv(self.d.tostring())) return ELT(_ec.elt_inv(self.d.tobytes()))
def _square(self): def _square(self):
return ELT(_ec.elt_square(self.d.tostring())) return ELT(_ec.elt_square(self.d.tobytes()))
if fastelt: if fastelt:
ELT = ELT_C ELT = ELT_C
@ -207,7 +207,7 @@ else:
class Point: class Point:
def __init__(self,x,y=None): def __init__(self,x,y=None):
if isinstance(x,str) and (y is None) and (len(x) == 60): if isinstance(x,bytes) and (y is None) and (len(x) == 60):
self.x = ELT(x[:30]) self.x = ELT(x[:30])
self.y = ELT(x[30:]) self.y = ELT(x[30:])
elif isinstance(x,Point): elif isinstance(x,Point):
@ -292,7 +292,7 @@ class Point:
return "(%s,%s)"%(str(self.x),str(self.y)) return "(%s,%s)"%(str(self.x),str(self.y))
def __repr__(self): def __repr__(self):
return "Point"+str(self) return "Point"+str(self)
def __nonzero__(self): def __bool__(self):
return self.x or self.y return self.x or self.y
def tobytes(self): def tobytes(self):
return self.x.tobytes() + self.y.tobytes() return self.x.tobytes() + self.y.tobytes()
@ -305,15 +305,15 @@ def bn_inv(a,N):
# order of the addition group of points # order of the addition group of points
ec_N = bytes_to_long( ec_N = bytes_to_long(
"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+\ b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"+
"\x13\xe9\x74\xe7\x2f\x8a\x69\x22\x03\x1d\x26\x03\xcf\xe0\xd7") b"\x13\xe9\x74\xe7\x2f\x8a\x69\x22\x03\x1d\x26\x03\xcf\xe0\xd7")
# base point # base point
ec_G = Point( ec_G = Point(
"\x00\xfa\xc9\xdf\xcb\xac\x83\x13\xbb\x21\x39\xf1\xbb\x75\x5f"+ b"\x00\xfa\xc9\xdf\xcb\xac\x83\x13\xbb\x21\x39\xf1\xbb\x75\x5f"+
"\xef\x65\xbc\x39\x1f\x8b\x36\xf8\xf8\xeb\x73\x71\xfd\x55\x8b"+ b"\xef\x65\xbc\x39\x1f\x8b\x36\xf8\xf8\xeb\x73\x71\xfd\x55\x8b"+
"\x01\x00\x6a\x08\xa4\x19\x03\x35\x06\x78\xe5\x85\x28\xbe\xbf"+ b"\x01\x00\x6a\x08\xa4\x19\x03\x35\x06\x78\xe5\x85\x28\xbe\xbf"+
"\x8a\x0b\xef\xf8\x67\xa7\xca\x36\x71\x6f\x7e\x01\xf8\x10\x52") b"\x8a\x0b\xef\xf8\x67\xa7\xca\x36\x71\x6f\x7e\x01\xf8\x10\x52")
def generate_ecdsa(k, sha): def generate_ecdsa(k, sha):
k = bytes_to_long(k) k = bytes_to_long(k)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
# Copyright 2008 Hector Martin <marcan@marcansoft.com> # Copyright 2008 Hector Martin <marcan@marcansoft.com>
# Licensed under the terms of the GNU GPL, version 2 # Licensed under the terms of the GNU GPL, version 2
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
@ -21,7 +21,7 @@ except ImportError:
from Crypto.Util.number import bytes_to_long, long_to_bytes from Crypto.Util.number import bytes_to_long, long_to_bytes
from Crypto.Signature import pkcs1_15 from Crypto.Signature import pkcs1_15
import ec from . import ec
WII_RSA4096 = 0 WII_RSA4096 = 0
WII_RSA2048 = 1 WII_RSA2048 = 1
@ -30,13 +30,13 @@ WII_ECDSA = 2
sigtypes = [ "RSA-4096", "RSA-2048", "EC-DSA" ] sigtypes = [ "RSA-4096", "RSA-2048", "EC-DSA" ]
def load_rsa_key(issuer): def load_rsa_key(issuer):
print "Loading private key for %s" % issuer print("Loading private key for %s" % issuer)
path = os.path.join(os.environ["HOME"], ".wii", "dpki", issuer + ".pem") path = os.path.join(os.environ["HOME"], ".wii", "dpki", issuer + ".pem")
return RSA.importKey(open(path, "r").read()) return RSA.importKey(open(path, "r").read())
signkeyfuncs = [ load_rsa_key, load_rsa_key, None ] signkeyfuncs = [ load_rsa_key, load_rsa_key, None ]
NULL_IV = "\x00"*16 NULL_IV = b"\x00"*16
keylist = [ keylist = [
"common-key", "common-key",
@ -86,13 +86,13 @@ known_titles_noregion = {
} }
def hexdump(s,sep=" "): def hexdump(s,sep=" "):
return sep.join(map(lambda x: "%02x"%ord(x),s)) return sep.join(["%02x"%x for x in s])
def strcmp(s1,s2): def strcmp(s1,s2):
clen = min(len(s1),len(s2)) clen = min(len(s1),len(s2))
for i in range(clen): for i in range(clen):
if s1[i] == "\0" and s2[i] == "\0": if s1[i] == 0 and s2[i] == 0:
return True return True
if s1[i] != s2[i]: if s1[i] != s2[i]:
return False return False
@ -101,10 +101,10 @@ def strcmp(s1,s2):
def ascii(s): def ascii(s):
s2 = "" s2 = ""
for c in s: for c in s:
if ord(c)<0x20 or ord(c)>0x7e: if c<0x20 or c>0x7e:
s2 += "." s2 += "."
else: else:
s2 += c s2 += chr(c)
return s2 return s2
def pad(s,c,l): def pad(s,c,l):
@ -114,15 +114,10 @@ def pad(s,c,l):
def chexdump(s): def chexdump(s):
for i in range(0,len(s),16): for i in range(0,len(s),16):
print "%08x %s %s |%s|"%(i,pad(hexdump(s[i:i+8],' ')," ",23),pad(hexdump(s[i+8:i+16],' ')," ",23),pad(ascii(s[i:i+16])," ",16)) print("%08x %s %s |%s|"%(i,pad(hexdump(s[i:i+8],' ')," ",23),pad(hexdump(s[i+8:i+16],' ')," ",23),pad(ascii(s[i:i+16])," ",16)))
def getcstring(s): def getcstring(s):
s2 = "" return s.split(b"\x00")[0].decode("ascii")
for c in s:
if c == "\x00":
break
s2 += c
return s2
def align(n,a): def align(n,a):
if a == 0: if a == 0:
@ -132,10 +127,10 @@ def align(n,a):
return n return n
def rangel(n,s): def rangel(n,s):
return range(n,n+s) return list(range(n,n+s))
def xrangel(n,s): def xrangel(n,s):
return xrange(n,n+s) return range(n,n+s)
def falign(f,a): def falign(f,a):
f.seek(align(f.tell(),a)) f.seek(align(f.tell(),a))
@ -200,7 +195,7 @@ def loadkeys(path = None):
try: try:
keys[key] = open(path + os.sep + key, "rb").read() keys[key] = open(path + os.sep + key, "rb").read()
except: except:
print "Warning: failed to load key %s"%key print("Warning: failed to load key %s"%key)
def loadkeys_dpki(path = None): def loadkeys_dpki(path = None):
if path is None: if path is None:
@ -210,7 +205,7 @@ def loadkeys_dpki(path = None):
def parse_certs(blob): def parse_certs(blob):
certs = {} certs = {}
certlist = [] certlist = []
while blob != "": while blob != b"":
cert = WiiCert(blob) cert = WiiCert(blob)
certs[cert.name] = cert certs[cert.name] = cert
certlist.append(cert) certlist.append(cert)
@ -250,7 +245,7 @@ class WiiPKAlgo:
code = ">"+codes[bytes] code = ">"+codes[bytes]
matchlen = len(match) matchlen = len(match)
for pad in xrange(0, 256**bytes): for pad in range(0, 256**bytes):
pad += 0x4612512415125316 pad += 0x4612512415125316
pad %= 256**bytes pad %= 256**bytes
padsig = signature + pack(code, pad) padsig = signature + pack(code, pad)
@ -270,11 +265,11 @@ class WiiRSA(WiiPKAlgo):
def get_digest(self, signature): def get_digest(self, signature):
lsig = bytes_to_long(signature) lsig = bytes_to_long(signature)
if lsig >= self.n: if lsig >= self.n:
print "Warning: signature larger than modulus, using sig%modulus as signature" print("Warning: signature larger than modulus, using sig%modulus as signature")
ldec = pow(lsig, self.e, self.n) ldec = pow(lsig, self.e, self.n)
dec = long_to_bytes(ldec) dec = long_to_bytes(ldec)
pad = len(signature) - len(dec) pad = len(signature) - len(dec)
dec = "\x00"*pad+dec dec = b"\x00"*pad+dec
return dec[-20:] return dec[-20:]
def sign(self, data, key): def sign(self, data, key):
@ -340,11 +335,11 @@ class WiiDisc:
return self.partitions return self.partitions
def showinfo(self): def showinfo(self):
print "Game %s, maker %s, magic %08x: %s"%(self.gamecode, self.makercode, self.magic, self.gamename) print("Game %s, maker %s, magic %08x: %s"%(self.gamecode, self.makercode, self.magic, self.gamename))
self.read_partitions() self.read_partitions()
print "%d partitions in ISO:"%len(self.partitions) print("%d partitions in ISO:"%len(self.partitions))
for p_num,p_dat in enumerate(self.partitions): for p_num,p_dat in enumerate(self.partitions):
print " [%2d] 0x%010x (%08x)"%(p_num,p_dat[0],p_dat[1]) print(" [%2d] 0x%010x (%08x)"%(p_num,p_dat[0],p_dat[1]))
class WiiSigned: class WiiSigned:
sigsizes = [512, 256, 60] sigsizes = [512, 256, 60]
@ -370,7 +365,7 @@ class WiiSigned:
def update(self): def update(self):
self.data = pack(">I",self.sigtype+0x10000) + self.signature self.data = pack(">I",self.sigtype+0x10000) + self.signature
self.data += "\x00" * (self.body_offset - len(self.data)) self.data += b"\x00" * (self.body_offset - len(self.data))
self.data += self.body self.data += self.body
def parse(self): def parse(self):
@ -388,7 +383,7 @@ class WiiSigned:
raise ValueError("Signature type %s does not match certificate type %s!"%(sigtypes[self.sigtype],sigtypes[cert.key_type])) raise ValueError("Signature type %s does not match certificate type %s!"%(sigtypes[self.sigtype],sigtypes[cert.key_type]))
return cert.pkalgo.get_digest(self.sigtype, self.signature) return cert.pkalgo.get_digest(self.sigtype, self.signature)
def brute_sha(self, match = "\x00", fillshort = None): def brute_sha(self, match = b"\x00", fillshort = None):
l = len(match) l = len(match)
if fillshort is None: if fillshort is None:
@ -408,7 +403,7 @@ class WiiSigned:
if len(issuer) > 39: if len(issuer) > 39:
raise ValueError("issuer name too long!") raise ValueError("issuer name too long!")
self.issuer = issuer.split("-") self.issuer = issuer.split("-")
self.body = issuer + "\x00" * (0x40 - len(issuer)) + self.body[0x40:] self.body = issuer + b"\x00" * (0x40 - len(issuer)) + self.body[0x40:]
self.update() self.update()
def update_signature(self, sig): def update_signature(self, sig):
@ -416,7 +411,7 @@ class WiiSigned:
self.data = pack(">I",self.sigtype+0x10000) + self.signature + self.data[len(sig) + 4:] self.data = pack(">I",self.sigtype+0x10000) + self.signature + self.data[len(sig) + 4:]
def null_signature(self): def null_signature(self):
self.signature = "\x00"*len(self.signature) self.signature = b"\x00"*len(self.signature)
self.data = pack(">I",self.sigtype+0x10000) + self.signature + self.data[len(self.signature) + 4:] self.data = pack(">I",self.sigtype+0x10000) + self.signature + self.data[len(self.signature) + 4:]
def sign(self,certs): def sign(self,certs):
@ -453,22 +448,22 @@ class WiiSigned:
if cert.pkalgo.can_get_digest: if cert.pkalgo.can_get_digest:
signhash = cert.pkalgo.get_digest(self.signature) signhash = cert.pkalgo.get_digest(self.signature)
if myhash == signhash: if myhash == signhash:
print it+"%s signed by %s using %s: %s [OK]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [OK]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
elif strcmp(myhash, signhash): elif strcmp(myhash, signhash):
print it+"%s signed by %s using %s: %s [BUG]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [BUG]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
print it+" Signature hash: %s"%hexdump(signhash) print(it+" Signature hash: %s"%hexdump(signhash))
else: else:
print it+"%s signed by %s using %s: %s [FAIL]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [FAIL]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
print it+" Signature hash: %s"%hexdump(signhash) print(it+" Signature hash: %s"%hexdump(signhash))
else: else:
sigok = cert.pkalgo.check_digest(self.signature,myhash) sigok = cert.pkalgo.check_digest(self.signature,myhash)
if sigok: if sigok:
print it+"%s signed by %s using %s: %s [OK]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [OK]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
else: else:
print it+"%s signed by %s using %s: %s [FAIL]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [FAIL]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
except KeyError: except KeyError:
print it+"%s signed by %s using %s: %s [ISSUER NOT FOUND]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)) print(it+"%s signed by %s using %s: %s [ISSUER NOT FOUND]"%(self.type, "-".join(self.issuer), sigtypes[self.sigtype], hexdump(myhash)))
class WiiTik(WiiSigned): class WiiTik(WiiSigned):
def __init__(self, data): def __init__(self, data):
@ -480,7 +475,7 @@ class WiiTik(WiiSigned):
def parse(self): def parse(self):
self.title_key_enc = self.body[0x7f:0x8f] self.title_key_enc = self.body[0x7f:0x8f]
self.title_id = self.body[0x9c:0xa4] self.title_id = self.body[0x9c:0xa4]
self.title_key_iv = self.title_id + "\x00"*8 self.title_key_iv = self.title_id + b"\x00"*8
self.common_key_index = ord(self.body[0xb1:0xb2]) self.common_key_index = ord(self.body[0xb1:0xb2])
try: try:
@ -489,7 +484,7 @@ class WiiTik(WiiSigned):
elif self.common_key_index == 1: elif self.common_key_index == 1:
key = keys["korean-key"] key = keys["korean-key"]
else: else:
print "WARNING: OLD FAKESIGNED TICKET WITH BAD KEY OFFSET, ASSUMING NORMAL COMMON KEY" print("WARNING: OLD FAKESIGNED TICKET WITH BAD KEY OFFSET, ASSUMING NORMAL COMMON KEY")
key = keys["common-key"] key = keys["common-key"]
aes = AES.new(key, AES.MODE_CBC, self.title_key_iv) aes = AES.new(key, AES.MODE_CBC, self.title_key_iv)
self.title_key = aes.decrypt(self.title_key_enc) self.title_key = aes.decrypt(self.title_key_enc)
@ -505,13 +500,13 @@ class WiiTik(WiiSigned):
return 0x164 return 0x164
def showinfo(self, it=""): def showinfo(self, it=""):
print it+"ETicket: " print(it+"ETicket: ")
print it+" Title ID: "+repr(self.title_id) print(it+" Title ID: "+repr(self.title_id))
print it+" Title key IV: "+hexdump(self.title_key_iv) print(it+" Title key IV: "+hexdump(self.title_key_iv))
print it+" Title key (encrypted): "+hexdump(self.title_key_enc) print(it+" Title key (encrypted): "+hexdump(self.title_key_enc))
print it+" Common key index: %d" % self.common_key_index print(it+" Common key index: %d" % self.common_key_index)
if self.title_key is not None: if self.title_key is not None:
print it+" Title key (decrypted): "+hexdump(self.title_key) print(it+" Title key (decrypted): "+hexdump(self.title_key))
class WiiPartitionOffsets: class WiiPartitionOffsets:
def __init__(self, data): def __init__(self, data):
@ -528,9 +523,9 @@ class WiiPartitionOffsets:
self.data_size = unpack(">I",self.data[0x18:0x1c])[0]<<2 self.data_size = unpack(">I",self.data[0x18:0x1c])[0]<<2
def showinfo(self, it=""): def showinfo(self, it=""):
print it+"TMD @ 0x%x [0x%x], Certs @ 0x%x [0x%x], H3 @ 0x%x, Data @ 0x%x [0x%x]"%( print(it+"TMD @ 0x%x [0x%x], Certs @ 0x%x [0x%x], H3 @ 0x%x, Data @ 0x%x [0x%x]"%(
self.tmd_offset, self.tmd_size, self.cert_offset, self.cert_size, self.tmd_offset, self.tmd_size, self.cert_offset, self.cert_size,
self.h3_offset, self.data_offset, self.data_size) self.h3_offset, self.data_offset, self.data_size))
def update(self): def update(self):
self.data = pack(">II",self.tmd_size, self.tmd_offset>>2) self.data = pack(">II",self.tmd_size, self.tmd_offset>>2)
@ -600,20 +595,20 @@ class WiiTmd(WiiSigned):
self.update() self.update()
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"TMD: " print(it+"TMD: ")
print it+" Versions: %d, CA CRL %d, Signer CRL %d, System %d-%d"%( print(it+" Versions: %d, CA CRL %d, Signer CRL %d, System %d-%d"%(
self.version,self.ca_crl_version,self.signer_crl_version,self.sys_version>>32,self.sys_version&0xffffffff) self.version,self.ca_crl_version,self.signer_crl_version,self.sys_version>>32,self.sys_version&0xffffffff))
print it+" Title ID: %s-%s (%s-%s)"%(hexdump(self.title_id[:4],''),hexdump(self.title_id[4:],''),repr(self.title_id[:4]),repr(self.title_id[4:])) print(it+" Title ID: %s-%s (%s-%s)"%(hexdump(self.title_id[:4],''),hexdump(self.title_id[4:],''),repr(self.title_id[:4]),repr(self.title_id[4:])))
print it+" Title Type: %d"%self.title_type print(it+" Title Type: %d"%self.title_type)
print it+" Group ID: %s"%repr(self.group_id) print(it+" Group ID: %s"%repr(self.group_id))
print it+" Access Rights: 0x%08x"%self.access_rights print(it+" Access Rights: 0x%08x"%self.access_rights)
print it+" Title Version: 0x%x"%self.title_version print(it+" Title Version: 0x%x"%self.title_version)
print it+" Boot Index: %d"%self.boot_index print(it+" Boot Index: %d"%self.boot_index)
print it+" Contents:" print(it+" Contents:")
print it+" ID Index Type Size Hash" print(it+" ID Index Type Size Hash")
for ct in self.get_content_records(): for ct in self.get_content_records():
print it+" %08X %-5d 0x%-5x %-12s %s"%(ct.cid, ct.index, ct.ftype, "0x%x"%ct.size,hexdump(ct.sha)) print(it+" %08X %-5d 0x%-5x %-12s %s"%(ct.cid, ct.index, ct.ftype, "0x%x"%ct.size,hexdump(ct.sha)))
class WiiCert(WiiSigned): class WiiCert(WiiSigned):
key_sizes = [516, 260, 60] key_sizes = [516, 260, 60]
@ -638,7 +633,7 @@ class WiiCert(WiiSigned):
self.pkalgo = self.pk_types[self.key_type](self.key) self.pkalgo = self.pk_types[self.key_type](self.key)
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"%s (%s)"%(self.name,sigtypes[self.key_type]) print(it+"%s (%s)"%(self.name,sigtypes[self.key_type]))
class WiiRootCert: class WiiRootCert:
def __init__(self, data): def __init__(self, data):
@ -650,7 +645,7 @@ class WiiRootCert:
self.key_type = 0 self.key_type = 0
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"%s (%s)"%(self.name,sigtypes[self.key_type]) print(it+"%s (%s)"%(self.name,sigtypes[self.key_type]))
class WiiPartition: class WiiPartition:
BLOCKS_PER_SUBGROUP = 8 BLOCKS_PER_SUBGROUP = 8
@ -732,37 +727,37 @@ class WiiPartition:
self.f.write(self.offsets.data) self.f.write(self.offsets.data)
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"Wii Partition at 0x%010x:"%(self.offset) print(it+"Wii Partition at 0x%010x:"%(self.offset))
self.offsets.showinfo(" ") self.offsets.showinfo(" ")
self.tik.showinfo(it+" ") self.tik.showinfo(it+" ")
self.tik.showsig(self.certs,it+" ") self.tik.showsig(self.certs,it+" ")
self.tmd.showinfo(it+" ") self.tmd.showinfo(it+" ")
self.tmd.showsig(self.certs,it+" ") self.tmd.showsig(self.certs,it+" ")
if self.checkh4hash(): if self.checkh4hash():
print it+" H4 hash check passed" print(it+" H4 hash check passed")
else: else:
print it+" H4 check failed: SHA1(H3) = "+hexdump(self.geth4hash()) print(it+" H4 check failed: SHA1(H3) = "+hexdump(self.geth4hash()))
print it+" Data:" print(it+" Data:")
print it+" Blocks: %d"%self.data_blocks print(it+" Blocks: %d"%self.data_blocks)
print it+" Subgroups: %d (plus %d blocks)"%(self.data_subgroups,self.extra_subgroup_blocks) print(it+" Subgroups: %d (plus %d blocks)"%(self.data_subgroups,self.extra_subgroup_blocks))
print it+" Groups: %d (plus %d blocks)"%(self.data_groups,self.extra_group_blocks) print(it+" Groups: %d (plus %d blocks)"%(self.data_groups,self.extra_group_blocks))
self.showcerts(it+" ") self.showcerts(it+" ")
def showcerts(self,it=""): def showcerts(self,it=""):
print it+"Certificates: " print(it+"Certificates: ")
for cert in self.certlist: for cert in self.certlist:
cert.showinfo(it+" - ") cert.showinfo(it+" - ")
cert.showsig(self.certs,it+" ") cert.showsig(self.certs,it+" ")
def geth4hash(self): def geth4hash(self):
return SHA.new(''.join(self.h3) + "\x00"*self.TAIL_H3).digest() return SHA.new(b''.join(self.h3) + b"\x00"*self.TAIL_H3).digest()
def checkh4hash(self): def checkh4hash(self):
return self.geth4hash() == self.tmd.get_content_records()[0].sha return self.geth4hash() == self.tmd.get_content_records()[0].sha
def updateh3(self): def updateh3(self):
self._seek(self.offsets.h3_offset) self._seek(self.offsets.h3_offset)
self.f.write(''.join(self.h3)) self.f.write(b''.join(self.h3))
def updateh4(self): def updateh4(self):
cr = self.tmd.get_content_records()[0] cr = self.tmd.get_content_records()[0]
@ -903,7 +898,7 @@ class WiiPartition:
else: else:
raise ValueError("Attempted to read group past the end of the partition data") raise ValueError("Attempted to read group past the end of the partition data")
data = "" data = b""
for i in range(nblocks): for i in range(nblocks):
data += self.readblock(blockoff+i) data += self.readblock(blockoff+i)
return data return data
@ -919,7 +914,7 @@ class WiiPartition:
if groupnum == self.data_groups and self.extra_group_blocks > 0 and len(data) == (self.extra_group_blocks * self.PLAIN_BLOCK_SIZE): if groupnum == self.data_groups and self.extra_group_blocks > 0 and len(data) == (self.extra_group_blocks * self.PLAIN_BLOCK_SIZE):
blocks = self.extra_group_blocks blocks = self.extra_group_blocks
writesize = blocks * self.CIPHER_BLOCK_SIZE writesize = blocks * self.CIPHER_BLOCK_SIZE
data += "\x00" * (self.PLAIN_BLOCK_SIZE * self.BLOCKS_PER_GROUP - blocks) data += b"\x00" * (self.PLAIN_BLOCK_SIZE * self.BLOCKS_PER_GROUP - blocks)
else: else:
raise ValueError("Attempted to write group past the end of the partition data") raise ValueError("Attempted to write group past the end of the partition data")
else: else:
@ -930,12 +925,12 @@ class WiiPartition:
h0 = [] h0 = []
h1 = [] h1 = []
h2 = "" h2 = b""
for subgroup in range(self.SUBGROUPS_PER_GROUP): for subgroup in range(self.SUBGROUPS_PER_GROUP):
bh1 = "" bh1 = b""
sh0 = [] sh0 = []
for block in range(self.BLOCKS_PER_SUBGROUP): for block in range(self.BLOCKS_PER_SUBGROUP):
bh0 = "" bh0 = b""
for chunk in range(self.DATA_CHUNKS_PER_BLOCK): for chunk in range(self.DATA_CHUNKS_PER_BLOCK):
offset = subgroup * self.PLAIN_SUBGROUP_SIZE + block * self.PLAIN_BLOCK_SIZE + chunk * self.DATA_CHUNK_SIZE offset = subgroup * self.PLAIN_SUBGROUP_SIZE + block * self.PLAIN_BLOCK_SIZE + chunk * self.DATA_CHUNK_SIZE
bh0 += SHA.new(data[offset:offset+self.DATA_CHUNK_SIZE]).digest() bh0 += SHA.new(data[offset:offset+self.DATA_CHUNK_SIZE]).digest()
@ -946,16 +941,16 @@ class WiiPartition:
h2 += SHA.new(bh1).digest() h2 += SHA.new(bh1).digest()
h3 = SHA.new(h2).digest() h3 = SHA.new(h2).digest()
data_out = "" data_out = b""
for subgroup in range(self.SUBGROUPS_PER_GROUP): for subgroup in range(self.SUBGROUPS_PER_GROUP):
for block in range(self.BLOCKS_PER_SUBGROUP): for block in range(self.BLOCKS_PER_SUBGROUP):
shablock = "" shablock = ""
shablock += h0[subgroup][block] shablock += h0[subgroup][block]
shablock += "\x00"*20 shablock += b"\x00"*20
shablock += h1[subgroup] shablock += h1[subgroup]
shablock += "\x00"*32 shablock += b"\x00"*32
shablock += h2 shablock += h2
shablock += "\x00"*32 shablock += b"\x00"*32
assert len(shablock) == self.SHA_SIZE, "sha block size messed up" assert len(shablock) == self.SHA_SIZE, "sha block size messed up"
aes = AES.new(self.tik.title_key, AES.MODE_CBC, NULL_IV) aes = AES.new(self.tik.title_key, AES.MODE_CBC, NULL_IV)
shablock = aes.encrypt(shablock) shablock = aes.encrypt(shablock)
@ -1019,7 +1014,7 @@ class WiiCachedPartition(WiiPartition):
def _dprint(self, s, *args): def _dprint(self, s, *args):
if self.debug: if self.debug:
print s%tuple(args) print(s%tuple(args))
def _readblock(self, blocknum): def _readblock(self, blocknum):
self._dprint("_readblock(0x%x)",blocknum) self._dprint("_readblock(0x%x)",blocknum)
@ -1174,7 +1169,7 @@ class WiiCachedPartition(WiiPartition):
hb = self.readblock(bstart - 1) hb = self.readblock(bstart - 1)
hb = hb[:hdroff] + data[:header] + hb[hdroff+header:] hb = hb[:hdroff] + data[:header] + hb[hdroff+header:]
self.writeblock(bstart - 1, hb) self.writeblock(bstart - 1, hb)
for block in xrange(bnum): for block in range(bnum):
self.writeblock(block+bstart, data[header+block*self.PLAIN_BLOCK_SIZE:header+(block+1)*self.PLAIN_BLOCK_SIZE]) self.writeblock(block+bstart, data[header+block*self.PLAIN_BLOCK_SIZE:header+(block+1)*self.PLAIN_BLOCK_SIZE])
if footer: if footer:
fb = self.readblock(bstart+bnum) fb = self.readblock(bstart+bnum)
@ -1246,11 +1241,11 @@ class WiiApploader:
self.extrafooter = data[0x20+self.textsize+self.trailersize:] self.extrafooter = data[0x20+self.textsize+self.trailersize:]
def showinfo(self, it=""): def showinfo(self, it=""):
print it+"Apploader:" print(it+"Apploader:")
print it+" Date: %s"%self.date print(it+" Date: %s"%self.date)
print it+" Entrypoint: 0x%08x"%self.entry print(it+" Entrypoint: 0x%08x"%self.entry)
print it+" Text size: 0x%x"%self.textsize print(it+" Text size: 0x%x"%self.textsize)
print it+" Trailer size: 0x%x"%self.trailersize print(it+" Trailer size: 0x%x"%self.trailersize)
class WiiPartitionData: class WiiPartitionData:
def __init__(self, partition): def __init__(self, partition):
@ -1291,11 +1286,11 @@ class WiiPartitionData:
self.dol = dol self.dol = dol
self.part.write(self.doloff, dol) self.part.write(self.doloff, dol)
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"Partition data:" print(it+"Partition data:")
print it+" Game Name: %s"%self.gamename print(it+" Game Name: %s"%self.gamename)
print it+" Offsets: DOL @ 0x%x [0x%x], Apploader @ 0x%x [0x%x], FST @ 0x%x [0x%x]"%(self.doloff, self.dolsize, 0x2440, self.apploadersize, self.fstoff, self.fstsize) print(it+" Offsets: DOL @ 0x%x [0x%x], Apploader @ 0x%x [0x%x], FST @ 0x%x [0x%x]"%(self.doloff, self.dolsize, 0x2440, self.apploadersize, self.fstoff, self.fstsize))
self.apploader.showinfo(it+" ") self.apploader.showinfo(it+" ")
print it+"FST:" print(it+"FST:")
self.fst.show(it+" ") self.fst.show(it+" ")
class FakeFile: class FakeFile:
@ -1381,7 +1376,7 @@ class WiiWad:
self.f.seek(4) self.f.seek(4)
wt = self.f.read(2) wt = self.f.read(2)
if wt == "\x00\x00": if wt == b"\x00\x00":
self.read_boot2hdr() self.read_boot2hdr()
else: else:
self.read_hdr() self.read_hdr()
@ -1389,7 +1384,7 @@ class WiiWad:
certdata = self.f.read(self.cert_len) certdata = self.f.read(self.cert_len)
self.certlist = [] self.certlist = []
self.certs = {} self.certs = {}
while certdata != "": while certdata != b"":
cert = WiiCert(certdata) cert = WiiCert(certdata)
self.certs[cert.name] = cert self.certs[cert.name] = cert
self.certlist.append(cert) self.certlist.append(cert)
@ -1415,8 +1410,8 @@ class WiiWad:
self.f.write(self.tik.data) self.f.write(self.tik.data)
def showinfo(self,it=""): def showinfo(self,it=""):
print it+"Wii Wad:" print(it+"Wii Wad:")
print it+" Header 0x%x Type %s Certs 0x%x Tik 0x%x TMD 0x%x Data 0x%x @ 0x%x Footer 0x%x"%(self.hdr_len, repr(self.wadtype), self.cert_len, self.tik_len, self.tmd_len, self.data_len, self.data_off, self.footer_len) print(it+" Header 0x%x Type %s Certs 0x%x Tik 0x%x TMD 0x%x Data 0x%x @ 0x%x Footer 0x%x"%(self.hdr_len, repr(self.wadtype), self.cert_len, self.tik_len, self.tmd_len, self.data_len, self.data_off, self.footer_len))
self.tik.showinfo(it+" ") self.tik.showinfo(it+" ")
self.tik.showsig(self.certs,it+" ") self.tik.showsig(self.certs,it+" ")
self.tmd.showinfo(it+" ") self.tmd.showinfo(it+" ")
@ -1426,15 +1421,15 @@ class WiiWad:
d = self.getcontent(ct.index) d = self.getcontent(ct.index)
sha = SHA.new(d).digest() sha = SHA.new(d).digest()
if sha != ct.sha: if sha != ct.sha:
print it+" SHA-1 for content %08x is invalid:"%ct.cid, hexdump(sha) print(it+" SHA-1 for content %08x is invalid:"%ct.cid, hexdump(sha))
print it+" Expected:",hexdump(ct.sha) print(it+" Expected:",hexdump(ct.sha))
allok=False allok=False
if allok: if allok:
print it+" All content SHA-1 hashes are valid" print(it+" All content SHA-1 hashes are valid")
self.showcerts(it+" ") self.showcerts(it+" ")
def showcerts(self,it=""): def showcerts(self,it=""):
print it+"Certificates: " print(it+"Certificates: ")
for cert in self.certlist: for cert in self.certlist:
cert.showinfo(it+" - ") cert.showinfo(it+" - ")
cert.showsig(self.certs,it+" ") cert.showsig(self.certs,it+" ")
@ -1447,7 +1442,7 @@ class WiiWad:
if encrypted: if encrypted:
return data return data
iv = pack(">H",index)+"\x00"*14 iv = pack(">H",index)+b"\x00"*14
aes = AES.new(self.tik.title_key, AES.MODE_CBC, iv) aes = AES.new(self.tik.title_key, AES.MODE_CBC, iv)
return aes.decrypt(data)[:ct.size] return aes.decrypt(data)[:ct.size]
@ -1470,14 +1465,14 @@ class WiiWadMaker(WiiWad):
self.tik_len = len(self.tik.data) self.tik_len = len(self.tik.data)
# if boot2, set type to "ib" # if boot2, set type to "ib"
if self.tmd.title_id == "\x00\x00\x00\x01\x00\x00\x00\x01": if self.tmd.title_id == b"\x00\x00\x00\x01\x00\x00\x00\x01":
if nandwad: if nandwad:
self.wadtype = 0 self.wadtype = 0
self.ALIGNMENT = 0 self.ALIGNMENT = 0
else: else:
self.wadtype = "ib" self.wadtype = b"ib"
else: else:
self.wadtype = "Is" self.wadtype = b"Is"
self.data_len = 0 self.data_len = 0
self.footer = footer self.footer = footer
@ -1509,16 +1504,16 @@ class WiiWadMaker(WiiWad):
cr.size = len(data) cr.size = len(data)
self.tmd.update_content_record(i,cr) self.tmd.update_content_record(i,cr)
if len(data)%16 != 0: if len(data)%16 != 0:
data += "\x00"*(16-len(data)%16) data += b"\x00"*(16-len(data)%16)
falign(self.f,0x40) falign(self.f,0x40)
iv = pack(">H",cr.index)+"\x00"*14 iv = pack(">H",cr.index)+b"\x00"*14
aes = AES.new(self.tik.title_key, AES.MODE_CBC, iv) aes = AES.new(self.tik.title_key, AES.MODE_CBC, iv)
self.f.write(aes.encrypt(data)) self.f.write(aes.encrypt(data))
falign(self.f,0x40) falign(self.f,0x40)
def adddata_encrypted(self, data): def adddata_encrypted(self, data):
if len(data)%16 != 0: if len(data)%16 != 0:
data += "\x00"*(16-len(data)%16) data += b"\x00"*(16-len(data)%16)
falign(self.f,0x40) falign(self.f,0x40)
self.f.write(data) self.f.write(data)
falign(self.f,0x40) falign(self.f,0x40)
@ -1531,7 +1526,7 @@ class WiiWadMaker(WiiWad):
falign(self.f,self.ALIGNMENT) falign(self.f,self.ALIGNMENT)
self.f.truncate() self.f.truncate()
if pad: if pad:
self.f.write("\x00"*0x40) self.f.write(b"\x00"*0x40)
self.updatetmd() self.updatetmd()
self.f.seek(0) self.f.seek(0)
if self.wadtype == 0: if self.wadtype == 0:
@ -1641,9 +1636,9 @@ class WiiFSTFile:
self.off = off self.off = off
self.size = size self.size = size
def show(self, it=""): def show(self, it=""):
print "%s%s @ 0x%x [0x%x]"%(it,self.name,self.off,self.size) print("%s%s @ 0x%x [0x%x]"%(it,self.name,self.off,self.size))
def generate(self, offset, stringoff, parent, dataoff, wiigcm=False): def generate(self, offset, stringoff, parent, dataoff, wiigcm=False):
stringdata = self.name + "\x00" stringdata = self.name.encode("ascii") + b"\x00"
off = self.off+dataoff off = self.off+dataoff
if wiigcm: if wiigcm:
off >>= 2 off >>= 2
@ -1688,9 +1683,9 @@ class WiiFSTDir:
raise ValueError("WTF") raise ValueError("WTF")
def show(self, it=""): def show(self, it=""):
if self.name == "": if self.name == "":
print it+"/" print(it+"/")
else: else:
print it+self.name+"/" print(it+self.name+"/")
for i in self.entries: for i in self.entries:
i.show(it+self.name+"/") i.show(it+self.name+"/")
def dump(self): def dump(self):
@ -1698,15 +1693,15 @@ class WiiFSTDir:
def add(self,x): def add(self,x):
self.entries.append(x) self.entries.append(x)
def generate(self, offset, stringoff, parent, dataoff, wiigcm=False): def generate(self, offset, stringoff, parent, dataoff, wiigcm=False):
stringdata = self.name + "\x00" stringdata = self.name.encode("ascii") + b"\x00"
myoff = offset myoff = offset
mysoff = stringoff mysoff = stringoff
stringoff+=len(stringdata) stringoff+=len(stringdata)
offset += 1 offset += 1
subdata="" subdata=b""
for e in self.entries: for e in self.entries:
d, s = e.generate(offset, stringoff, myoff, dataoff, wiigcm) d, s = e.generate(offset, stringoff, myoff, dataoff, wiigcm)
offset += len(d)/12 offset += len(d)//12
stringoff += len(s) stringoff += len(s)
stringdata += s stringdata += s
subdata += d subdata += d

View File

@ -1,11 +1,11 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys import sys
import re import re
import pywii as wii import pywii as wii
hash = wii.SHA.new(open(sys.argv[2]).read()).digest().encode("hex") hash = wii.SHA.new(open(sys.argv[2]).read()).digest().encode("hex")
f = open(sys.argv[1], "r") f = open(sys.argv[1], "rb")
data = f.read() data = f.read()
f.close() f.close()
data = re.sub('@SHA1SUM@', hash, data) data = re.sub('@SHA1SUM@', hash, data)
open(sys.argv[3], "w").write(data) open(sys.argv[3], "wb").write(data)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path, struct import sys, os, os.path, struct
import pywii as wii import pywii as wii

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path, struct import sys, os, os.path, struct
import pywii as wii import pywii as wii
@ -7,6 +7,7 @@ fstb = wii.WiiFSTBuilder(0x20)
fstb.addfrom(sys.argv[2]) fstb.addfrom(sys.argv[2])
try:
arc = open(sys.argv[1],"wb") arc = open(sys.argv[1],"wb")
# dummy generate to get length # dummy generate to get length
fstlen = len(fstb.fst.generate()) fstlen = len(fstb.fst.generate())
@ -24,3 +25,6 @@ for f in fstb.files:
wii.falign(arc,0x20) wii.falign(arc,0x20)
arc.close() arc.close()
except:
os.remove(sys.argv[1])
raise

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -15,12 +15,12 @@ certfile = args.pop(0)
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read()) certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
print "Certification file %s: " % certfile print("Certification file %s: " % certfile)
cert = wii.WiiCert(open(certfile, "rb").read()) cert = wii.WiiCert(open(certfile, "rb").read())
cert.showinfo(" ") cert.showinfo(" ")
cert.showsig(certs," ") cert.showsig(certs," ")
print "Certificates:" print("Certificates:")
for cert in certlist: for cert in certlist:
cert.showinfo(" - ") cert.showinfo(" - ")
cert.showsig(certs," ") cert.showsig(certs," ")

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -11,7 +11,7 @@ disc.showinfo()
partitions = disc.read_partitions() partitions = disc.read_partitions()
parts = range(len(partitions)) parts = list(range(len(partitions)))
try: try:
pnum = int(sys.argv[2]) pnum = int(sys.argv[2])

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii import pywii
@ -17,7 +17,7 @@ if sys.argv[1] == "-cetk":
elif sys.argv[1] == "-tmd": elif sys.argv[1] == "-tmd":
signed = pywii.WiiTmd(open(infile, "rb").read()) signed = pywii.WiiTmd(open(infile, "rb").read())
else: else:
print "EYOUFAILIT" print("EYOUFAILIT")
sys.exit(1) sys.exit(1)
certs, certlist = pywii.parse_certs(open(certfile).read()) certs, certlist = pywii.parse_certs(open(certfile).read())
@ -25,11 +25,11 @@ certs, certlist = pywii.parse_certs(open(certfile).read())
signed.update_issuer(issuer) signed.update_issuer(issuer)
if not signed.sign(certs): if not signed.sign(certs):
print "dpki signing failed" print("dpki signing failed")
sys.exit(1) sys.exit(1)
open(outfile, "wb").write(signed.data) open(outfile, "wb").write(signed.data)
print "successfully signed %s" % outfile print("successfully signed %s" % outfile)
sys.exit(0) sys.exit(0)

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys import sys
import pywii as wii import pywii as wii
if len(sys.argv) != 3: if len(sys.argv) != 3:
print "Usage: %s keyfile.[priv|pub] infile"%sys.argv[0] print("Usage: %s keyfile.[priv|pub] infile"%sys.argv[0])
sys.exit(1) sys.exit(1)
if sys.argv[1] == "-": if sys.argv[1] == "-":
@ -12,46 +12,46 @@ if sys.argv[1] == "-":
else: else:
k = open(sys.argv[1],"rb").read() k = open(sys.argv[1],"rb").read()
if len(k) not in (30,60): if len(k) not in (30,60):
print "Failed to read key" print("Failed to read key")
sys.exit(2) sys.exit(2)
if len(k) == 30: if len(k) == 30:
print "Key is a private key, generating public key..." print("Key is a private key, generating public key...")
q = wii.ec.priv_to_pub(k) q = wii.ec.priv_to_pub(k)
else: else:
q = k q = k
print "Public key:" print("Public key:")
pq = q.encode('hex') pq = q.encode('hex')
print "X =",pq[:30] print("X =",pq[:30])
print " ",pq[30:60] print(" ",pq[30:60])
print "Y =",pq[60:90] print("Y =",pq[60:90])
print " ",pq[90:] print(" ",pq[90:])
print print()
indata = open(sys.argv[2],"rb").read() indata = open(sys.argv[2],"rb").read()
if len(indata) < 64 or indata[:4] != "SIG0": if len(indata) < 64 or indata[:4] != "SIG0":
print "Invalid header" print("Invalid header")
sys.exit(3) sys.exit(3)
r = indata[4:34] r = indata[4:34]
s = indata[34:64] s = indata[34:64]
sha = wii.SHA.new(indata[64:]).digest() sha = wii.SHA.new(indata[64:]).digest()
print "SHA1: %s"%sha.encode('hex') print("SHA1: %s"%sha.encode('hex'))
print print()
print "Signature:" print("Signature:")
print "R =",r[:15].encode('hex') print("R =",r[:15].encode('hex'))
print " ",r[15:].encode('hex') print(" ",r[15:].encode('hex'))
print "S =",s[:15].encode('hex') print("S =",s[:15].encode('hex'))
print " ",s[15:].encode('hex') print(" ",s[15:].encode('hex'))
print print()
if wii.ec.check_ecdsa(q,r,s,sha): if wii.ec.check_ecdsa(q,r,s,sha):
print "Signature is VALID" print("Signature is VALID")
else: else:
print "Signature is INVALID" print("Signature is INVALID")
sys.exit(4) sys.exit(4)

View File

@ -1,33 +1,33 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os import sys, os
import pywii as wii import pywii as wii
if len(sys.argv) != 2: if len(sys.argv) != 2:
print "Usage: %s keyfile.priv"%sys.argv[0] print("Usage: %s keyfile.priv"%sys.argv[0])
sys.exit(1) sys.exit(1)
print "Generating private key..." print("Generating private key...")
k = wii.ec.gen_priv_key() k = wii.ec.gen_priv_key()
print "Private key:" print("Private key:")
pk = k.encode('hex') pk = k.encode('hex')
print "K =",pk[:30] print("K =",pk[:30])
print " ",pk[30:] print(" ",pk[30:])
print print()
print "Corresponding public key:" print("Corresponding public key:")
q = wii.ec.priv_to_pub(k) q = wii.ec.priv_to_pub(k)
pq = q.encode('hex') pq = q.encode('hex')
print "X =",pq[:30] print("X =",pq[:30])
print " ",pq[30:60] print(" ",pq[30:60])
print "Y =",pq[60:90] print("Y =",pq[60:90])
print " ",pq[90:] print(" ",pq[90:])
fd = open(sys.argv[1],"wb") fd = open(sys.argv[1],"wb")
os.fchmod(fd.fileno(), 0o600) os.fchmod(fd.fileno(), 0o600)
fd.write(k) fd.write(k)
fd.close() fd.close()
print "Saved private key to %s"%sys.argv[1] print("Saved private key to %s"%sys.argv[1])

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys import sys
import pywii as wii import pywii as wii
if len(sys.argv) not in (2,3): if len(sys.argv) not in (2,3):
print "Usage: %s keyfile.priv [keyfile.pub]"%sys.argv[0] print("Usage: %s keyfile.priv [keyfile.pub]"%sys.argv[0])
sys.exit(1) sys.exit(1)
if sys.argv[1] == "-": if sys.argv[1] == "-":
@ -12,19 +12,19 @@ if sys.argv[1] == "-":
else: else:
k = open(sys.argv[1],"rb").read() k = open(sys.argv[1],"rb").read()
if len(k) != 30: if len(k) != 30:
print "Failed to read private key" print("Failed to read private key")
sys.exit(2) sys.exit(2)
print "Public key:" print("Public key:")
q = wii.ec.priv_to_pub(k) q = wii.ec.priv_to_pub(k)
pq = q.encode('hex') pq = q.encode('hex')
print "X =",pq[:30] print("X =",pq[:30])
print " ",pq[30:60] print(" ",pq[30:60])
print "Y =",pq[60:90] print("Y =",pq[60:90])
print " ",pq[90:] print(" ",pq[90:])
if len(sys.argv) == 3: if len(sys.argv) == 3:
fd = open(sys.argv[2],"wb") fd = open(sys.argv[2],"wb")
fd.write(q) fd.write(q)
fd.close() fd.close()
print "Saved public key to %s"%sys.argv[2] print("Saved public key to %s"%sys.argv[2])

View File

@ -1,10 +1,9 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys import sys
import pywii as wii import pywii as wii
if len(sys.argv) != 4: if len(sys.argv) != 4:
print "Usage: %s keyfile.priv infile outfile"%sys.argv[0] print("Usage: %s keyfile.priv infile outfile"%sys.argv[0])
sys.exit(1) sys.exit(1)
if sys.argv[1] == "-": if sys.argv[1] == "-":
@ -13,20 +12,20 @@ else:
k = open(sys.argv[1],"rb").read() k = open(sys.argv[1],"rb").read()
if len(k) != 30: if len(k) != 30:
print "Failed to read private key" print("Failed to read private key")
sys.exit(2) sys.exit(2)
indata = open(sys.argv[2],"rb").read() indata = open(sys.argv[2],"rb").read()
sha = wii.SHA.new(indata).digest() sha = wii.SHA.new(indata).digest()
print "SHA1: %s"%sha.encode('hex') print("SHA1: %s"%sha.encode('hex'))
print print()
print "Signature:" print("Signature:")
r,s = wii.ec.generate_ecdsa(k,sha) r,s = wii.ec.generate_ecdsa(k,sha)
print "R =",r[:15].encode('hex') print("R =",r[:15].encode('hex'))
print " ",r[15:].encode('hex') print(" ",r[15:].encode('hex'))
print "S =",s[:15].encode('hex') print("S =",s[:15].encode('hex'))
print " ",s[15:].encode('hex') print(" ",s[15:].encode('hex'))
outdata = "SIG0" + r + s + indata outdata = "SIG0" + r + s + indata

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -11,8 +11,8 @@ def parseint(d):
return int(d) return int(d)
if len(sys.argv) < 4 or len(sys.argv) > 7: if len(sys.argv) < 4 or len(sys.argv) > 7:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <file to extract to> [Partition offset] [length]"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <file to extract to> [Partition offset] [length]"%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, data_name = sys.argv[1:4] iso_name, partno, data_name = sys.argv[1:4]
@ -27,19 +27,19 @@ if len(sys.argv) == 6:
copy_length = parseint(sys.argv[5]) copy_length = parseint(sys.argv[5])
if copy_length is not None and copy_length < 0: if copy_length is not None and copy_length < 0:
print "Error: negative copy length" print("Error: negative copy length")
sys.exit(1) sys.exit(1)
disc = wii.WiiDisc(iso_name) disc = wii.WiiDisc(iso_name)
disc.showinfo() disc.showinfo()
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False) part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False)
if part_offset >= part.data_bytes: if part_offset >= part.data_bytes:
print "Error: Offset past end of partition" print("Error: Offset past end of partition")
sys.exit(1) sys.exit(1)
if copy_length is None: if copy_length is None:
copy_length = part.data_bytes - part_offset copy_length = part.data_bytes - part_offset
if copy_length > (part.data_bytes - part_offset): if copy_length > (part.data_bytes - part_offset):
print "Error: Length too large" print("Error: Length too large")
sys.exit(1) sys.exit(1)
dataf = open(data_name, "wb") dataf = open(data_name, "wb")
@ -49,7 +49,7 @@ while left > 0:
blocklen = min(left, 4*1024*1024) blocklen = min(left, 4*1024*1024)
d = part.read(offset, blocklen) d = part.read(offset, blocklen)
if len(d) != blocklen: if len(d) != blocklen:
print "Part EOF reached!" print("Part EOF reached!")
sys.exit(1) sys.exit(1)
dataf.write(d) dataf.write(d)
offset += blocklen offset += blocklen

View File

@ -1,4 +1,4 @@
#!/usr/bin/python2 #!/usr/bin/python3
import sys, os, os.path import sys, os, os.path
sys.path.append(os.path.realpath(os.path.dirname(sys.argv[0]))+"/../Common") sys.path.append(os.path.realpath(os.path.dirname(sys.argv[0]))+"/../Common")
@ -7,8 +7,8 @@ import pywii as wii
wii.loadkeys(os.environ["HOME"]+os.sep+".wii") wii.loadkeys(os.environ["HOME"]+os.sep+".wii")
if len(sys.argv) != 4: if len(sys.argv) != 4:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <dol output>"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <dol output>"%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, dol_name = sys.argv[1:4] iso_name, partno, dol_name = sys.argv[1:4]

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -11,8 +11,8 @@ def parseint(d):
return int(d) return int(d)
if len(sys.argv) < 4 or len(sys.argv) > 7: if len(sys.argv) < 4 or len(sys.argv) > 7:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <root path to extract to> "%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <root path to extract to> "%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, data_name = sys.argv[1:4] iso_name, partno, data_name = sys.argv[1:4]
@ -27,19 +27,19 @@ if len(sys.argv) == 6:
copy_length = parseint(sys.argv[5]) copy_length = parseint(sys.argv[5])
if copy_length is not None and copy_length < 0: if copy_length is not None and copy_length < 0:
print "Error: negative copy length" print("Error: negative copy length")
sys.exit(1) sys.exit(1)
disc = wii.WiiDisc(iso_name) disc = wii.WiiDisc(iso_name)
disc.showinfo() disc.showinfo()
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False) part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False)
if part_offset >= part.data_bytes: if part_offset >= part.data_bytes:
print "Error: Offset past end of partition" print("Error: Offset past end of partition")
sys.exit(1) sys.exit(1)
if copy_length is None: if copy_length is None:
copy_length = part.data_bytes - part_offset copy_length = part.data_bytes - part_offset
if copy_length > (part.data_bytes - part_offset): if copy_length > (part.data_bytes - part_offset):
print "Error: Length too large" print("Error: Length too large")
sys.exit(1) sys.exit(1)
dataf = open(data_name, "wb") dataf = open(data_name, "wb")
@ -49,7 +49,7 @@ while left > 0:
blocklen = min(left, 4*1024*1024) blocklen = min(left, 4*1024*1024)
d = part.read(offset, blocklen) d = part.read(offset, blocklen)
if len(d) != blocklen: if len(d) != blocklen:
print "Part EOF reached!" print("Part EOF reached!")
sys.exit(1) sys.exit(1)
dataf.write(d) dataf.write(d)
offset += blocklen offset += blocklen

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -6,8 +6,8 @@ import pywii as wii
wii.loadkeys() wii.loadkeys()
if len(sys.argv) != 5: if len(sys.argv) != 5:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <apploader text> <apploader trailer>"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <apploader text> <apploader trailer>"%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, app_name, trail_name = sys.argv[1:5] iso_name, partno, app_name, trail_name = sys.argv[1:5]

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -11,8 +11,8 @@ def parseint(d):
return int(d) return int(d)
if len(sys.argv) < 4 or len(sys.argv) > 7: if len(sys.argv) < 4 or len(sys.argv) > 7:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <file to inject> [Partition offset] [data offset] [length]"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <file to inject> [Partition offset] [data offset] [length]"%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, data_name = sys.argv[1:4] iso_name, partno, data_name = sys.argv[1:4]
@ -34,10 +34,10 @@ if copy_length == None:
copy_length = data_len - data_offset copy_length = data_len - data_offset
copy_end = data_offset + copy_length copy_end = data_offset + copy_length
if copy_length < 0: if copy_length < 0:
print "Error: negative copy length" print("Error: negative copy length")
sys.exit(1) sys.exit(1)
if copy_end > data_len: if copy_end > data_len:
print "Error: data file is too small" print("Error: data file is too small")
sys.exit(1) sys.exit(1)
disc = wii.WiiDisc(iso_name) disc = wii.WiiDisc(iso_name)
@ -52,7 +52,7 @@ while left > 0:
blocklen = min(left, 4*1024*1024) blocklen = min(left, 4*1024*1024)
d = dataf.read(blocklen) d = dataf.read(blocklen)
if len(d) != blocklen: if len(d) != blocklen:
print "File EOF reached!" print("File EOF reached!")
sys.exit(1) sys.exit(1)
part.write(offset, d) part.write(offset, d)
offset += blocklen offset += blocklen

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -6,8 +6,8 @@ import pywii as wii
wii.loadkeys() wii.loadkeys()
if len(sys.argv) != 4: if len(sys.argv) != 4:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <dol to inject>"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <dol to inject>"%sys.argv[0])
sys.exit(1) sys.exit(1)
iso_name, partno, dol_name = sys.argv[1:4] iso_name, partno, dol_name = sys.argv[1:4]

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -6,9 +6,9 @@ import pywii as wii
wii.loadkeys() wii.loadkeys()
if len(sys.argv) != 4: if len(sys.argv) != 4:
print "Usage:" print("Usage:")
print " python %s <encrypted ISO> <partition number> <IOS version>"%sys.argv[0] print(" python %s <encrypted ISO> <partition number> <IOS version>"%sys.argv[0])
print " IOS version should be just the minor number (16, 33, etc) in decimal" print(" IOS version should be just the minor number (16, 33, etc) in decimal")
sys.exit(1) sys.exit(1)
iso_name, partno, ios = sys.argv[1:4] iso_name, partno, ios = sys.argv[1:4]

View File

@ -1,10 +1,10 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
def hexdump(s): def hexdump(s):
return ' '.join(map(lambda x: "%02x"%x,map(ord,s))) return ' '.join(["%02x"%x for x in list(map(ord,s))])
isofile = sys.argv[1] isofile = sys.argv[1]
disc = WiiDisc(isofile) disc = WiiDisc(isofile)

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -6,7 +6,7 @@ import pywii as wii
wii.loadkeys() wii.loadkeys()
tikfile = sys.argv[1] tikfile = sys.argv[1]
print "fixing Tik file %s " % tikfile print("fixing Tik file %s " % tikfile)
tik = wii.WiiTik(open(tikfile, "rb").read()) tik = wii.WiiTik(open(tikfile, "rb").read())
tik.null_signature() tik.null_signature()
tik.brute_sha() tik.brute_sha()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -17,12 +17,12 @@ certs = None
if len(args) > 0: if len(args) > 0:
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read()) certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
print "ETicket file %s:"%tikfile print("ETicket file %s:"%tikfile)
tik = wii.WiiTik(open(tikfile, "rb").read()) tik = wii.WiiTik(open(tikfile, "rb").read())
tik.showinfo(" ") tik.showinfo(" ")
if certs is not None: if certs is not None:
tik.showsig(certs," ") tik.showsig(certs," ")
print "Certificates:" print("Certificates:")
for cert in certlist: for cert in certlist:
cert.showinfo(" - ") cert.showinfo(" - ")
cert.showsig(certs," ") cert.showsig(certs," ")

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -6,7 +6,7 @@ import pywii as wii
wii.loadkeys() wii.loadkeys()
tmdfile = sys.argv[1] tmdfile = sys.argv[1]
print "TMD file %s:"%tmdfile print("TMD file %s:"%tmdfile)
tmd = wii.WiiTmd(open(tmdfile, "rb").read()) tmd = wii.WiiTmd(open(tmdfile, "rb").read())
tmd.null_signature() tmd.null_signature()
tmd.brute_sha() tmd.brute_sha()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -17,12 +17,12 @@ certs = None
if len(args) > 0: if len(args) > 0:
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read()) certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
print "TMD file %s:"%tmdfile print("TMD file %s:"%tmdfile)
tmd = wii.WiiTmd(open(tmdfile, "rb").read()) tmd = wii.WiiTmd(open(tmdfile, "rb").read())
tmd.showinfo(" ") tmd.showinfo(" ")
if certs is not None: if certs is not None:
tmd.showsig(certs," ") tmd.showsig(certs," ")
print "Certificates:" print("Certificates:")
for cert in certlist: for cert in certlist:
cert.showinfo(" - ") cert.showinfo(" - ")
cert.showsig(certs," ") cert.showsig(certs," ")

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -14,7 +14,7 @@ args = sys.argv[1:]
tmdfile = args.pop(0) tmdfile = args.pop(0)
indir = args.pop(0) indir = args.pop(0)
print "updating content records of TMD file %s" % tmdfile print("updating content records of TMD file %s" % tmdfile)
tmd = wii.WiiTmd(open(tmdfile, "rb").read()) tmd = wii.WiiTmd(open(tmdfile, "rb").read())
for i, cr in enumerate(tmd.get_content_records()): for i, cr in enumerate(tmd.get_content_records()):

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii
@ -14,7 +14,7 @@ if len(args) == 2:
else: else:
newvers = int(args.pop(0), 16) newvers = int(args.pop(0), 16)
print "setting version of TMD file %s to 0x%04x" % (tmdfile, newvers) print("setting version of TMD file %s to 0x%04x" % (tmdfile, newvers))
tmd = wii.WiiTmd(open(tmdfile, "rb").read()) tmd = wii.WiiTmd(open(tmdfile, "rb").read())
tmd.title_version = newvers tmd.title_version = newvers
tmd.update() tmd.update()

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python2 #!/usr/bin/env python3
import sys, os, os.path import sys, os, os.path
import pywii as wii import pywii as wii