Guest User

Untitled

a guest
Jun 20th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.12 KB | None | 0 0
  1. import sys, os, struct, zlib
  2. from Crypto.Cipher import AES
  3.  
  4. def u32(x):
  5. return (x & 0xFFFFFFFF)
  6.  
  7. KEY_MATERIAL = 'e413645fa69cafe34a76192843e48cbd691d1f9fba87e8a23d40e02ce13b0d534d10301576f31bc70b763a60cf07149cfca50e2a6b3955b98f26ca84a5844a8aeca7318f8d7dba406af4e45c4806fa4d7b736d51cceaaf0e96f657bb3a8af9b175d51b9bddc1ed475677260f33c41ddbc1ee30b46c4df1b24a25cf7cb6019794'
  8.  
  9. class sead_rand:
  10. '''Implements Splatoon 2's mersenne random generator.'''
  11. def __init__(self, seed):
  12. self.seed = u32(seed)
  13. self.state = [self.seed]
  14. for i in xrange(1, 5):
  15. self.state.append(u32(0x6C078965 * (self.state[-1] ^ (self.state[-1] >> 30)) + i))
  16. self.state = self.state[1:]
  17. def get_u32(self):
  18. a = u32(self.state[0] ^ (self.state[0] << 11))
  19. self.state[0] = self.state[1]
  20. b = u32(self.state[3])
  21. c = u32(a ^ (a >> 8) ^ b ^ (b >> 19))
  22. self.state[1] = self.state[2]
  23. self.state[2] = b
  24. self.state[3] = c
  25. return c
  26. def decrypt_resource(path, fn, out_path = None):
  27. if not out_path:
  28. out_path = '%s.dec' % path
  29. with open(path, 'rb') as f:
  30. dat = f.read()
  31. if dat[-8:] != 'nisasyst':
  32. raise ValueError('Error: Input appears not to be an encrypted Splatoon 2 archive!')
  33. seed = u32(zlib.crc32(fn))
  34. print 'Seed = 0x%08x = crc32(%s)' % (seed, fn)
  35. key_iv = ''
  36. rnd = sead_rand(seed)
  37. for _ in xrange(0x40):
  38. key_iv += KEY_MATERIAL[(rnd.get_u32() >> 24)]
  39. key_iv = key_iv.decode('hex')
  40. key, iv = key_iv[:0x10], key_iv[0x10:]
  41. print 'Key: %s' % key.encode('hex')
  42. print 'IV: %s' % iv.encode('hex')
  43. with open(out_path, 'wb') as f:
  44. f.write(AES.new(key, AES.MODE_CBC, iv).decrypt(dat[:-8]))
  45. print 'Decrypted %s to %s!' % (path, out_path)
  46. def main(argc, argv):
  47. if argc == 3:
  48. decrypt_resource(argv[1], argv[2])
  49. elif argc == 4:
  50. decrypt_resource(argv[1], argv[2], argv[3])
  51. else:
  52. print 'Usage: %s in_file resource_path [out_file]' % argv[0]
  53. print 'Example: %s TankInfo.byml Mush/TankInfo.byml' % argv[0]
  54. if __name__ == '__main__':
  55. main(len(sys.argv), sys.argv)
Add Comment
Please, Sign In to add comment