Struggling to decrypt

This commit is contained in:
Nichlas Severinsen 2018-06-21 21:30:38 +02:00
parent 16a5e95777
commit 9d75699178
3 changed files with 139 additions and 10 deletions

1
.gitignore vendored
View file

@ -2,6 +2,7 @@
*.iso
*.ird
ird
region_*
# Byte-compiled / optimized / DLL files
__pycache__/

View file

@ -16,6 +16,61 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import os
import gzip
ORDER = 'big'
SECTOR = 2048
def bytes_to_int(byte):
return int.from_bytes(byte, ORDER)
class IRD:
def is_compressed(self, fileobj):
fileobj.seek(0)
return fileobj.read(4) != b"3IRD"
def uncompress(self, filename):
with gzip.open(filename, 'rb') as gzfile:
with open('ird', 'wb') as outfile:
outfile.write(gzfile.read())
def __init__(self, filename):
with open(filename, 'rb') as fileobj:
if self.is_compressed(fileobj):
self.uncompress(filename)
self.size = os.stat('ird').st_size
with open('ird', 'rb') as ird:
self.magic_string = ird.read(4)
self.version = bytes_to_int(ird.read(1))
self.game_id = ird.read(9)
self.game_name = ird.read(12)
self.update_version = ird.read(4)
self.game_version = ird.read(5)
if self.version == 7:
self.identifier = ird.read(4)
self.header = ird.read(SECTOR*3)
self.footer = ird.read(SECTOR)
self.region_count = ird.read(1)
print(self.game_name, self.update_version, self.game_version, self.region_count)
ird.seek(self.size - (2 + 115 + 16 + 16))
if self.version >= 9:
self.pic = ird.read(115)
self.data_one = ird.read(16)
print(self.data_one.hex())
self.data_two = ird.read(16)
if self.version < 9:
self.pic = ird.read(115)
self.uid = ird.read(2)
print(self.uid)
if filename != 'ird':
os.rm('ird')

View file

@ -22,13 +22,90 @@ import os
import sys
import core
import struct
import shutil
from Crypto.Cipher import AES
def bytes_to_int(byte):
return int.from_bytes(byte, core.ORDER)
def int_to_hexstr(integer):
return '{:02x}'.format(integer)
def int_to_bytes(integer):
return bytes(bytearray.fromhex(int_to_hexstr(integer)))
def bprint(byte):
byteint = bytes_to_int(byte)
print(byte, '\t->', byteint, '\t->', byteint*8, '\t->', byteint*2048 )
if __name__ == '__main__':
print(os.path.getsize(sys.argv[1]))
size = os.stat(sys.argv[1]) #.st_size.to_bytes(2, core.ORDER)
print(size)
#core.IRD('ird.ird')
#sys.exit()
bprint(b'\x00\x00\x00\x00')
bprint(b'\x00\x00\x0c\xbf')
bprint(b'\x00\x00\x00q\xc2')
bprint(b'\x00\x00s\xc2\x7f')
bprint(b'\x00\x00s\xc2\x80')
data = bytes(bytearray.fromhex("c9c1ec71205c2a6e8adc19795f9bfbd8"))
key = bytes(bytearray.fromhex("380bcf0b53455b3c7817ab4fa3ba90ed"))
iv = bytes(bytearray.fromhex("69474772af6fdab342743aefaa186287"))
cipher = AES.new(key, AES.MODE_CBC, iv)
disc_key = cipher.encrypt(data)
regions = [
{'start': 0, 'end': 6682624, 'enc': False},
{'start': 6682624, 'end': 59641856, 'enc': True},
{'start': 59641856, 'end': 15537010688, 'enc': False},
# There's also a last sector between 15537010688 and 15537012736, but seems like it's not used
]
files = []
with open(sys.argv[1], 'rb') as iso:
for i, region in enumerate(regions):
files.append('region_' + str(i))
with open('region_' + str(i), 'wb') as output:
iso.seek(region['start'])
if not region['enc']:
while iso.tell() < region['end']:
data = iso.read(core.SECTOR)
output.write(data)
continue
else:
while iso.tell() < region['end']:
data = iso.read(core.SECTOR)
num = iso.tell()
iv = ['' for i in range(0,16)]
for j in range(0,16):
iv[16 - j - 1] = hex(ord(struct.pack("B", num & 0xFF))).replace('0x','')
num >>= 8
iv = "".join(iv)[-16:]
#print(iv)
cipher = AES.new(disc_key, AES.MODE_CBC, iv)
output.write(cipher.decrypt(data))
print(iso.tell())
with open('output.iso', 'wb') as iso:
for f in files:
with open(f, 'rb') as fd:
shutil.copyfileobj(fd, iso, 1024*1024*10)
sys.exit()
size = os.stat(sys.argv[1]).st_size
size_hex = bytes(bytearray.fromhex(hex(int(size / 2048)).replace('0x','').zfill(16)))
print(size, size_hex)
with open(sys.argv[1], 'rb') as iso:
sector1 = iso.read(core.SECTOR)
num_unenc_sectors = int.from_bytes(sector1[0:4], core.ORDER)
@ -40,17 +117,12 @@ if __name__ == '__main__':
regions.append({'start': sector1[8+4*i:12+4*i], 'end': sector1[12+4*i:16+4*i], 'enc': encrypted})
encrypted = not encrypted
regions.append({'start': regions[-1]['end'], 'end': size, 'enc': True})
regions.append({'start': regions[-1]['end'], 'end': size_hex, 'enc': True})
print(regions)
# data1 from ird: 44 4901 0800 0020 0042 444f 0111 0101 00
# TODO: import .ird (which can either be plaintext starting with 3IRD or .gz)
data = bytes(bytearray.fromhex("444901080000200042444f0111010100"))
key = bytes(bytearray.fromhex("380bcf0b53455b3c7817ab4fa3ba90ed"))
iv = bytes(bytearray.fromhex("69474772af6fdab342743aefaa186287"))
cipher = AES.new(key, AES.MODE_CBC, iv)
disc_key = cipher.encrypt(data)
print(disc_key)
with open('output.iso', 'wb') as output:
@ -64,6 +136,7 @@ if __name__ == '__main__':
print('end: ', end)
print('size: ', end - start - 1)
if region['enc']:
num = end
print(num)
iv = ['' for i in range(0,16)]