Guest User

Untitled

a guest
Sep 18th, 2011
778
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.88 KB | None | 0 0
  1. # modified by GliGli and Tiros for the reset glitch hack
  2.  
  3. # you might need to fill in this
  4. secret_1BL = "\xDD\x88\xAD\x0C\x9E\xD6\x69\xE7\xB5\x67\x94\xFB\x68\x56\x3E\xFA"
  5. cpukey = "\x2B\xFD\x39\xE1\x35\xDA\x26\xF0\x5B\x4A\x34\x44\xE8\x55\xD2\x4E"
  6.  
  7. #XELL_BASE_FLASH = 0xc0000
  8. #CODE_BASE = 0x1c000000
  9.  
  10. # don't change anything from here.
  11.  
  12. # so we can do updates properly
  13. SCRIPT_VERSION = 0x01
  14.  
  15. Keyvault = None
  16. SMC = None
  17. CB_A = None
  18. CB_A_crypted = None
  19. CB_B = None
  20. CD = None
  21. CD_plain = None
  22. CE = None
  23. CF = None
  24. CG = None
  25. #Xell = ""
  26. #Exploit = None
  27.  
  28. #if secret_1BL is None:
  29. # secret_1BL = open("key_1BL.bin", "rb").read()
  30.  
  31. # Import Psyco if available
  32. try:
  33. import psyco
  34. psyco.full()
  35. except ImportError:
  36. pass
  37.  
  38. # first, unpack base input image. We are ignoring any updates here
  39. import hmac, sha, struct, sys, binascii
  40. try:
  41. import Crypto.Cipher.ARC4 as RC4
  42. except ImportError:
  43. print "Error importing Crypto.Cipher.ARC4 - please install python-crypto!"
  44. print "You can get it from http://www.dlitz.net/software/pycrypto/"
  45. sys.exit(-1)
  46.  
  47. def unpack_base_image(image):
  48. global SMC, CB_A, CB_B, CD, CE, Keyvault
  49.  
  50. if image[0x205] == "\xFF" or image[0x415] == "\xFF" or image[0x200] == "\xFF":
  51. print "ECC'ed - will unecc."
  52. res = ""
  53. for s in range(0, len(image), 528):
  54. res += image[s:s+512]
  55. image = res
  56.  
  57. unpackstring = "!HHLLL64s5LLLLLLLL"
  58. (id1, build, flags, bloffset, size0, copyright, z0, z1, z2, z3, r7, size1, r3, r4, z5, z6, smc_len, smc_start) = struct.unpack(unpackstring, image[:struct.calcsize(unpackstring)])
  59. #assert not (z0 or z1 or z2 or z3 or z5 or z6), "zeros are not zero."
  60.  
  61. block_offset = bloffset
  62.  
  63. SMC = image[smc_start:smc_start+smc_len]
  64. Keyvault = image[0x4000:0x8000]
  65.  
  66. assert smc_len == 0x3000, "never saw an SMC != 0x3000 bytes"
  67. semi = 0
  68. for block in range(30):
  69. (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
  70. block_size += 0xF
  71. block_size &= ~0xF
  72. id = ord(block_id[1]) & 0xF
  73.  
  74. print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
  75. data = image[block_offset:block_offset+block_size]
  76.  
  77. if id == 2:
  78. if semi == 0:
  79. CB_A = data
  80. semi = 1
  81. elif semi ==1:
  82. CB_B = data
  83. semi = 0
  84.  
  85. elif id == 4:
  86. CD = data
  87. elif id == 5:
  88. CE = data
  89.  
  90. block_offset += block_size
  91.  
  92. if id == 5:
  93. break
  94.  
  95. assert CB_A and CD
  96.  
  97. def unpack_update(image):
  98. global CF, CG
  99.  
  100. block_offset = 0
  101. for block in range(30):
  102. (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
  103. block_size += 0xF
  104. block_size &= ~0xF
  105. id = ord(block_id[1]) & 0xF
  106.  
  107. print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
  108. data = image[block_offset:block_offset+block_size]
  109.  
  110. if id == 6:
  111. CF = data
  112. elif id == 7:
  113. CG = data
  114.  
  115. block_offset += block_size
  116.  
  117. if id == 7:
  118. break
  119.  
  120. def build(data):
  121. return struct.unpack(">H", data[2:4])[0]
  122.  
  123. def decrypt_CB(CB):
  124. secret = secret_1BL
  125. key = hmac.new(secret, CB[0x10:0x20], sha).digest()[0:0x10]
  126. CB = CB[0:0x10] + key + RC4.new(key).decrypt(CB[0x20:])
  127. return CB
  128.  
  129. def decrypt_CB_Cpu(CB):
  130. assert cpukey
  131. secret = CB_A[0x10:0x20]
  132. h = hmac.new(secret,None, sha);
  133. h.update(CB[0x10:0x20]);
  134. h.update(cpukey);
  135. key = h.digest()[0:0x10]
  136. CB = CB[0:0x10] +key+ RC4.new(key).decrypt(CB[0x20:])
  137. return CB
  138.  
  139. def decrypt_CD(CD, CB):
  140. # enable this code if you want to extract CD from a flash image and you know the cup key.
  141. # disable this when this is a zero-paired image.
  142. assert cpukey or build(CD) < 1920
  143. secret = CB[0x10:0x20]
  144. key = hmac.new(secret, CD[0x10:0x20], sha).digest()[0:0x10]
  145. if build(CD) >= 1920:
  146. key = hmac.new(cpukey, key, sha).digest()[0:0x10]
  147. CD = CD[0:0x10] + key + RC4.new(key).decrypt(CD[0x20:])
  148. return CD
  149.  
  150. def decrypt_CE(CE, CD):
  151. secret = CD[0x10:0x20]
  152. key = hmac.new(secret, CE[0x10:0x20], sha).digest()[0:0x10]
  153. CE = CE[0:0x10] + key + RC4.new(key).decrypt(CE[0x20:])
  154. return CE
  155.  
  156. def decrypt_CF(CF):
  157. secret = secret_1BL
  158. key = hmac.new(secret, CF[0x20:0x30], sha).digest()[0:0x10]
  159. CF = CF[0:0x20] + key + RC4.new(key).decrypt(CF[0x30:])
  160. return CF
  161.  
  162. def decrypt_CG(CG, CF):
  163. secret = CF[0x330:0x330+0x10]
  164. key = hmac.new(secret, CG[0x10:0x20], sha).digest()[0:0x10]
  165. CG = CG[:0x10] + key + RC4.new(key).decrypt(CG[0x20:])
  166. return CG
  167.  
  168. def decrypt_SMC(SMC):
  169. key = [0x42, 0x75, 0x4e, 0x79]
  170. res = ""
  171. for i in range(len(SMC)):
  172. j = ord(SMC[i])
  173. mod = j * 0xFB
  174. res += chr(j ^ (key[i&3] & 0xFF))
  175. key[(i+1)&3] += mod
  176. key[(i+2)&3] += mod >> 8
  177. return res
  178.  
  179. def encrypt_CB(CB, random):
  180. secret = secret_1BL
  181. key = hmac.new(secret, random, sha).digest()[0:0x10]
  182. CB = CB[0:0x10] + random + RC4.new(key).encrypt(CB[0x20:])
  183. return CB, key
  184.  
  185. def encrypt_CB_Cpu(CB):
  186. assert cpukey
  187. secret = CB_A[0x10:0x20]
  188. h = hmac.new(secret,None, sha);
  189. h.update(CB[0x10:0x20]);
  190. h.update(cpukey);
  191. key = h.digest()[0:0x10]
  192. CB = CB[0:0x20] + RC4.new(key).encrypt(CB[0x20:])
  193. return CB, key
  194.  
  195. def encrypt_CD(CD, CB_key, random):
  196. secret = CB_key
  197. key = hmac.new(secret, random, sha).digest()[0:0x10]
  198. CD = CD[0:0x10] + random + RC4.new(key).encrypt(CD[0x20:])
  199. return CD, key
  200.  
  201. def encrypt_CE(CE, CD_key, random):
  202. secret = CD_key
  203. key = hmac.new(secret, random, sha).digest()[0:0x10]
  204. CE = CE[0:0x10] + random + RC4.new(key).encrypt(CE[0x20:])
  205. return CE
  206.  
  207. def encrypt_CF(CF, random):
  208. secret = secret_1BL
  209. key = hmac.new(secret, random, sha).digest()[0:0x10]
  210. CF_key = CF[0x330:0x330+0x10]
  211. CF = CF[0:0x20] + random + RC4.new(key).encrypt(CF[0x30:])
  212. return CF, CF_key
  213.  
  214. def encrypt_CG(CG, CF_key, random):
  215. secret = CF_key
  216. key = hmac.new(secret, random, sha).digest()[0:0x10]
  217. CG = CG[:0x10] + random + RC4.new(key).encrypt(CG[0x20:])
  218. return CG
  219.  
  220. def encrypt_SMC(SMC):
  221. key = [0x42, 0x75, 0x4e, 0x79]
  222. res = ""
  223. for i in range(len(SMC)):
  224. j = ord(SMC[i]) ^ (key[i&3] & 0xFF)
  225. mod = j * 0xFB
  226. res += chr(j)
  227. key[(i+1)&3] += mod
  228. key[(i+2)&3] += mod >> 8
  229. return res
  230.  
  231. # CB_patches is an array of patchsets, a patchset is a version number followed by an array of patches, a patch is 3 ints: [offset,plaintext,patch]
  232.  
  233. CB_patches = [[9188,[[0x4f08,0x409a0010,0x60000000],[0x5618,0x480018e1,0x60000000],[0x5678,0x480000b9,0x60000000]]]]
  234.  
  235. def int_to_str(i):
  236. return [chr((i>>24) & 0xff),chr((i>>16) & 0xff),chr((i>>8) & 0xff),chr(i & 0xff)]
  237.  
  238. def patch_CB(CB):
  239. found = False
  240.  
  241. for versions in CB_patches:
  242. if build(CB) == versions[0]:
  243. print "patchset for %d found, %d patch(es)" % (versions[0],len(versions[1]))
  244. found = True
  245. for patches in versions[1]:
  246. plain = int_to_str(patches[1])
  247. patch = int_to_str(patches[2])
  248.  
  249. patched = ""
  250.  
  251. for i in range(4):
  252. keystream = ord(plain[i]) ^ ord(CB[i+patches[0]])
  253. patched = patched + chr(keystream ^ ord(patch[i]))
  254.  
  255. CB = CB[:patches[0]] + patched + CB[patches[0]+4:]
  256.  
  257. assert found,"can't patch that CB"
  258.  
  259. return CB
  260.  
  261. # SMC_patches is an array of patchsets, a patchset is a crc32 of the image minus first 4 bytes, human readable version info and an array of patches, a patch is: [offset,byte0,byte1,...]
  262.  
  263. SMC_patches = [[0xf9c96639,"Trinity, version 3.1",[[0x13b3,0x00,0x00]]],
  264. [0x5b3aed00,"Jasper, version 2.3",[[0x12ba,0x00,0x00]]],
  265. [0x9ad5b7ee,"Zephyr, version 1.10",[[0x1257,0x00,0x00]]],
  266. [0x7e5bc217,"Zephyr, version 1.13",[[0x12a3,0x00,0x00]]],
  267. [0x1d0c613e,"Falcon, version 1.6",[[0x12a3,0x00,0x00]]]]
  268.  
  269. def patch_SMC(SMC):
  270. found = False
  271.  
  272. smc_crc = binascii.crc32(SMC[4:]) & 0xffffffff
  273.  
  274. print "CRC32: %x" % (smc_crc)
  275.  
  276. for versions in SMC_patches:
  277. if smc_crc == versions[0]:
  278. print "patchset \"%s\" matches, %d patch(es)" % (versions[1],len(versions[2]))
  279. found = True
  280. for patches in versions[2]:
  281. for i in range(len(patches)-1):
  282. SMC = SMC[:patches[0]+i] + chr(patches[i+1]) + SMC[patches[0]+i+1:]
  283.  
  284. if not found:
  285. print" ! Warning: can't patch that SMC, here are the current supported versions:"
  286. for versions in SMC_patches:
  287. print " - %s" % versions[1]
  288.  
  289. return SMC
  290.  
  291.  
  292. def allzero(string):
  293. for x in string:
  294. if ord(x):
  295. return False
  296. return True
  297.  
  298. def allFF(string):
  299. for x in string:
  300. if ord(x) != 0xFF:
  301. return False
  302. return True
  303.  
  304. def calcecc(data):
  305. assert len(data) == 0x210
  306. val = 0
  307. for i in range(0x1066):
  308. if not i & 31:
  309. v = ~struct.unpack("<L", data[i/8:i/8+4])[0]
  310. val ^= v & 1
  311. v >>= 1
  312. if val & 1:
  313. val ^= 0x6954559
  314. val >>= 1
  315.  
  316. val = ~val
  317. return data[:-4] + struct.pack("<L", (val << 6) & 0xFFFFFFFF)
  318.  
  319. def addecc(data, block = 0, off_8 = "\x00" * 4):
  320. res = ""
  321. while len(data):
  322. d = (data[:0x200] + "\x00" * 0x200)[:0x200]
  323. data = data[0x200:]
  324.  
  325. d += struct.pack("<L4B4s4s", block / 32, 0, 0xFF, 0, 0, off_8, "\0\0\0\0")
  326. d = calcecc(d)
  327. block += 1
  328. res += d
  329. return res
  330.  
  331. import sys
  332.  
  333. for i in sys.argv[1:]:
  334. image = open(i, "rb").read()[:1*1024*1024]
  335. if image[:2] == "\xFF\x4F":
  336. print " * found flash image, unpacking..."
  337. unpack_base_image(image)
  338. CB_A_crypted = CB_A
  339. SMC = decrypt_SMC(SMC)
  340. elif image[:2] == "CB":
  341. print " * found (hopefully) decrypted CB"
  342. CB_A_crypted = None
  343. CB_A = image
  344. elif image[:2] == "CD" and allzero(image[0x20:0x230]):
  345. print " * found decrypted CD"
  346. CD_plain = image
  347. elif image[:2] == "CF":
  348. print " * found update"
  349. unpack_update(image)
  350. CF = decrypt_CF(CF)
  351. CG = decrypt_CG(CG, CF)
  352. elif len(image) == 0x3000 and image.find("<Copyright 2001-") >= 0:
  353. print " * found decrypted SMC"
  354. SMC = image
  355. elif len(image) == 0x3000:
  356. print " * found encrypted SMC (i hope so)"
  357. SMC = decrypt_SMC(image)
  358. #elif image[-0x10:] == "x" * 16:
  359. #print " * found XeLL binary, must be linked to %08x" % CODE_BASE
  360.  
  361. #assert len(image) <= 256*1024
  362. #image = (image + "\0" * 256*1024)[:256*1024]
  363. #Xell += image
  364. else:
  365. raise " * unknown image found in file %s!" % i
  366.  
  367. print " * we found the following parts:"
  368. print "SMC: %d.%d" %(ord(SMC[0x101]),ord(SMC[0x102]))
  369. print "CB_A:", CB_A and build(CB_A) or "missing"
  370. print "CB_B:", CB_B and build(CB_B) or "missing"
  371. print "CD (image):", CD and build(CD) or "missing"
  372. print "CD (decrypted):", CD_plain and build(CD_plain) or "missing"
  373.  
  374. if not CB_B:
  375. print " * checking for proper 1BL key...",
  376. sum = 0
  377. for v in secret_1BL:
  378. sum = sum + ord(v)
  379. assert sum == 0x983, "you need to fill in secret_1BL properly!"
  380. print "ok"
  381.  
  382. if CB_A_crypted:
  383. print " * decrypting..."
  384. CB_A = decrypt_CB(CB_A_crypted)
  385. open("output/CB_A.bin", "wb").write(CB_A)
  386. CD = decrypt_CD(CD, CB_A)
  387. CE = decrypt_CE(CE, CD)
  388.  
  389. print "CD:", CD and build(CD) or "missing"
  390. print "CE:", CE and build(CE) or "missing"
  391. print "CF:", CF and build(CF) or "missing"
  392. print "CG:", CG and build(CG) or "missing"
  393. open("output/CE.bin", "wb").write(CE)
  394. #open("output/CG.bin", "wb").write(CG)
  395. print " * checking if all files decrypted properly...",
  396. assert allzero(SMC[-4:])
  397. assert allzero(CE[0x20:0x28])
  398. assert allzero(CF[0x30:0x230])
  399. #assert allzero(CG[-0x20:-0x18])
  400. print "ok"
  401.  
  402. print " * checking required versions...",
  403. assert CD_plain, "you need a decrypted CD"
  404. print "ok"
  405.  
  406. xenon_builds = []
  407. zephyr_builds = [4578]
  408. falcon_builds = []
  409. jasper_builds = [6750]
  410. trinity_builds = [9188]
  411.  
  412. print " * this image will be valid *only* for:",
  413. if build(CB_A) in xenon_builds: print "xenon",
  414. if build(CB_A) in zephyr_builds: print "zephyr",
  415. if build(CB_A) in falcon_builds: print "falcon",
  416. if build(CB_A) in jasper_builds: print "jasper",
  417. if build(CB_A) in trinity_builds: print "trinity (slim)",
  418. print
  419.  
  420. Final = ""
  421.  
  422. print " * patching SMC..."
  423. SMC=patch_SMC(SMC)
  424.  
  425. CD = CD_plain
  426.  
  427. if CB_B:
  428. print " * patching CB_B..."
  429.  
  430. CB_B = patch_CB(CB_B)
  431.  
  432. c = "patched CB img"
  433. else:
  434. print " * zero-pairing..."
  435.  
  436. CB_A = CB_A[0:0x20] + "\0" * 0x20 + CB_A[0x40:]
  437.  
  438. c = "zeropair image"
  439.  
  440. open("output/CB_A.bin", "wb").write(CB_A)
  441. if CB_B:
  442. open("output/CB_B.bin", "wb").write(CB_B)
  443. open("output/SMC.bin", "wb").write(SMC)
  444.  
  445. print " * constructing new image..."
  446.  
  447. base_size = 0x8000 + len(CB_A) + len(CD) + len(CE)
  448. if CB_B:
  449. base_size += len(CB_B)
  450. base_size += 16383
  451. base_size &=~16383
  452.  
  453. patch_offset = base_size
  454.  
  455. print " * base size: %x" % base_size
  456.  
  457. c += ", version=%02x, CB=%d" % (SCRIPT_VERSION, build(CB_A))
  458. Header = struct.pack(">HHLLL64s5LLLLLLLL", 0xFF4F, 1888, 0, 0x8000, base_size, c, 0, 0, 0, 0, 0x4000, patch_offset, 0x20712, 0x4000, 0, 0, 0x3000, 0x1000)
  459.  
  460. Header = (Header + "\0" * 0x1000)[:0x1000]
  461. random = "\0" * 16
  462.  
  463. SMC = encrypt_SMC(SMC)
  464.  
  465. if not CB_B:
  466. CB_A, CB_A_key = encrypt_CB(CB_A, random)
  467. CD, CD_key = encrypt_CD(CD, CB_A_key, random)
  468. CE = encrypt_CE(CE, CD_key, random)
  469.  
  470. #assert len(Final) < XELL_BASE_FLASH, "Please move XELL_BASE_FLASH"
  471.  
  472. #if len(Xell) <= 256*1024:
  473. #print " * No separate recovery Xell available!"
  474. #Xell *= 2
  475.  
  476. print " * Flash Layout:"
  477.  
  478. def add_to_flash(d, w, offset = 0):
  479. global Final
  480. print "0x%08x..0x%08x (0x%08x bytes) %s" % (offset + len(Final), offset + len(Final) + len(d) - 1, len(d), w)
  481. Final += d
  482.  
  483. def pad_to(loc):
  484.  
  485. global Final
  486. print loc
  487. pad = "\xFF" * (loc - len(Final))
  488. add_to_flash(pad, "Padding")
  489.  
  490. add_to_flash(Header[:0x200], "Header")
  491. pad_to(0x1000)
  492. add_to_flash(SMC, "SMC")
  493. add_to_flash(Keyvault, "Keyvault")
  494.  
  495. if CB_B:
  496. add_to_flash(CB_A_crypted, "CB_A %d" % build(CB_A))
  497. add_to_flash(CB_B, "CB_B %d" % build(CB_B))
  498. else:
  499. add_to_flash(CB_A, "CB_A %d" % build(CB_A))
  500.  
  501. add_to_flash(CD, "CD %d" % build(CD))
  502. add_to_flash(CE, "CE %d" % build(CE))
  503. pad_to(patch_offset)
  504. add_to_flash(CF, "CF %d" % build(CF))
  505. add_to_flash(CG, "CG %d" % build(CG))
  506. #pad_to(XELL_BASE_FLASH)
  507. #add_to_flash(Xell[0:256*1024], "Xell (backup)")
  508. #add_to_flash(Xell[256*1024:], "Xell (main)")
  509.  
  510. print " * Encoding ECC..."
  511.  
  512. Final = addecc(Final)
  513.  
  514. open("output/image_00000000.ecc", "wb").write(Final)
  515.  
  516. print "------------- Written into output/image_00000000.ecc"
Advertisement
Add Comment
Please, Sign In to add comment