Initial commit
This commit is contained in:
1736
pywii/Alameda/Alameda.py
Normal file
1736
pywii/Alameda/Alameda.py
Normal file
File diff suppressed because it is too large
Load Diff
335
pywii/Common/Struct.py
Normal file
335
pywii/Common/Struct.py
Normal file
@@ -0,0 +1,335 @@
|
||||
import struct, sys
|
||||
|
||||
class StructType(tuple):
|
||||
def __getitem__(self, value):
|
||||
return [self] * value
|
||||
def __call__(self, value, endian='<'):
|
||||
if isinstance(value, str):
|
||||
return struct.unpack(endian + tuple.__getitem__(self, 0), value[:tuple.__getitem__(self, 1)])[0]
|
||||
else:
|
||||
return struct.pack(endian + tuple.__getitem__(self, 0), value)
|
||||
|
||||
class StructException(Exception):
|
||||
pass
|
||||
|
||||
class Struct(object):
|
||||
__slots__ = ('__attrs__', '__baked__', '__defs__', '__endian__', '__next__', '__sizes__', '__values__')
|
||||
int8 = StructType(('b', 1))
|
||||
uint8 = StructType(('B', 1))
|
||||
|
||||
int16 = StructType(('h', 2))
|
||||
uint16 = StructType(('H', 2))
|
||||
|
||||
int32 = StructType(('l', 4))
|
||||
uint32 = StructType(('L', 4))
|
||||
|
||||
int64 = StructType(('q', 8))
|
||||
uint64 = StructType(('Q', 8))
|
||||
|
||||
float = StructType(('f', 4))
|
||||
|
||||
@classmethod
|
||||
def string(cls, len, offset=0, encoding=None, stripNulls=False, value=''):
|
||||
return StructType(('string', (len, offset, encoding, stripNulls, value)))
|
||||
|
||||
LE = '<'
|
||||
BE = '>'
|
||||
__endian__ = '<'
|
||||
|
||||
def __init__(self, func=None, unpack=None, **kwargs):
|
||||
self.__defs__ = []
|
||||
self.__sizes__ = []
|
||||
self.__attrs__ = []
|
||||
self.__values__ = {}
|
||||
self.__next__ = True
|
||||
self.__baked__ = False
|
||||
|
||||
if func == None:
|
||||
self.__format__()
|
||||
else:
|
||||
sys.settrace(self.__trace__)
|
||||
func()
|
||||
for name in func.func_code.co_varnames:
|
||||
value = self.__frame__.f_locals[name]
|
||||
self.__setattr__(name, value)
|
||||
|
||||
self.__baked__ = True
|
||||
|
||||
if unpack != None:
|
||||
if isinstance(unpack, tuple):
|
||||
self.unpack(*unpack)
|
||||
else:
|
||||
self.unpack(unpack)
|
||||
|
||||
if len(kwargs):
|
||||
for name in kwargs:
|
||||
self.__values__[name] = kwargs[name]
|
||||
|
||||
def __trace__(self, frame, event, arg):
|
||||
self.__frame__ = frame
|
||||
sys.settrace(None)
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
if name in self.__slots__:
|
||||
return object.__setattr__(self, name, value)
|
||||
|
||||
if self.__baked__ == False:
|
||||
if not isinstance(value, list):
|
||||
value = [value]
|
||||
attrname = name
|
||||
else:
|
||||
attrname = '*' + name
|
||||
|
||||
self.__values__[name] = None
|
||||
|
||||
for sub in value:
|
||||
if isinstance(sub, Struct):
|
||||
sub = sub.__class__
|
||||
try:
|
||||
if issubclass(sub, Struct):
|
||||
sub = ('struct', sub)
|
||||
except TypeError:
|
||||
pass
|
||||
type_, size = tuple(sub)
|
||||
if type_ == 'string':
|
||||
self.__defs__.append(Struct.string)
|
||||
self.__sizes__.append(size)
|
||||
self.__attrs__.append(attrname)
|
||||
self.__next__ = True
|
||||
|
||||
if attrname[0] != '*':
|
||||
self.__values__[name] = size[3]
|
||||
elif self.__values__[name] == None:
|
||||
self.__values__[name] = [size[3] for val in value]
|
||||
elif type_ == 'struct':
|
||||
self.__defs__.append(Struct)
|
||||
self.__sizes__.append(size)
|
||||
self.__attrs__.append(attrname)
|
||||
self.__next__ = True
|
||||
|
||||
if attrname[0] != '*':
|
||||
self.__values__[name] = size()
|
||||
elif self.__values__[name] == None:
|
||||
self.__values__[name] = [size() for val in value]
|
||||
else:
|
||||
if self.__next__:
|
||||
self.__defs__.append('')
|
||||
self.__sizes__.append(0)
|
||||
self.__attrs__.append([])
|
||||
self.__next__ = False
|
||||
|
||||
self.__defs__[-1] += type_
|
||||
self.__sizes__[-1] += size
|
||||
self.__attrs__[-1].append(attrname)
|
||||
|
||||
if attrname[0] != '*':
|
||||
self.__values__[name] = 0
|
||||
elif self.__values__[name] == None:
|
||||
self.__values__[name] = [0 for val in value]
|
||||
else:
|
||||
try:
|
||||
self.__values__[name] = value
|
||||
except KeyError:
|
||||
raise AttributeError(name)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if self.__baked__ == False:
|
||||
return name
|
||||
else:
|
||||
try:
|
||||
return self.__values__[name]
|
||||
except KeyError:
|
||||
raise AttributeError(name)
|
||||
|
||||
def __len__(self):
|
||||
ret = 0
|
||||
arraypos, arrayname = None, None
|
||||
|
||||
for i in range(len(self.__defs__)):
|
||||
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
|
||||
|
||||
if sdef == Struct.string:
|
||||
size, offset, encoding, stripNulls, value = size
|
||||
if isinstance(size, str):
|
||||
size = self.__values__[size] + offset
|
||||
elif sdef == Struct:
|
||||
if attrs[0] == '*':
|
||||
if arrayname != attrs:
|
||||
arrayname = attrs
|
||||
arraypos = 0
|
||||
size = len(self.__values__[attrs[1:]][arraypos])
|
||||
size = len(self.__values__[attrs])
|
||||
|
||||
ret += size
|
||||
|
||||
return ret
|
||||
|
||||
def unpack(self, data, pos=0):
|
||||
for name in self.__values__:
|
||||
if not isinstance(self.__values__[name], Struct):
|
||||
self.__values__[name] = None
|
||||
elif self.__values__[name].__class__ == list and len(self.__values__[name]) != 0:
|
||||
if not isinstance(self.__values__[name][0], Struct):
|
||||
self.__values__[name] = None
|
||||
|
||||
arraypos, arrayname = None, None
|
||||
|
||||
for i in range(len(self.__defs__)):
|
||||
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
|
||||
|
||||
if sdef == Struct.string:
|
||||
size, offset, encoding, stripNulls, value = size
|
||||
if isinstance(size, str):
|
||||
size = self.__values__[size] + offset
|
||||
|
||||
temp = data[pos:pos+size]
|
||||
if len(temp) != size:
|
||||
raise StructException('Expected %i byte string, got %i' % (size, len(temp)))
|
||||
|
||||
if encoding != None:
|
||||
temp = temp.decode(encoding)
|
||||
|
||||
if stripNulls:
|
||||
temp = temp.rstrip('\0')
|
||||
|
||||
if attrs[0] == '*':
|
||||
name = attrs[1:]
|
||||
if self.__values__[name] == None:
|
||||
self.__values__[name] = []
|
||||
self.__values__[name].append(temp)
|
||||
else:
|
||||
self.__values__[attrs] = temp
|
||||
pos += size
|
||||
elif sdef == Struct:
|
||||
if attrs[0] == '*':
|
||||
if arrayname != attrs:
|
||||
arrayname = attrs
|
||||
arraypos = 0
|
||||
name = attrs[1:]
|
||||
self.__values__[attrs][arraypos].unpack(data, pos)
|
||||
pos += len(self.__values__[attrs][arraypos])
|
||||
arraypos += 1
|
||||
else:
|
||||
self.__values__[attrs].unpack(data, pos)
|
||||
pos += len(self.__values__[attrs])
|
||||
else:
|
||||
values = struct.unpack(self.__endian__+sdef, data[pos:pos+size])
|
||||
pos += size
|
||||
j = 0
|
||||
for name in attrs:
|
||||
if name[0] == '*':
|
||||
name = name[1:]
|
||||
if self.__values__[name] == None:
|
||||
self.__values__[name] = []
|
||||
self.__values__[name].append(values[j])
|
||||
else:
|
||||
self.__values__[name] = values[j]
|
||||
j += 1
|
||||
|
||||
return self
|
||||
|
||||
def pack(self):
|
||||
arraypos, arrayname = None, None
|
||||
|
||||
ret = ''
|
||||
for i in range(len(self.__defs__)):
|
||||
sdef, size, attrs = self.__defs__[i], self.__sizes__[i], self.__attrs__[i]
|
||||
|
||||
if sdef == Struct.string:
|
||||
size, offset, encoding, stripNulls, value = size
|
||||
if isinstance(size, str):
|
||||
size = self.__values__[size]+offset
|
||||
|
||||
if attrs[0] == '*':
|
||||
if arrayname != attrs:
|
||||
arraypos = 0
|
||||
arrayname = attrs
|
||||
temp = self.__values__[attrs[1:]][arraypos]
|
||||
arraypos += 1
|
||||
else:
|
||||
temp = self.__values__[attrs]
|
||||
|
||||
if encoding != None:
|
||||
temp = temp.encode(encoding)
|
||||
|
||||
temp = temp[:size]
|
||||
ret += temp + ('\0' * (size - len(temp)))
|
||||
elif sdef == Struct:
|
||||
if attrs[0] == '*':
|
||||
if arrayname != attrs:
|
||||
arraypos = 0
|
||||
arrayname = attrs
|
||||
ret += self.__values__[attrs[1:]][arraypos].pack()
|
||||
arraypos += 1
|
||||
else:
|
||||
ret += self.__values__[attrs].pack()
|
||||
else:
|
||||
values = []
|
||||
for name in attrs:
|
||||
if name[0] == '*':
|
||||
if arrayname != name:
|
||||
arraypos = 0
|
||||
arrayname = name
|
||||
values.append(self.__values__[name[1:]][arraypos])
|
||||
arraypos += 1
|
||||
else:
|
||||
values.append(self.__values__[name])
|
||||
|
||||
ret += struct.pack(self.__endian__+sdef, *values)
|
||||
return ret
|
||||
|
||||
def __getitem__(self, value):
|
||||
return [('struct', self.__class__)] * value
|
||||
|
||||
if __name__=='__main__':
|
||||
class TestStruct(Struct):
|
||||
__endian__ = Struct.LE
|
||||
def __format__(self):
|
||||
self.foo, self.bar = Struct.uint32, Struct.float
|
||||
self.baz = Struct.string(8)
|
||||
|
||||
self.omg = Struct.uint32
|
||||
self.wtf = Struct.string(self.omg)
|
||||
|
||||
class HaxStruct(Struct):
|
||||
__endian__ = Struct.LE
|
||||
def __format__(self):
|
||||
self.thing1 = Struct.uint32
|
||||
self.thing2 = Struct.uint32
|
||||
self.hax = HaxStruct
|
||||
|
||||
test = TestStruct()
|
||||
test.unpack('\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.bar == 1.0
|
||||
assert test.baz == 'deadbeef'
|
||||
assert test.omg == 4
|
||||
assert test.wtf == 'test'
|
||||
assert test.hax.thing1 == 0xBEBAFECA
|
||||
assert test.hax.thing2 == 0xCAFEBABE
|
||||
|
||||
print 'Tests successful'
|
||||
|
||||
"""
|
||||
@Struct.LE
|
||||
def TestStruct():
|
||||
foo, bar = Struct.uint32, Struct.float
|
||||
baz = Struct.string(8)
|
||||
|
||||
omg = Struct.uint32
|
||||
wtf = Struct.string(omg)
|
||||
|
||||
@Struct.LE
|
||||
def HaxStruct():
|
||||
thing1 = Struct.uint32
|
||||
thing2 = Struct.uint32
|
||||
hax = HaxStruct()
|
||||
|
||||
test = TestStruct()
|
||||
test.foo = 0xCAFEBABE
|
||||
test.bar = 0.0
|
||||
thing = test.hax.thing1
|
||||
test.hax.thing1 = test.hax.thing2
|
||||
test.hax.thing2 = thing
|
||||
assert test.pack() == '\xBE\xBA\xFE\xCA\0\0\0\0deadbeef\x04\x00\x00\x00test\xBE\xBA\xFE\xCA\xCA\xFE\xBA\xBE'
|
||||
"""
|
||||
3
pywii/Common/pywii/__init__.py
Normal file
3
pywii/Common/pywii/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from wii import *
|
||||
367
pywii/Common/pywii/ec.py
Normal file
367
pywii/Common/pywii/ec.py
Normal file
@@ -0,0 +1,367 @@
|
||||
#!/usr/bin/python
|
||||
# Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
# Copyright 2008 Hector Martin <marcan@marcansoft.com>
|
||||
# Licensed under the terms of the GNU GPL, version 2
|
||||
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
|
||||
from array import array
|
||||
from struct import pack, unpack
|
||||
from Crypto.Util.number import bytes_to_long, long_to_bytes
|
||||
|
||||
# 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"+\
|
||||
"\x3b\x33\x3b\x20\xe9\xce\x42\x81\xfe\x11\x5f\x7d\x8f\x90\xad"
|
||||
|
||||
def hexdump(s,sep=""):
|
||||
return sep.join(map(lambda x: "%02x"%ord(x),s))
|
||||
|
||||
def bhex(s,sep=""):
|
||||
return hexdump(long_to_bytes(s,30),sep)
|
||||
|
||||
fastelt = False
|
||||
try:
|
||||
import _ec
|
||||
fastelt = True
|
||||
except ImportError:
|
||||
#print "C Elliptic Curve functions not available. EC certificate checking will be much slower."
|
||||
pass
|
||||
|
||||
|
||||
class ByteArray(array):
|
||||
def __new__(cls, initializer=None):
|
||||
return super(ByteArray, cls) .__new__(cls,'B',initializer)
|
||||
def __init__(self,initializer=None):
|
||||
array.__init__(self)
|
||||
def __setitem__(self,item,value):
|
||||
if isinstance(item, slice):
|
||||
array.__setitem__(self, item, [x & 0xFF for x in value])
|
||||
else:
|
||||
array.__setitem__(self, item, value & 0xFF)
|
||||
def __long__(self):
|
||||
return bytes_to_long(self.tostring())
|
||||
def __str__(self):
|
||||
return ''.join(["%02x"%ord(x) for x in self.tostring()])
|
||||
def __repr__(self):
|
||||
return "ByteArray('%s')"%''.join(["\\x%02x"%ord(x) for x in self.tostring()])
|
||||
|
||||
class ELT_PY:
|
||||
SIZEBITS=233
|
||||
SIZE=(SIZEBITS+7)/8
|
||||
square = ByteArray("\x00\x01\x04\x05\x10\x11\x14\x15\x40\x41\x44\x45\x50\x51\x54\x55")
|
||||
def __init__(self, initializer=None):
|
||||
if isinstance(initializer, long) or isinstance(initializer, int):
|
||||
self.d = ByteArray(long_to_bytes(initializer,self.SIZE))
|
||||
elif isinstance(initializer, str):
|
||||
self.d = ByteArray(initializer)
|
||||
elif isinstance(initializer, ByteArray):
|
||||
self.d = ByteArray(initializer)
|
||||
elif isinstance(initializer, array):
|
||||
self.d = ByteArray(initializer)
|
||||
elif isinstance(initializer, ELT):
|
||||
self.d = ByteArray(initializer.d)
|
||||
elif initializer is None:
|
||||
self.d = ByteArray([0]*self.SIZE)
|
||||
else:
|
||||
raise TypeError("Invalid initializer type")
|
||||
if len(self.d) != self.SIZE:
|
||||
raise ValueError("ELT size must be 30")
|
||||
|
||||
def __cmp__(self, other):
|
||||
if other == 0: #exception
|
||||
if self:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
if not isinstance(other,ELT):
|
||||
return NotImplemented
|
||||
return cmp(self.d,other.d)
|
||||
|
||||
def __long__(self):
|
||||
return long(self.d)
|
||||
def __repr__(self):
|
||||
return repr(self.d).replace("ByteArray","ELT")
|
||||
def __str__(self):
|
||||
return str(self.d)
|
||||
def __nonzero__(self):
|
||||
for x in self.d:
|
||||
if x != 0:
|
||||
return True
|
||||
return False
|
||||
def __len__(self):
|
||||
return self.SIZE
|
||||
def __add__(self,other):
|
||||
if not isinstance(other,ELT):
|
||||
return NotImplemented
|
||||
new = ELT(self)
|
||||
for x in range(self.SIZE):
|
||||
new[x] ^= other[x]
|
||||
return new
|
||||
def _mul_x(self):
|
||||
carry = self[0]&1
|
||||
x = 0
|
||||
d = ELT()
|
||||
for i in range(self.SIZE-1):
|
||||
y = self[i + 1]
|
||||
d[i] = x ^ (y >> 7)
|
||||
x = y << 1
|
||||
d[29] = x ^ carry
|
||||
d[20] ^= carry << 2
|
||||
return d
|
||||
def __mul__(self,other):
|
||||
if not isinstance(other,ELT):
|
||||
return NotImplemented
|
||||
d = ELT()
|
||||
i = 0
|
||||
mask = 1
|
||||
for n in range(self.SIZEBITS):
|
||||
d = d._mul_x()
|
||||
if (self[i] & mask) != 0:
|
||||
d += other
|
||||
mask >>= 1
|
||||
if mask == 0:
|
||||
mask = 0x80
|
||||
i+=1
|
||||
return d
|
||||
def __pow__(self,other):
|
||||
if other == -1:
|
||||
return 1/self
|
||||
if other < 1:
|
||||
return NotImplemented
|
||||
if other % 2 == 0:
|
||||
return self._square()**(other/2)
|
||||
x = self
|
||||
for i in range(other-1):
|
||||
x *= self
|
||||
return x
|
||||
def _square(self):
|
||||
wide = ByteArray([0]*self.SIZE*2)
|
||||
for i in range(self.SIZE):
|
||||
wide[2*i] = self.square[self[i] >> 4]
|
||||
wide[2*i + 1] = self.square[self[i] & 0xf]
|
||||
for i in range(self.SIZE):
|
||||
x = wide[i]
|
||||
|
||||
wide[i + 19] ^= x >> 7;
|
||||
wide[i + 20] ^= x << 1;
|
||||
|
||||
wide[i + 29] ^= x >> 1;
|
||||
wide[i + 30] ^= x << 7;
|
||||
x = wide[30] & 0xFE;
|
||||
|
||||
wide[49] ^= x >> 7;
|
||||
wide[50] ^= x << 1;
|
||||
|
||||
wide[59] ^= x >> 1;
|
||||
|
||||
wide[30] &= 1;
|
||||
return ELT(wide[self.SIZE:])
|
||||
def _itoh_tsujii(self,b,j):
|
||||
t = ELT(self)
|
||||
return t**(2**j) * b
|
||||
def __rdiv__(self,other):
|
||||
if isinstance(other,ELT):
|
||||
return 1/self * other
|
||||
elif other == 1:
|
||||
t = self._itoh_tsujii(self, 1)
|
||||
s = t._itoh_tsujii(self, 1)
|
||||
t = s._itoh_tsujii(s, 3)
|
||||
s = t._itoh_tsujii(self, 1)
|
||||
t = s._itoh_tsujii(s, 7)
|
||||
s = t._itoh_tsujii(t, 14)
|
||||
t = s._itoh_tsujii(self, 1)
|
||||
s = t._itoh_tsujii(t, 29)
|
||||
t = s._itoh_tsujii(s, 58)
|
||||
s = t._itoh_tsujii(t, 116)
|
||||
return s**2
|
||||
else:
|
||||
return NotImplemented
|
||||
|
||||
def __getitem__(self,item):
|
||||
return self.d[item]
|
||||
def __setitem__(self,item,value):
|
||||
self.d[item] = value
|
||||
def tobignum(self):
|
||||
return bytes_to_long(self.d.tostring())
|
||||
def tobytes(self):
|
||||
return self.d.tostring()
|
||||
|
||||
class ELT_C(ELT_PY):
|
||||
def __mul__(self,other):
|
||||
if not isinstance(other,ELT):
|
||||
return NotImplemented
|
||||
return ELT(_ec.elt_mul(self.d.tostring(),other.d.tostring()))
|
||||
def __rdiv__(self,other):
|
||||
if other != 1:
|
||||
return ELT_PY.__rdiv__(self,other)
|
||||
return ELT(_ec.elt_inv(self.d.tostring()))
|
||||
def _square(self):
|
||||
return ELT(_ec.elt_square(self.d.tostring()))
|
||||
|
||||
if fastelt:
|
||||
ELT = ELT_C
|
||||
else:
|
||||
ELT = ELT_PY
|
||||
|
||||
class Point:
|
||||
def __init__(self,x,y=None):
|
||||
if isinstance(x,str) and (y is None) and (len(x) == 60):
|
||||
self.x = ELT(x[:30])
|
||||
self.y = ELT(x[30:])
|
||||
elif isinstance(x,Point):
|
||||
self.x = ELT(x.x)
|
||||
self.y = ELT(x.y)
|
||||
else:
|
||||
self.x = ELT(x)
|
||||
self.y = ELT(y)
|
||||
def on_curve(self):
|
||||
return (self.x**3 + self.x**2 + self.y**2 + self.x*self.y + ELT(ec_b)) == 0
|
||||
def __cmp__(self, other):
|
||||
if other == 0:
|
||||
if self.x or self.y:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
elif isinstance(other, Point):
|
||||
ca = cmp(self.x,other.x)
|
||||
if ca != 0:
|
||||
return ca
|
||||
return cmp(self.y,other.y)
|
||||
return NotImplemented
|
||||
def _double(self):
|
||||
if self.x == 0:
|
||||
return Point(0,0)
|
||||
|
||||
s = self.y/self.x + self.x
|
||||
rx = s**2 + s
|
||||
rx[29] ^= 1;
|
||||
ry = s * rx + rx + self.x**2
|
||||
return Point(rx,ry)
|
||||
def __add__(self, other):
|
||||
if not isinstance(other,Point):
|
||||
return NotImplemented
|
||||
if self == 0:
|
||||
return Point(other)
|
||||
if other == 0:
|
||||
return Point(self)
|
||||
u = self.x + other.x
|
||||
if u == 0:
|
||||
u = self.y + other.y
|
||||
if u == 0:
|
||||
return self._double()
|
||||
else:
|
||||
return Point(0,0)
|
||||
|
||||
s = (self.y + other.y) / u
|
||||
t = s**2 + s + other.x
|
||||
t[29] ^= 1
|
||||
|
||||
rx = t+self.x
|
||||
ry = s*t+self.y+rx
|
||||
return Point(rx,ry)
|
||||
|
||||
def __mul__(self, other):
|
||||
bts = long_to_bytes(other,30)
|
||||
d = Point(0,0)
|
||||
for i in range(30):
|
||||
mask = 0x80
|
||||
while mask != 0:
|
||||
d = d._double()
|
||||
if ((ord(bts[i]) & mask) != 0):
|
||||
d += self
|
||||
mask >>=1
|
||||
return d
|
||||
#def __mul__(self, other):
|
||||
#if not (isinstance(other,long) or isinstance(other,int)):
|
||||
#return NotImplemented
|
||||
|
||||
#d = Point(0,0)
|
||||
#s = Point(self)
|
||||
|
||||
#while other != 0:
|
||||
#if other & 1:
|
||||
#d += s
|
||||
#s = s._double()
|
||||
#other >>= 1
|
||||
#return d
|
||||
def __rmul__(self, other):
|
||||
return self * other
|
||||
def __str__(self):
|
||||
return "(%s,%s)"%(str(self.x),str(self.y))
|
||||
def __repr__(self):
|
||||
return "Point"+str(self)
|
||||
def __nonzero__(self):
|
||||
return self.x or self.y
|
||||
def tobytes(self):
|
||||
return self.x.tobytes() + self.y.tobytes()
|
||||
|
||||
#only for prime N
|
||||
#segher, your math makes my head hurt. But it works.
|
||||
def bn_inv(a,N):
|
||||
return pow(a,N-2,N)
|
||||
|
||||
|
||||
# order of the addition group of points
|
||||
ec_N = bytes_to_long(
|
||||
"\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")
|
||||
|
||||
# base point
|
||||
ec_G = Point(
|
||||
"\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"+
|
||||
"\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")
|
||||
|
||||
def generate_ecdsa(k, sha):
|
||||
k = bytes_to_long(k)
|
||||
|
||||
if k >= ec_N:
|
||||
raise Exception("Invalid private key")
|
||||
|
||||
e = bytes_to_long(sha)
|
||||
|
||||
m = open("/dev/random","rb").read(30)
|
||||
if len(m) != 30:
|
||||
raise Exception("Failed to get random data")
|
||||
m = bytes_to_long(m) % ec_N
|
||||
|
||||
r = (m * ec_G).x.tobignum() % ec_N
|
||||
|
||||
kk = ((r*k)+e)%ec_N
|
||||
s = (bn_inv(m,ec_N) * kk)%ec_N
|
||||
|
||||
r = long_to_bytes(r,30)
|
||||
s = long_to_bytes(s,30)
|
||||
return r,s
|
||||
|
||||
def check_ecdsa(q,r,s,sha):
|
||||
|
||||
q = Point(q)
|
||||
r = bytes_to_long(r)
|
||||
s = bytes_to_long(s)
|
||||
e = bytes_to_long(sha)
|
||||
|
||||
s_inv = bn_inv(s,ec_N)
|
||||
|
||||
w1 = (e*s_inv)%ec_N
|
||||
w2 = (r*s_inv)%ec_N
|
||||
|
||||
r1 = w1 * ec_G + w2 * q
|
||||
|
||||
rx = r1.x.tobignum()%ec_N
|
||||
|
||||
return rx == r
|
||||
|
||||
def priv_to_pub(k):
|
||||
k = bytes_to_long(k)
|
||||
q = k * ec_G
|
||||
return q.tobytes()
|
||||
|
||||
def gen_priv_key():
|
||||
k = open("/dev/random","rb").read(30)
|
||||
if len(k) != 30:
|
||||
raise Exception("Failed to get random data")
|
||||
|
||||
k = bytes_to_long(k)
|
||||
k = k % ec_N
|
||||
return long_to_bytes(k,30)
|
||||
1757
pywii/Common/pywii/wii.py
Normal file
1757
pywii/Common/pywii/wii.py
Normal file
File diff suppressed because it is too large
Load Diff
10
pywii/README
Normal file
10
pywii/README
Normal file
@@ -0,0 +1,10 @@
|
||||
Python library to deal with Wii formats.
|
||||
|
||||
Currently has decent support for discs, partitions (including
|
||||
accessing the partition data using read() and write(), with
|
||||
caching), wads, and the structures contained within (certs,
|
||||
tiks, tmds, etc)
|
||||
|
||||
Stuff may be broken. Some things are unfinished.
|
||||
|
||||
It also makes breakfast.
|
||||
94
pywii/breakfast.py
Normal file
94
pywii/breakfast.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import zlib, time, base64, sys
|
||||
|
||||
class WaffleBatter:
|
||||
def __init__(self):
|
||||
self.cooking_time = 100
|
||||
self.batter = "eNp9VbGu3DgM7PMVhBs2sq4VDnHKwxUu1DLehQhBxeukD7iPvyEl78tLXuJisbbJ4Qw5lIn+dJUfri+/i+n92Lbr70siblreWFLejtE/zQhHZpW4C+OGW0pKoWuOUvVb6VlG/DUtJAsO8tC3SGFkpvKUy19xyO0ynlHl54LhYEIpteTnyOmiIcwa9BHLGIzHWvFSN0D+lFwaFzyM2ks4NjaKdb04NujEPWe8NTV4SPohvSWvSe3IUsn4kkQ5V3DRt+JtQyNq7GiEUpT+nt84SnSZqBOtq+SqpZsAoq1K97fPEbWWCcUSXwjJyBvNoR7+rN3lht1nRNDEF2r7DIRTR3+RsT/PBRFsini0VHsPEL9bUSXAOTeBqO59RrDWv1yz1IkRKHXtVhVqJt0ydoz5VV9i9oxHTIYXEGz9tri8QKSZV8gfmcLggEqcJoO2nXcGXyR9ekL4uymiuyM50QNsDnYOdU0SrMHhnBy2iQgcmEPOd1GReXG5xB/JuQ9vG8LmiNpe50SDVZA+Z6/fIOsfG5K4jeRGuWwO8SbRsC3nPkkILVkHyySxLHzu8335niZKdeOidXST6IvDXI+bBHo/IdH6OjtpJNN/q720zAVjypwuZTcqhMK3j5ni7QWLr+zCzU4Mh9E9JarAcYc1GLKvPQHkGZ2crdlj/rUdfsyazZcTOXQtGI0ko3icBvh+/i19sUBOzbYxE/PUat1BEEV9a9xu+yN6Ns/W/sgJ22pGz07NpZUR7wjQ0OprQsoNp8lricDGqfpUL7o5KHc7SYrJNa9Emizkkr62l95ByOas/16rh+8zIHqpIiCCzuDbVrFl+oHIlGTxy97LJjgL8vJRGPOIKjciEEDkw3E4+649OhcIOpdRw8TzJt0qnOFHDi8IMMFpqTDUrFeC7ebJd+2Y5tQB+OsHQPrkyPaB6OksLkWEzb6lhIH5ONLIn309dBt31whH+WbXvtsv803g07orZaNeyudfMRx2v81bk9d9H/vr6mNX5i//A5YHk94="
|
||||
|
||||
class Waffle:
|
||||
def __init__(self, waffle):
|
||||
self.waffle = waffle
|
||||
def display(self, file=sys.stdout):
|
||||
file.write(self.waffle)
|
||||
|
||||
class WaffleIron:
|
||||
def __init__(self):
|
||||
self.power = False
|
||||
self.time = 0
|
||||
self.full = False
|
||||
self.contents = False
|
||||
pass
|
||||
def switchPower(self, power):
|
||||
self.power = power
|
||||
def fill(self, contents):
|
||||
if not self.power:
|
||||
raise RuntimeError("Turn on the iron first!")
|
||||
if not isinstance(contents, WaffleBatter):
|
||||
raise ValueError("Iron can only be filled with batter!")
|
||||
self.contents = contents
|
||||
self.time = time.time()
|
||||
return self.contents.cooking_time
|
||||
def contentsAreCooked(self):
|
||||
return time.time() > (self.time+self.contents.cooking_time)
|
||||
def getTimeLeft(self):
|
||||
return max(0,(self.time+self.contents.cooking_time) - time.time())
|
||||
def getContents(self):
|
||||
if self.contentsAreCooked():
|
||||
batter = self.contents.batter
|
||||
cookedbatter = zlib.decompress(base64.b64decode(batter))
|
||||
self.contents = Waffle(cookedbatter)
|
||||
else:
|
||||
raise RuntimeError("Waffle is not yet cooked!")
|
||||
return self.contents
|
||||
|
||||
class BreakfastType:
|
||||
def __init__(self):
|
||||
raise NotImplementedError("BreakfastType is abstract")
|
||||
|
||||
class Waffles(BreakfastType):
|
||||
def __init__(self):
|
||||
pass
|
||||
def make(self):
|
||||
batter = WaffleBatter()
|
||||
iron = WaffleIron()
|
||||
iron.switchPower(True)
|
||||
cooktime = iron.fill(batter)
|
||||
cm, cs = divmod(cooktime,60)
|
||||
if cm > 0:
|
||||
print "Cooking time will be approximately %d minute%s and %d second%s"%(cm, 's'*(cm!=1), cs, 's'*(cs!=1))
|
||||
else:
|
||||
print "Cooking time will be approximately %d second%s"%(cs, 's'*(cs!=1))
|
||||
while not iron.contentsAreCooked():
|
||||
left = iron.getTimeLeft()
|
||||
m,s = divmod(left+0.99,60)
|
||||
sys.stdout.write("%02d:%02d"%(m,s))
|
||||
sys.stdout.flush()
|
||||
time.sleep(0.5)
|
||||
sys.stdout.write("\x08"*5)
|
||||
sys.stdout.flush()
|
||||
print
|
||||
waffle = iron.getContents()
|
||||
iron.switchPower(False)
|
||||
return waffle
|
||||
|
||||
class BreakfastMaker:
|
||||
preferredBreakfasts = {'bushing':Waffles}
|
||||
def __init__(self):
|
||||
pass
|
||||
def makeBreakfastFor(self, user):
|
||||
if not user in self.preferredBreakfasts:
|
||||
raise ValueError("I don't know how to make breakfast for %s!"%user)
|
||||
maker = self.preferredBreakfasts[user]
|
||||
breakfast = maker().make()
|
||||
return breakfast
|
||||
|
||||
print "Breakfast Maker v0.2"
|
||||
user = raw_input("Please enter your username: ")
|
||||
maker = BreakfastMaker()
|
||||
print "Making breakfast for %s..."%user
|
||||
breakfast = maker.makeBreakfastFor(user)
|
||||
print
|
||||
print "Your breakfast is ready!"
|
||||
print
|
||||
breakfast.display()
|
||||
print "\a"
|
||||
248
pywii/ecmodule/_ecmodule.c
Normal file
248
pywii/ecmodule/_ecmodule.c
Normal file
@@ -0,0 +1,248 @@
|
||||
// Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
// Copyright 2008 Hector Martin <marcan@marcansoft.com>
|
||||
// Licensed under the terms of the GNU GPL, version 2
|
||||
// http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
|
||||
#include "Python.h"
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint32_t u32;
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
static void elt_copy(u8 *d, const u8 *a)
|
||||
{
|
||||
memcpy(d, a, 30);
|
||||
}
|
||||
|
||||
static void elt_zero(u8 *d)
|
||||
{
|
||||
memset(d, 0, 30);
|
||||
}
|
||||
|
||||
static int elt_is_zero(const u8 *d)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
if (d[i] != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void elt_add(u8 *d, const u8 *a, const u8 *b)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 30; i++)
|
||||
d[i] = a[i] ^ b[i];
|
||||
}
|
||||
|
||||
static void elt_mul_x(u8 *d, const u8 *a)
|
||||
{
|
||||
u8 carry, x, y;
|
||||
u32 i;
|
||||
|
||||
carry = a[0] & 1;
|
||||
|
||||
x = 0;
|
||||
for (i = 0; i < 29; i++) {
|
||||
y = a[i + 1];
|
||||
d[i] = x ^ (y >> 7);
|
||||
x = y << 1;
|
||||
}
|
||||
d[29] = x ^ carry;
|
||||
|
||||
d[20] ^= carry << 2;
|
||||
}
|
||||
|
||||
static void elt_mul(u8 *d, const u8 *a, const u8 *b)
|
||||
{
|
||||
u32 i, n;
|
||||
u8 mask;
|
||||
|
||||
elt_zero(d);
|
||||
|
||||
i = 0;
|
||||
mask = 1;
|
||||
for (n = 0; n < 233; n++) {
|
||||
elt_mul_x(d, d);
|
||||
|
||||
if ((a[i] & mask) != 0)
|
||||
elt_add(d, d, b);
|
||||
|
||||
mask >>= 1;
|
||||
if (mask == 0) {
|
||||
mask = 0x80;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const u8 square[16] =
|
||||
"\x00\x01\x04\x05\x10\x11\x14\x15\x40\x41\x44\x45\x50\x51\x54\x55";
|
||||
|
||||
static void elt_square_to_wide(u8 *d, const u8 *a)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
for (i = 0; i < 30; i++) {
|
||||
d[2*i] = square[a[i] >> 4];
|
||||
d[2*i + 1] = square[a[i] & 15];
|
||||
}
|
||||
}
|
||||
|
||||
static void wide_reduce(u8 *d)
|
||||
{
|
||||
u32 i;
|
||||
u8 x;
|
||||
|
||||
for (i = 0; i < 30; i++) {
|
||||
x = d[i];
|
||||
|
||||
d[i + 19] ^= x >> 7;
|
||||
d[i + 20] ^= x << 1;
|
||||
|
||||
d[i + 29] ^= x >> 1;
|
||||
d[i + 30] ^= x << 7;
|
||||
}
|
||||
|
||||
x = d[30] & ~1;
|
||||
|
||||
d[49] ^= x >> 7;
|
||||
d[50] ^= x << 1;
|
||||
|
||||
d[59] ^= x >> 1;
|
||||
|
||||
d[30] &= 1;
|
||||
}
|
||||
|
||||
static void elt_square(u8 *d, const u8 *a)
|
||||
{
|
||||
u8 wide[60];
|
||||
|
||||
elt_square_to_wide(wide, a);
|
||||
wide_reduce(wide);
|
||||
|
||||
elt_copy(d, wide + 30);
|
||||
}
|
||||
|
||||
static void itoh_tsujii(u8 *d, const u8 *a, const u8 *b, u32 j)
|
||||
{
|
||||
u8 t[30];
|
||||
|
||||
elt_copy(t, a);
|
||||
while (j--) {
|
||||
elt_square(d, t);
|
||||
elt_copy(t, d);
|
||||
}
|
||||
|
||||
elt_mul(d, t, b);
|
||||
}
|
||||
|
||||
static void elt_inv(u8 *d, const u8 *a)
|
||||
{
|
||||
u8 t[30];
|
||||
u8 s[30];
|
||||
|
||||
itoh_tsujii(t, a, a, 1);
|
||||
itoh_tsujii(s, t, a, 1);
|
||||
itoh_tsujii(t, s, s, 3);
|
||||
itoh_tsujii(s, t, a, 1);
|
||||
itoh_tsujii(t, s, s, 7);
|
||||
itoh_tsujii(s, t, t, 14);
|
||||
itoh_tsujii(t, s, a, 1);
|
||||
itoh_tsujii(s, t, t, 29);
|
||||
itoh_tsujii(t, s, s, 58);
|
||||
itoh_tsujii(s, t, t, 116);
|
||||
elt_square(d, s);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------- */
|
||||
|
||||
static PyObject *
|
||||
_ec_elt_mul(PyObject *self /* Not used */, PyObject *args)
|
||||
{
|
||||
const char *a, *b;
|
||||
char d[30];
|
||||
int la, lb;
|
||||
if (!PyArg_ParseTuple(args, "s#s#", &a, &la, &b, &lb))
|
||||
return NULL;
|
||||
|
||||
if(la != 30 || lb != 30) {
|
||||
PyErr_SetString(PyExc_ValueError, "ELT lengths must be 30");
|
||||
return NULL;
|
||||
}
|
||||
elt_mul(d,a,b);
|
||||
return Py_BuildValue("s#", d, 30);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_ec_elt_inv(PyObject *self /* Not used */, PyObject *args)
|
||||
{
|
||||
const char *a;
|
||||
char d[30];
|
||||
int la;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#", &a, &la))
|
||||
return NULL;
|
||||
|
||||
if(la != 30) {
|
||||
PyErr_SetString(PyExc_ValueError, "ELT length must be 30");
|
||||
return NULL;
|
||||
}
|
||||
elt_inv(d,a);
|
||||
return Py_BuildValue("s#", d, 30);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
_ec_elt_square(PyObject *self /* Not used */, PyObject *args)
|
||||
{
|
||||
const char *a;
|
||||
char d[30];
|
||||
int la;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#", &a, &la))
|
||||
return NULL;
|
||||
|
||||
if(la != 30) {
|
||||
PyErr_SetString(PyExc_ValueError, "ELT length must be 30");
|
||||
return NULL;
|
||||
}
|
||||
elt_square(d,a);
|
||||
return Py_BuildValue("s#", d, 30);
|
||||
}
|
||||
|
||||
/* List of methods defined in the module */
|
||||
|
||||
static struct PyMethodDef _ec_methods[] = {
|
||||
{"elt_mul", (PyCFunction)_ec_elt_mul, METH_VARARGS, "Multiply two ELTs"},
|
||||
{"elt_inv", (PyCFunction)_ec_elt_inv, METH_VARARGS, "Take the inverse of an ELT"},
|
||||
{"elt_square", (PyCFunction)_ec_elt_square, METH_VARARGS, "Efficiently square an ELT"},
|
||||
|
||||
{NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
/* Initialization function for the module (*must* be called init_ec) */
|
||||
|
||||
static char _ec_module_documentation[] =
|
||||
"Faster C versions of some ELT functions"
|
||||
;
|
||||
|
||||
void
|
||||
init_ec()
|
||||
{
|
||||
PyObject *m, *d;
|
||||
|
||||
/* Create the module and add the functions */
|
||||
m = Py_InitModule4("_ec", _ec_methods,
|
||||
_ec_module_documentation,
|
||||
(PyObject*)NULL,PYTHON_API_VERSION);
|
||||
|
||||
/* Check for errors */
|
||||
if (PyErr_Occurred())
|
||||
Py_FatalError("can't initialize module _ec");
|
||||
}
|
||||
|
||||
9
pywii/ecmodule/setup.py
Normal file
9
pywii/ecmodule/setup.py
Normal file
@@ -0,0 +1,9 @@
|
||||
from distutils.core import setup, Extension
|
||||
|
||||
module1 = Extension('_ec',
|
||||
sources = ['_ecmodule.c'])
|
||||
|
||||
setup (name = 'ELT_C',
|
||||
version = '0.1',
|
||||
description = 'C ELT functions',
|
||||
ext_modules = [module1])
|
||||
11
pywii/pywii-tools/addhash.py
Executable file
11
pywii/pywii-tools/addhash.py
Executable file
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
import sys
|
||||
import re
|
||||
import pywii as wii
|
||||
|
||||
hash = wii.SHA.new(open(sys.argv[2]).read()).digest().encode("hex")
|
||||
f = open(sys.argv[1], "r")
|
||||
data = f.read()
|
||||
f.close()
|
||||
data = re.sub('@SHA1SUM@', hash, data)
|
||||
open(sys.argv[3], "w").write(data)
|
||||
15
pywii/pywii-tools/arclist.py
Executable file
15
pywii/pywii-tools/arclist.py
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path, struct
|
||||
import pywii as wii
|
||||
|
||||
arc = open(sys.argv[1], "rb")
|
||||
|
||||
tag, fstoff, fstsize, dataoff = struct.unpack(">IIII16x",arc.read(0x20))
|
||||
|
||||
arc.seek(fstoff)
|
||||
fst = arc.read(fstsize)
|
||||
|
||||
fst = wii.WiiFST(fst)
|
||||
|
||||
fst.show()
|
||||
26
pywii/pywii-tools/arcpack.py
Executable file
26
pywii/pywii-tools/arcpack.py
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path, struct
|
||||
import pywii as wii
|
||||
|
||||
fstb = wii.WiiFSTBuilder(0x20)
|
||||
|
||||
fstb.addfrom(sys.argv[2])
|
||||
|
||||
arc = open(sys.argv[1],"wb")
|
||||
# dummy generate to get length
|
||||
fstlen = len(fstb.fst.generate())
|
||||
dataoff = wii.align(0x20+fstlen,0x20)
|
||||
fst = fstb.fst.generate(dataoff)
|
||||
|
||||
hdr = struct.pack(">IIII16x",0x55AA382d,0x20,fstlen,dataoff)
|
||||
arc.write(hdr)
|
||||
|
||||
arc.write(fst)
|
||||
wii.falign(arc,0x20)
|
||||
for f in fstb.files:
|
||||
data = open(f, "rb").read()
|
||||
arc.write(data)
|
||||
wii.falign(arc,0x20)
|
||||
|
||||
arc.close()
|
||||
26
pywii/pywii-tools/certinfo.py
Executable file
26
pywii/pywii-tools/certinfo.py
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
certfile = args.pop(0)
|
||||
|
||||
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
|
||||
|
||||
print "Certification file %s: " % certfile
|
||||
cert = wii.WiiCert(open(certfile, "rb").read())
|
||||
cert.showinfo(" ")
|
||||
cert.showsig(certs," ")
|
||||
|
||||
print "Certificates:"
|
||||
for cert in certlist:
|
||||
cert.showinfo(" - ")
|
||||
cert.showsig(certs," ")
|
||||
28
pywii/pywii-tools/discinfo.py
Executable file
28
pywii/pywii-tools/discinfo.py
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
isofile = sys.argv[1]
|
||||
disc = wii.WiiDisc(isofile,readonly=True)
|
||||
disc.showinfo()
|
||||
|
||||
partitions = disc.read_partitions()
|
||||
|
||||
parts = range(len(partitions))
|
||||
|
||||
try:
|
||||
pnum = int(sys.argv[2])
|
||||
partitions[pnum]
|
||||
parts = [pnum]
|
||||
except:
|
||||
pass
|
||||
|
||||
for partno in parts:
|
||||
part = wii.WiiCachedPartition(disc,partno)
|
||||
part.showinfo()
|
||||
pdat = wii.WiiPartitionData(part)
|
||||
pdat.showinfo()
|
||||
|
||||
35
pywii/pywii-tools/dpkisign.py
Executable file
35
pywii/pywii-tools/dpkisign.py
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii
|
||||
|
||||
pywii.loadkeys_dpki()
|
||||
|
||||
args = sys.argv[1:]
|
||||
mode = args.pop(0)
|
||||
infile = args.pop(0)
|
||||
outfile = args.pop(0)
|
||||
certfile = args.pop(0)
|
||||
issuer = args.pop(0)
|
||||
|
||||
if sys.argv[1] == "-cetk":
|
||||
signed = pywii.WiiTik(open(infile, "rb").read())
|
||||
elif sys.argv[1] == "-tmd":
|
||||
signed = pywii.WiiTmd(open(infile, "rb").read())
|
||||
else:
|
||||
print "EYOUFAILIT"
|
||||
sys.exit(1)
|
||||
|
||||
certs, certlist = pywii.parse_certs(open(certfile).read())
|
||||
|
||||
signed.update_issuer(issuer)
|
||||
|
||||
if not signed.sign(certs):
|
||||
print "dpki signing failed"
|
||||
sys.exit(1)
|
||||
|
||||
open(outfile, "wb").write(signed.data)
|
||||
|
||||
print "successfully signed %s" % outfile
|
||||
sys.exit(0)
|
||||
|
||||
57
pywii/pywii-tools/ecchecksig.py
Executable file
57
pywii/pywii-tools/ecchecksig.py
Executable file
@@ -0,0 +1,57 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import pywii as wii
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print "Usage: %s keyfile.[priv|pub] infile"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
if sys.argv[1] == "-":
|
||||
k = sys.stdin.read()
|
||||
else:
|
||||
k = open(sys.argv[1],"rb").read()
|
||||
if len(k) not in (30,60):
|
||||
print "Failed to read key"
|
||||
sys.exit(2)
|
||||
|
||||
if len(k) == 30:
|
||||
print "Key is a private key, generating public key..."
|
||||
q = wii.ec.priv_to_pub(k)
|
||||
else:
|
||||
q = k
|
||||
|
||||
print "Public key:"
|
||||
pq = q.encode('hex')
|
||||
print "X =",pq[:30]
|
||||
print " ",pq[30:60]
|
||||
print "Y =",pq[60:90]
|
||||
print " ",pq[90:]
|
||||
print
|
||||
|
||||
indata = open(sys.argv[2],"rb").read()
|
||||
|
||||
if len(indata) < 64 or indata[:4] != "SIG0":
|
||||
print "Invalid header"
|
||||
sys.exit(3)
|
||||
|
||||
r = indata[4:34]
|
||||
s = indata[34:64]
|
||||
|
||||
sha = wii.SHA.new(indata[64:]).digest()
|
||||
print "SHA1: %s"%sha.encode('hex')
|
||||
|
||||
print
|
||||
print "Signature:"
|
||||
print "R =",r[:15].encode('hex')
|
||||
print " ",r[15:].encode('hex')
|
||||
print "S =",s[:15].encode('hex')
|
||||
print " ",s[15:].encode('hex')
|
||||
print
|
||||
|
||||
if wii.ec.check_ecdsa(q,r,s,sha):
|
||||
print "Signature is VALID"
|
||||
else:
|
||||
print "Signature is INVALID"
|
||||
sys.exit(4)
|
||||
|
||||
33
pywii/pywii-tools/ecgenpriv.py
Executable file
33
pywii/pywii-tools/ecgenpriv.py
Executable file
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os
|
||||
import pywii as wii
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
print "Usage: %s keyfile.priv"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
print "Generating private key..."
|
||||
|
||||
k = wii.ec.gen_priv_key()
|
||||
|
||||
print "Private key:"
|
||||
pk = k.encode('hex')
|
||||
print "K =",pk[:30]
|
||||
print " ",pk[30:]
|
||||
|
||||
print
|
||||
print "Corresponding public key:"
|
||||
q = wii.ec.priv_to_pub(k)
|
||||
pq = q.encode('hex')
|
||||
print "X =",pq[:30]
|
||||
print " ",pq[30:60]
|
||||
print "Y =",pq[60:90]
|
||||
print " ",pq[90:]
|
||||
|
||||
fd = open(sys.argv[1],"wb")
|
||||
os.fchmod(fd.fileno(), 0o600)
|
||||
fd.write(k)
|
||||
fd.close()
|
||||
|
||||
print "Saved private key to %s"%sys.argv[1]
|
||||
30
pywii/pywii-tools/ecpriv2pub.py
Executable file
30
pywii/pywii-tools/ecpriv2pub.py
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import pywii as wii
|
||||
|
||||
if len(sys.argv) not in (2,3):
|
||||
print "Usage: %s keyfile.priv [keyfile.pub]"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
if sys.argv[1] == "-":
|
||||
k = sys.stdin.read()
|
||||
else:
|
||||
k = open(sys.argv[1],"rb").read()
|
||||
if len(k) != 30:
|
||||
print "Failed to read private key"
|
||||
sys.exit(2)
|
||||
|
||||
print "Public key:"
|
||||
q = wii.ec.priv_to_pub(k)
|
||||
pq = q.encode('hex')
|
||||
print "X =",pq[:30]
|
||||
print " ",pq[30:60]
|
||||
print "Y =",pq[60:90]
|
||||
print " ",pq[90:]
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
fd = open(sys.argv[2],"wb")
|
||||
fd.write(q)
|
||||
fd.close()
|
||||
print "Saved public key to %s"%sys.argv[2]
|
||||
35
pywii/pywii-tools/ecsign.py
Executable file
35
pywii/pywii-tools/ecsign.py
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import pywii as wii
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print "Usage: %s keyfile.priv infile outfile"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
if sys.argv[1] == "-":
|
||||
k = sys.stdin.read()
|
||||
else:
|
||||
k = open(sys.argv[1],"rb").read()
|
||||
|
||||
if len(k) != 30:
|
||||
print "Failed to read private key"
|
||||
sys.exit(2)
|
||||
|
||||
indata = open(sys.argv[2],"rb").read()
|
||||
sha = wii.SHA.new(indata).digest()
|
||||
|
||||
print "SHA1: %s"%sha.encode('hex')
|
||||
print
|
||||
print "Signature:"
|
||||
r,s = wii.ec.generate_ecdsa(k,sha)
|
||||
print "R =",r[:15].encode('hex')
|
||||
print " ",r[15:].encode('hex')
|
||||
print "S =",s[:15].encode('hex')
|
||||
print " ",s[15:].encode('hex')
|
||||
|
||||
outdata = "SIG0" + r + s + indata
|
||||
|
||||
fd = open(sys.argv[3],"wb")
|
||||
fd.write(outdata)
|
||||
fd.close()
|
||||
59
pywii/pywii-tools/extract.py
Executable file
59
pywii/pywii-tools/extract.py
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
def parseint(d):
|
||||
if len(d) > 2 and d[0:2].lower()=='0x':
|
||||
return int(d,16)
|
||||
return int(d)
|
||||
|
||||
if len(sys.argv) < 4 or len(sys.argv) > 7:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <file to extract to> [Partition offset] [length]"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, data_name = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
part_offset = 0
|
||||
data_offset = 0
|
||||
copy_length = None
|
||||
|
||||
if len(sys.argv) >= 5:
|
||||
part_offset = parseint(sys.argv[4])
|
||||
if len(sys.argv) == 6:
|
||||
copy_length = parseint(sys.argv[5])
|
||||
|
||||
if copy_length is not None and copy_length < 0:
|
||||
print "Error: negative copy length"
|
||||
sys.exit(1)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False)
|
||||
if part_offset >= part.data_bytes:
|
||||
print "Error: Offset past end of partition"
|
||||
sys.exit(1)
|
||||
if copy_length is None:
|
||||
copy_length = part.data_bytes - part_offset
|
||||
if copy_length > (part.data_bytes - part_offset):
|
||||
print "Error: Length too large"
|
||||
sys.exit(1)
|
||||
|
||||
dataf = open(data_name, "wb")
|
||||
left = copy_length
|
||||
offset = part_offset
|
||||
while left > 0:
|
||||
blocklen = min(left, 4*1024*1024)
|
||||
d = part.read(offset, blocklen)
|
||||
if len(d) != blocklen:
|
||||
print "Part EOF reached!"
|
||||
sys.exit(1)
|
||||
dataf.write(d)
|
||||
offset += blocklen
|
||||
left -= blocklen
|
||||
|
||||
dataf.close()
|
||||
|
||||
26
pywii/pywii-tools/extractdol.py
Executable file
26
pywii/pywii-tools/extractdol.py
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import sys, os, os.path
|
||||
sys.path.append(os.path.realpath(os.path.dirname(sys.argv[0]))+"/../Common")
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys(os.environ["HOME"]+os.sep+".wii")
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <dol output>"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, dol_name = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False)
|
||||
partdata = wii.WiiPartitionData(part)
|
||||
|
||||
dolf = open(dol_name, "wb")
|
||||
dolf.write(partdata.dol)
|
||||
dolf.close()
|
||||
|
||||
|
||||
59
pywii/pywii-tools/extractfiles.py
Normal file
59
pywii/pywii-tools/extractfiles.py
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
def parseint(d):
|
||||
if len(d) > 2 and d[0:2].lower()=='0x':
|
||||
return int(d,16)
|
||||
return int(d)
|
||||
|
||||
if len(sys.argv) < 4 or len(sys.argv) > 7:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <root path to extract to> "%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, data_name = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
part_offset = 0
|
||||
data_offset = 0
|
||||
copy_length = None
|
||||
|
||||
if len(sys.argv) >= 5:
|
||||
part_offset = parseint(sys.argv[4])
|
||||
if len(sys.argv) == 6:
|
||||
copy_length = parseint(sys.argv[5])
|
||||
|
||||
if copy_length is not None and copy_length < 0:
|
||||
print "Error: negative copy length"
|
||||
sys.exit(1)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False)
|
||||
if part_offset >= part.data_bytes:
|
||||
print "Error: Offset past end of partition"
|
||||
sys.exit(1)
|
||||
if copy_length is None:
|
||||
copy_length = part.data_bytes - part_offset
|
||||
if copy_length > (part.data_bytes - part_offset):
|
||||
print "Error: Length too large"
|
||||
sys.exit(1)
|
||||
|
||||
dataf = open(data_name, "wb")
|
||||
left = copy_length
|
||||
offset = part_offset
|
||||
while left > 0:
|
||||
blocklen = min(left, 4*1024*1024)
|
||||
d = part.read(offset, blocklen)
|
||||
if len(d) != blocklen:
|
||||
print "Part EOF reached!"
|
||||
sys.exit(1)
|
||||
dataf.write(d)
|
||||
offset += blocklen
|
||||
left -= blocklen
|
||||
|
||||
dataf.close()
|
||||
|
||||
24
pywii/pywii-tools/getappldr.py
Executable file
24
pywii/pywii-tools/getappldr.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
if len(sys.argv) != 5:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <apploader text> <apploader trailer>"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, app_name, trail_name = sys.argv[1:5]
|
||||
partno = int(partno)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False)
|
||||
partdata = wii.WiiPartitionData(part)
|
||||
|
||||
apploader = partdata.apploader
|
||||
apploader.showinfo()
|
||||
open(app_name,"wb").write(apploader.text)
|
||||
open(trail_name,"wb").write(apploader.trailer)
|
||||
68
pywii/pywii-tools/inject.py
Executable file
68
pywii/pywii-tools/inject.py
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
def parseint(d):
|
||||
if len(d) > 2 and d[0:2].lower()=='0x':
|
||||
return int(d,16)
|
||||
return int(d)
|
||||
|
||||
if len(sys.argv) < 4 or len(sys.argv) > 7:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <file to inject> [Partition offset] [data offset] [length]"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, data_name = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
part_offset = 0
|
||||
data_offset = 0
|
||||
copy_length = None
|
||||
|
||||
if len(sys.argv) >= 5:
|
||||
part_offset = parseint(sys.argv[4])
|
||||
if len(sys.argv) >= 6:
|
||||
data_offset = parseint(sys.argv[5])
|
||||
if len(sys.argv) == 7:
|
||||
copy_length = parseint(sys.argv[6])
|
||||
|
||||
data_len = os.stat(data_name).st_size
|
||||
|
||||
if copy_length == None:
|
||||
copy_length = data_len - data_offset
|
||||
copy_end = data_offset + copy_length
|
||||
if copy_length < 0:
|
||||
print "Error: negative copy length"
|
||||
sys.exit(1)
|
||||
if copy_end > data_len:
|
||||
print "Error: data file is too small"
|
||||
sys.exit(1)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False, checkhash=False)
|
||||
|
||||
dataf = open(data_name, "rb")
|
||||
dataf.seek(data_offset)
|
||||
left = copy_length
|
||||
offset = part_offset
|
||||
while left > 0:
|
||||
blocklen = min(left, 4*1024*1024)
|
||||
d = dataf.read(blocklen)
|
||||
if len(d) != blocklen:
|
||||
print "File EOF reached!"
|
||||
sys.exit(1)
|
||||
part.write(offset, d)
|
||||
offset += blocklen
|
||||
left -= blocklen
|
||||
|
||||
part.flush()
|
||||
part.update()
|
||||
part.tmd.null_signature()
|
||||
part.tmd.brute_sha()
|
||||
part.updatetmd()
|
||||
|
||||
|
||||
|
||||
31
pywii/pywii-tools/injectdol.py
Executable file
31
pywii/pywii-tools/injectdol.py
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print "Usage:"
|
||||
print " python %s <encrypted ISO> <partition number> <dol to inject>"%sys.argv[0]
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, dol_name = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
|
||||
doldata = open(dol_name, "rb").read()
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False)
|
||||
partdata = wii.WiiPartitionData(part)
|
||||
partdata.replacedol(doldata)
|
||||
|
||||
part.flush()
|
||||
part.update()
|
||||
part.tmd.null_signature()
|
||||
part.tmd.brute_sha()
|
||||
part.updatetmd()
|
||||
part.showinfo()
|
||||
|
||||
|
||||
28
pywii/pywii-tools/partsetios.py
Executable file
28
pywii/pywii-tools/partsetios.py
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print "Usage:"
|
||||
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"
|
||||
sys.exit(1)
|
||||
|
||||
iso_name, partno, ios = sys.argv[1:4]
|
||||
partno = int(partno)
|
||||
iosno = int(ios)
|
||||
|
||||
disc = wii.WiiDisc(iso_name)
|
||||
disc.showinfo()
|
||||
part = wii.WiiCachedPartition(disc, partno, cachesize=32, debug=False)
|
||||
part.tmd.sys_version = 0x100000000 + iosno
|
||||
part.tmd.update()
|
||||
part.tmd.null_signature()
|
||||
part.tmd.brute_sha()
|
||||
part.updatetmd()
|
||||
part.showinfo()
|
||||
|
||||
|
||||
1
pywii/pywii-tools/pywii
Symbolic link
1
pywii/pywii-tools/pywii
Symbolic link
@@ -0,0 +1 @@
|
||||
../Common/pywii
|
||||
20
pywii/pywii-tools/rsapatch.py
Executable file
20
pywii/pywii-tools/rsapatch.py
Executable file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
def hexdump(s):
|
||||
return ' '.join(map(lambda x: "%02x"%x,map(ord,s)))
|
||||
|
||||
isofile = sys.argv[1]
|
||||
disc = WiiDisc(isofile)
|
||||
disc.showinfo()
|
||||
part = WiiPartition(disc,int(sys.argv[2]))
|
||||
part.showinfo()
|
||||
|
||||
part.tmd.update_signature(file("signthree.bin").read())
|
||||
part.tmd.brute_sha()
|
||||
part.updatetmd()
|
||||
|
||||
part.showinfo()
|
||||
|
||||
10
pywii/pywii-tools/saveinfo.py
Executable file
10
pywii/pywii-tools/saveinfo.py
Executable file
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
savefile = sys.argv[1]
|
||||
save = wii.WiiSave(savefile)
|
||||
save.showcerts()
|
||||
17
pywii/pywii-tools/tikfix.py
Executable file
17
pywii/pywii-tools/tikfix.py
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
tikfile = sys.argv[1]
|
||||
print "fixing Tik file %s " % tikfile
|
||||
tik = wii.WiiTik(open(tikfile, "rb").read())
|
||||
tik.null_signature()
|
||||
tik.brute_sha()
|
||||
tik.update()
|
||||
f = open(tikfile,"wb")
|
||||
f.write(tik.data)
|
||||
f.close()
|
||||
|
||||
28
pywii/pywii-tools/tikinfo.py
Executable file
28
pywii/pywii-tools/tikinfo.py
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
tikfile = args.pop(0)
|
||||
|
||||
certs = None
|
||||
if len(args) > 0:
|
||||
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
|
||||
|
||||
print "ETicket file %s:"%tikfile
|
||||
tik = wii.WiiTik(open(tikfile, "rb").read())
|
||||
tik.showinfo(" ")
|
||||
if certs is not None:
|
||||
tik.showsig(certs," ")
|
||||
print "Certificates:"
|
||||
for cert in certlist:
|
||||
cert.showinfo(" - ")
|
||||
cert.showsig(certs," ")
|
||||
18
pywii/pywii-tools/tmdfix.py
Executable file
18
pywii/pywii-tools/tmdfix.py
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
tmdfile = sys.argv[1]
|
||||
print "TMD file %s:"%tmdfile
|
||||
tmd = wii.WiiTmd(open(tmdfile, "rb").read())
|
||||
tmd.null_signature()
|
||||
tmd.brute_sha()
|
||||
tmd.update()
|
||||
tmd.parse()
|
||||
tmd.showinfo(" ")
|
||||
f = open(tmdfile,"wb")
|
||||
f.write(tmd.data)
|
||||
f.close()
|
||||
28
pywii/pywii-tools/tmdinfo.py
Executable file
28
pywii/pywii-tools/tmdinfo.py
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
tmdfile = args.pop(0)
|
||||
|
||||
certs = None
|
||||
if len(args) > 0:
|
||||
certs, certlist = wii.parse_certs(open(args.pop(0), "rb").read())
|
||||
|
||||
print "TMD file %s:"%tmdfile
|
||||
tmd = wii.WiiTmd(open(tmdfile, "rb").read())
|
||||
tmd.showinfo(" ")
|
||||
if certs is not None:
|
||||
tmd.showsig(certs," ")
|
||||
print "Certificates:"
|
||||
for cert in certlist:
|
||||
cert.showinfo(" - ")
|
||||
cert.showsig(certs," ")
|
||||
29
pywii/pywii-tools/tmdupdatecr.py
Executable file
29
pywii/pywii-tools/tmdupdatecr.py
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
from Crypto.Hash import SHA
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
tmdfile = args.pop(0)
|
||||
indir = args.pop(0)
|
||||
|
||||
print "updating content records of TMD file %s" % tmdfile
|
||||
tmd = wii.WiiTmd(open(tmdfile, "rb").read())
|
||||
|
||||
for i, cr in enumerate(tmd.get_content_records()):
|
||||
data = open(os.path.join(indir, "%08X" % cr.cid), "rb").read()
|
||||
cr.sha = SHA.new(data).digest()
|
||||
cr.size = len(data)
|
||||
tmd.update_content_record(i, cr)
|
||||
|
||||
tmd.null_signature()
|
||||
tmd.brute_sha()
|
||||
tmd.update()
|
||||
f = open(tmdfile, "wb")
|
||||
f.write(tmd.data)
|
||||
f.close()
|
||||
|
||||
23
pywii/pywii-tools/tmdvers.py
Executable file
23
pywii/pywii-tools/tmdvers.py
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
tmdfile = args.pop(0)
|
||||
|
||||
if len(args) == 2:
|
||||
newvers = int(args.pop(0)) << 8 | int(args.pop(0))
|
||||
else:
|
||||
newvers = int(args.pop(0), 16)
|
||||
|
||||
print "setting version of TMD file %s to 0x%04x" % (tmdfile, newvers)
|
||||
tmd = wii.WiiTmd(open(tmdfile, "rb").read())
|
||||
tmd.title_version = newvers
|
||||
tmd.update()
|
||||
f = open(tmdfile,"wb")
|
||||
f.write(tmd.data)
|
||||
f.close()
|
||||
16
pywii/pywii-tools/wadinfo.py
Executable file
16
pywii/pywii-tools/wadinfo.py
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
wadfile = args.pop(0)
|
||||
wad = wii.WiiWad(wadfile)
|
||||
wad.showinfo()
|
||||
34
pywii/pywii-tools/wadpack-boot2.py
Executable file
34
pywii/pywii-tools/wadpack-boot2.py
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
wii.loadkeys()
|
||||
|
||||
wadfile = sys.argv[1]
|
||||
indir = sys.argv[2]
|
||||
|
||||
tmd = wii.WiiTmd(open(indir+os.sep+"tmd", "rb").read())
|
||||
tik = wii.WiiTik(open(indir+os.sep+"cetk", "rb").read())
|
||||
|
||||
certs, certlist = wii.parse_certs(open(os.path.join(indir, "certs"), "rb").read())
|
||||
|
||||
footer = open(indir+os.sep+"footer", "rb").read()
|
||||
|
||||
wad = wii.WiiWadMaker(wadfile, tmd, tik, certlist, footer, nandwad=True)
|
||||
|
||||
for i,ct in enumerate(tmd.get_content_records()):
|
||||
data = open(indir+os.sep+"%08X"%ct.cid, "rb").read()
|
||||
wad.adddata(data,ct.cid)
|
||||
|
||||
wad.finish()
|
||||
|
||||
if not wad.tik.signcheck(wad.certs):
|
||||
wad.tik.null_signature()
|
||||
wad.tik.brute_sha()
|
||||
wad.updatetik()
|
||||
|
||||
if not wad.tmd.signcheck(wad.certs):
|
||||
wad.tmd.null_signature()
|
||||
wad.tmd.brute_sha()
|
||||
wad.updatetmd()
|
||||
40
pywii/pywii-tools/wadpack.py
Executable file
40
pywii/pywii-tools/wadpack.py
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
wadfile = args.pop(0)
|
||||
indir = args.pop(0)
|
||||
|
||||
tmd = wii.WiiTmd(open(os.path.join(indir, "tmd"), "rb").read())
|
||||
tik = wii.WiiTik(open(os.path.join(indir, "cetk"), "rb").read())
|
||||
|
||||
certs, certlist = wii.parse_certs(open(os.path.join(indir, "certs"), "rb").read())
|
||||
|
||||
footer = open(os.path.join(indir, "footer"), "rb").read()
|
||||
|
||||
wad = wii.WiiWadMaker(wadfile, tmd, tik, certlist, footer)
|
||||
|
||||
for i,ct in enumerate(tmd.get_content_records()):
|
||||
data = open(os.path.join(indir, "%08X" % ct.cid), "rb").read()
|
||||
wad.adddata(data,ct.cid)
|
||||
|
||||
wad.finish()
|
||||
|
||||
if not wad.tik.signcheck(wad.certs):
|
||||
wad.tik.null_signature()
|
||||
wad.tik.brute_sha()
|
||||
wad.updatetik()
|
||||
|
||||
if not wad.tmd.signcheck(wad.certs):
|
||||
wad.tmd.null_signature()
|
||||
wad.tmd.brute_sha()
|
||||
wad.updatetmd()
|
||||
44
pywii/pywii-tools/wadunpack.py
Executable file
44
pywii/pywii-tools/wadunpack.py
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys, os, os.path
|
||||
import pywii as wii
|
||||
|
||||
args = sys.argv[1:]
|
||||
|
||||
if args[0] == "-dpki":
|
||||
wii.loadkeys_dpki()
|
||||
args.pop(0)
|
||||
else:
|
||||
wii.loadkeys()
|
||||
|
||||
wadfile = args.pop(0)
|
||||
outdir = args.pop(0)
|
||||
wad = wii.WiiWad(wadfile)
|
||||
wad.showinfo()
|
||||
|
||||
if not os.path.isdir(outdir):
|
||||
os.mkdir(outdir)
|
||||
|
||||
for ct in wad.tmd.get_content_records():
|
||||
data = wad.getcontent(ct.index)
|
||||
f = open(os.path.join(outdir, "%08X" % ct.cid),"wb")
|
||||
f.write(data)
|
||||
f.close()
|
||||
|
||||
f = open(os.path.join(outdir, "cetk"),"wb")
|
||||
f.write(wad.tik.data)
|
||||
f.close()
|
||||
|
||||
f = open(os.path.join(outdir, "tmd"),"wb")
|
||||
f.write(wad.tmd.data)
|
||||
f.close()
|
||||
|
||||
f = open(os.path.join(outdir, "certs"),"wb")
|
||||
for cert in wad.certlist:
|
||||
f.write(cert.data)
|
||||
wii.falign(f,0x40)
|
||||
f.close()
|
||||
|
||||
f = open(os.path.join(outdir, "footer"),"wb")
|
||||
f.write(wad.footer)
|
||||
f.close()
|
||||
Reference in New Issue
Block a user