Aller au contenu


Photo

Probléme 360 Freeboot For Cygnos Tool


  • Veuillez vous connecter pour répondre
4 réponses à ce sujet

Posté 23 septembre 2010 - 21:18

#1
Hyxenstus

Hyxenstus

    Sunriseur

  • Members
  • PipPip
  • 25 messages
  • Sexe:Male
Bien le bonjour la companie,

Je me soumet à vous car une de mes XBOX 360 que je désire JTAGué joue les fortes têtes, je m'explique :

- J'ai effectué plusieurs Dumps (à l'aide de ma Cygnos) sans aucuns soucis
- J'ai extrait mon SMC avec Cygnos 360 Toolbox 1.09

Et là les problémes commencent :

- 360 Freeboot For Cygnos Tool refuse de prendre mon SMC

Fichier joint  smc.GIF   15,29 Ko   14 téléchargement(s)

- Je lance alors le script sous cygwin et j'obtient le message :

Fichier joint  cygwin.GIF   25,06 Ko   16 téléchargement(s)

Quelqu'un pourait - il me venir en aide ?

Hyxenstus
  • Retour en haut

Posté 24 septembre 2010 - 17:36

#2
Hyxenstus

Hyxenstus

    Sunriseur

  • Members
  • PipPip
  • 25 messages
  • Sexe:Male

360 Freeboot for cygnos tool est malheureusement dépassée aujourd'hui par manque de temps pour en faire une nouvelle version.

Je t'invite à utiliser le logiciel de bestpig qui est très bien. tu n'auras plus besoin d'extraire SMC, KV ou quoi que ce soit d'autre, tu as juste besoin de ta clée CPU et de ta nand d'origine.



Merci pour cette réponse mais j'ai trouvé la solution : j'ai modifié le build.py et sa marche nickel maintenant.

Build.py :

# we need to build an image with:

# SMC fitting to system type + hack
# CB = 1920+, zeropaired
# CD for CB
# CE
# CF 4558, zeropaired
# CG
# Xell
# exploit buffer

# where in flash to find the XELL image

# you need to fill in this
secret_1BL = "\xDD\x88\xAD\x0C\x9E\xD6\x69\xE7\xB5\x67\x94\xFB\x68\x56\x3E\xFA"

XELL_BASE_FLASH = 0xc0000
CODE_BASE = 0x1c000000
EXPLOIT_BASE = 0x200
SMC_CONFIG_START = 0xff7e00
SMC_CONFIG_END = 0xffbe00
FLASH_END = 0x1080000

CROSS_COMPILE = "powerpc64-linux-gnu-"

# don't change anything from here.

# so we can do updates properly
SCRIPT_VERSION = 0x00

Keyvault = None
SMC = None
SMC_CONFIG = None
CB = None
CD = None
CE = None
CF = None
CG = None
Xell = ""
Exploit = None
CONSOLE = None

if secret_1BL is None:
	secret_1BL = open("key_1BL.bin", "rb").read()

 # Import Psyco if available
try:
	import psyco
	psyco.full()
except ImportError:
	pass

# first, unpack base input image. We are ignoring any updates here
import hmac, sha, struct, sys
try:
	import Crypto.Cipher.ARC4 as RC4
except ImportError:
	print "Error importing Crypto.Cipher.ARC4 - please install python-crypto!"
	print "You can get it from http://www.dlitz.net/software/pycrypto/"
	sys.exit(-1)

def unpack_base_image(image):
	global SMC, SMC_CONFIG, CB, CD, CE, Keyvault

	if image[0x205] == "\xFF" or image[0x415] == "\xFF" or image[0x200] == "\xFF":
		print "ECC'ed - will unecc."
		res = ""
		for s in range(0, len(image), 528):
			res += image[s:s+512]
		image = res

	unpackstring = "!HHLLL64s5LLLLLLLL"
	(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)])
	assert not (z0 or z1 or z2 or z3 or z6), "zeros are not zero."

	block_offset = bloffset

	SMC = image[smc_start:smc_start+smc_len]

	if len(image) == 16*1024*1024:
		SMC_CONFIG = image[0xf7c000:0xf80000]

	Keyvault = image[0x4000:0x8000]

	assert smc_len == 0x3000, "never saw an SMC != 0x3000 bytes"

	for block in range(30):
		(block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
		block_size += 0xF
		block_size &= ~0xF
		id = ord(block_id[1]) & 0xF

		print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
		data = image[block_offset:block_offset+block_size]

		if id == 2:
			CB = data
		elif id == 4:
			CD = data
		elif id == 5:
			CE = data

		block_offset += block_size

		if id == 5:
			break

	assert CB and CD and CE

def unpack_update(image):
	global CF, CG

	block_offset = 0
	for block in range(30):
		(block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
		block_size += 0xF
		block_size &= ~0xF
		id = ord(block_id[1]) & 0xF

		print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
		data = image[block_offset:block_offset+block_size]

		if id == 6:
			CF = data
		elif id == 7:
			CG = data

		block_offset += block_size

		if id == 7:
			break

def build(data):
	return struct.unpack(">H", data[2:4])[0]

def decrypt_CB(CB):
	secret = secret_1BL
	key = hmac.new(secret, CB[0x10:0x20], sha).digest()[0:0x10]
	CB = CB[0:0x10] + key + RC4.new(key).decrypt(CB[0x20:])
	return CB

def decrypt_CD(CD, CB, cpukey = None):
# enable this code if you want to extract CD from a flash image and you know the cup key.
# disable this when this is a zero-paired image.
#	assert cpukey or build(CD) < 1920
	secret = CB[0x10:0x20]
	key = hmac.new(secret, CD[0x10:0x20], sha).digest()[0:0x10]
#	if build(CD) >= 1920:
#		key = hmac.new(cpukey, key, sha).digest()[0:0x10]
	CD = CD[0:0x10] + key + RC4.new(key).decrypt(CD[0x20:])
	return CD

def decrypt_CE(CE, CD):
	secret = CD[0x10:0x20]
	key = hmac.new(secret, CE[0x10:0x20], sha).digest()[0:0x10]
	CE = CE[0:0x10] + key + RC4.new(key).decrypt(CE[0x20:])
	return CE

def decrypt_CF(CF):
	secret = secret_1BL
	key = hmac.new(secret, CF[0x20:0x30], sha).digest()[0:0x10]
	CF = CF[0:0x20] + key + RC4.new(key).decrypt(CF[0x30:])
	return CF

def decrypt_CG(CG, CF):
	secret = CF[0x330:0x330+0x10]
	key = hmac.new(secret, CG[0x10:0x20], sha).digest()[0:0x10]
	CG = CG[:0x10] + key + RC4.new(key).decrypt(CG[0x20:])
	return CG

def decrypt_SMC(SMC):
	key = [0x42, 0x75, 0x4e, 0x79]
	res = ""
	for i in range(len(SMC)):
		j = ord(SMC[i])
		mod = j * 0xFB
		res += chr(j ^ (key[i&3] & 0xFF))
		key[(i+1)&3] += mod
		key[(i+2)&3] += mod >> 8
	return res

def encrypt_CB(CB, random):
	secret = secret_1BL
	key = hmac.new(secret, random, sha).digest()[0:0x10]
	CB = CB[0:0x10] + random + RC4.new(key).encrypt(CB[0x20:])
	return CB, key

def encrypt_CD(CD, CB_key, random):
	secret = CB_key
	key = hmac.new(secret, random, sha).digest()[0:0x10]
	CD = CD[0:0x10] + random + RC4.new(key).encrypt(CD[0x20:])
	return CD, key

def encrypt_CE(CE, CD_key, random):
	secret = CD_key
	key = hmac.new(secret, random, sha).digest()[0:0x10]
	CE = CE[0:0x10] + random + RC4.new(key).encrypt(CE[0x20:])
	return CE

def encrypt_CF(CF, random):
	secret = secret_1BL
	key = hmac.new(secret, random, sha).digest()[0:0x10]
	CF_key = CF[0x330:0x330+0x10]
	CF = CF[0:0x20] + random + RC4.new(key).encrypt(CF[0x30:])
	return CF, CF_key

def encrypt_CG(CG, CF_key, random):
	secret = CF_key
	key = hmac.new(secret, random, sha).digest()[0:0x10]
	CG = CG[:0x10] + random + RC4.new(key).encrypt(CG[0x20:])
	return CG

def encrypt_SMC(SMC):
	key = [0x42, 0x75, 0x4e, 0x79]
	res = ""
	for i in range(len(SMC)):
		j = ord(SMC[i]) ^ (key[i&3] & 0xFF)
		mod = j * 0xFB
		res += chr(j)
		key[(i+1)&3] += mod
		key[(i+2)&3] += mod >> 8
	return res

import sys

for i in sys.argv[1:]:
	image = open(i, "rb").read()
	if image[:2] == "\xFF\x4F":
		print " * found flash image, unpacking and decrypting..."
		unpack_base_image(image)
		CB = decrypt_CB(CB)
		CD = decrypt_CD(CD, CB)
		CE = decrypt_CE(CE, CD)
		SMC = decrypt_SMC(SMC)
	elif image[:2] == "CB":
		print " * found (hopefully) decrypted CB"
		CB = image
	elif image[:2] == "CD":
		print " * found (hopefully) raw CD"
		CD = image
	elif image[:2] == "CF":
		print " * found update"
		unpack_update(image)
		CF = decrypt_CF(CF)
		CG = decrypt_CG(CG, CF)
	elif len(image) == 0x3000 and image.find("<Copyright 2001-") >= 0:
		print " * found decrypted SMC"
		SMC = image
	elif len(image) == 0x3000:
		print " * found encrypted SMC (i hope so)"
		SMC = decrypt_SMC(image)
	elif image[-0x10:] == "x" * 16:
		print " * found XeLL binary, must be linked to %08x" % CODE_BASE

		assert len(image) <= 256*1024
		image = (image + "\0" * 256*1024)[:256*1024]
		Xell += image
	else:
		assert len(image) <= 256*1024
		image = (image + "\0" * 256*1024)[:256*1024]
		Xell += image

print " * we found the following parts:"
print "CB:", CB and build(CB) or "missing"
print "CD:", CD and build(CD) or "missing"
print "CE:", CE and build(CE) or "missing"
print "CF:", CF and build(CF) or "missing"
print "CG:", CG and build(CG) or "missing"

open("output/CB", "wb").write(CB)
open("output/CD", "wb").write(CD)
open("output/CE", "wb").write(CE)
open("output/CF", "wb").write(CF)
open("output/CG", "wb").write(CG)
open("output/SMC", "wb").write(SMC)

def allzero(string):
	for x in string:
		if ord(x):
			return False
	return True

def allFF(string):
	for x in string:
		if ord(x) != 0xFF:
			return False
	return True

print " * checking if all files decrypted properly...",
assert allzero(CB[0x270:0x390])
assert allzero(CD[0x20:0x230])
assert allzero(CE[0x20:0x28])
assert allzero(CF[0x30:0x230])
assert allzero(CG[-0x20:-0x18])
assert allzero(SMC[-4:])
print "ok"

print " * checking required versions...",
assert CB and build(CB) >= 1920, "we need CB of at least 1920 (allowing zeropair-updates)"
assert CD and build(CD) == build(CB), "CD must match CB"
assert CD and build(CD) != 8453, "This CD doesn't allow 4532 or 4548 to be booted."
assert CE and build(CE) == 1888, "CE should always be 1888"
assert CF and build(CF) in [4532, 4548], "CF must be either 4532 or 4548 (exploitable)"
assert CG and build(CG) == build(CF), "CG must match CF"
print "ok"

offset_jtag = SMC.find("\xea\x00\xc0\x0f")

if offset_jtag > 0:
	print " * Fixing up the hacked SMC code with the target address"
	SMC = SMC[:offset_jtag+4] + struct.pack(">I", EXPLOIT_BASE) + SMC[offset_jtag+8:]
else:
	print " * SMC does not include the JTAG hack"

open("output/SMC", "wb").write(SMC)

xenon_builds = [1920, 1921]
zephyr_builds = [4558]
falcon_builds = [5766, 5770, 5761]
jasper_builds = [6712, 6723]

print " * this image will be valid *only* for:",
if build(CB) in xenon_builds:
	CONSOLE = "xenon"
if build(CB) in zephyr_builds:
	CONSOLE = "zephyr"
if build(CB) in falcon_builds:
	CONSOLE = "falcon"
if build(CB) in jasper_builds:
	CONSOLE = "jasper"

print CONSOLE

print " * zero-pairing..."

CB = CB[0:0x20] + "\0" * 0x20 + CB[0x40:]
CF = CF[0:0x21c] + "\0" * 4 + CF[0x220:]

print " * constructing new image..."

base_size = 0x8000 + len(CB) + len(CD) + len(CE)
base_size += 16383
base_size &=~16383

patch_offset = base_size

print " * base size: %x" % base_size

Final = ""

c = "zeropair image, version=%02x, CB=%d" % (SCRIPT_VERSION, build(CB))
Header = struct.pack(">HHLLL64s5LLLLLLLL", 0xFF4F, 1888, 0, 0x8000, base_size, c, 0, 0, 0, 0, 0x4000, patch_offset, 0x20712, 0x4000, 0, 0, 0x3000, 0x1000)

Header = (Header + "\0" * 0x1000)[:0x1000]
random = "\0" * 16
SMC = encrypt_SMC(SMC)
CB, CB_key = encrypt_CB(CB, random)
CD, CD_key = encrypt_CD(CD, CB_key, random)
CE = encrypt_CE(CE, CD_key, random)

# CF has an indirection table

update_size = ((len(CF) + len(CG) - 65536) + 16383) / 16384

patch_start = (patch_offset + 65536)/ 16384

table = [update_size] + range(patch_start, patch_start + update_size)

table = ''.join([struct.pack(">H", x) for x in table])

CF = CF[:0x30] + table + CF[0x30+len(table):]

open("output/CF", "wb").write(CF)


CF, CF_key = encrypt_CF(CF, random)
CG = encrypt_CG(CG, CF_key, random)

def calcecc(data):
	assert len(data) == 0x210
	val = 0
	for i in range(0x1066):
		if not i & 31:
			v = ~struct.unpack("<L", data[i/8:i/8+4])[0]
		val ^= v & 1
		v >>= 1
		if val & 1:
			val ^= 0x6954559
		val >>= 1

	val = ~val
	return data[:-4] + struct.pack("<L", (val << 6) & 0xFFFFFFFF)

def addecc(data, block = 0, off_8 = "\x00" * 4):
	global CONSOLE

	res = ""
	while len(data):
		d = (data[:0x200] + "\x00" * 0x200)[:0x200]
		data = data[0x200:]

		if CONSOLE == "jasper":
			d += struct.pack("<BL3B4s4s", 0x00, block / 32, 0xFF, 0x00, 0x00, off_8, "\0\0\0\0")
		else:
			d += struct.pack("<L4B4s4s", block / 32, 0x00, 0xFF, 0x00, 0x00, off_8, "\0\0\0\0")

		d = calcecc(d)
		block += 1
		res += d
	return res

# print " * compiling payload stub"

FLASH_BASE = 0xc8000000 + XELL_BASE_FLASH

# import os
# assert not os.system(CROSS_COMPILE + "gcc -nostdlib payload.S -DFLASH_BASE=0x%08x -DCODE_BASE=0x%08x -o payload.o -Ttext=0" % (FLASH_BASE, CODE_BASE))  >> 8
# assert not os.system(CROSS_COMPILE + "objcopy -O binary payload.o output/payload.bin") >> 8

Exploit = open("output/payload.bin").read()

assert len(Final) < XELL_BASE_FLASH, "Please move XELL_BASE_FLASH"


if len(Xell) <= 256*1024:
	print " * No separate recovery Xell available!"
	Xell *= 2

print " * Flash Layout:"

def add_to_flash(d, w, offset = 0):
	global Final
	print "0x%08x..0x%08x (0x%08x bytes) %s" % (offset + len(Final), offset + len(Final) + len(d) - 1, len(d), w)
	Final += d

def pad_to(loc):
	global Final
	pad = "\xFF" * (loc - len(Final))
	add_to_flash(pad, "Padding")

add_to_flash(Header[:0x200], "Header")
add_to_flash(Exploit[:0x200], "Exploit")
pad_to(0x1000)
add_to_flash(SMC, "SMC")
add_to_flash(Keyvault, "Keyvault")
add_to_flash(CB, "CB %d" % build(CB))
add_to_flash(CD, "CD %d" % build(CD))
add_to_flash(CE, "CE %d" % build(CE))
pad_to(patch_offset)
add_to_flash(CF, "CF %d" % build(CF))
add_to_flash(CG, "CG %d" % build(CG))
pad_to(XELL_BASE_FLASH)

add_to_flash(Xell[0:256*1024], "Xell (backup)")
add_to_flash(Xell[256*1024:], "Xell (main)")

print " * Encoding ECC..."

Final = addecc(Final)

SMC_CONFIG = addecc(SMC_CONFIG)
pad_to(SMC_CONFIG_START)
add_to_flash(SMC_CONFIG, "SMC config")
pad_to(FLASH_END)

exploit_base = EXPLOIT_BASE/0x200*0x210

if exploit_base < len(Final):
	Final = Final[:exploit_base]  + addecc(Final[exploit_base:exploit_base + 0x200], 0, struct.pack(">I", 0x350)) + Final[exploit_base + 0x210:]

open("output/image.bin", "wb").write(Final)

print "------------- Written into output/image.bin"

if exploit_base >= len(Final):
	Final = ""
	add_to_flash(Exploit, "Exploit buffer", EXPLOIT_BASE)
	open("output/image.bin" % EXPLOIT_BASE, "wb").write(addecc(Final, 0x50030000 * 32))
	print "------------- Written into output/image.bin" % EXPLOIT_BASE

print " ! please flash output/image.bin, and setup your JTAG device to do the DMA read from %08x" % (EXPLOIT_BASE)

La modification se situe à la ligne 257 et consiste à continuer la création de l'iamge même en cas d'erreur
  • Retour en haut

Posté 24 septembre 2010 - 22:29

#3
Manethon

Manethon

    Modding addict

  • Technicien LS expert
  • 21 721 messages
  • Sexe:Male
  • Lieu:Valenciennes Nord 59
bon travail
même si effectivement c'est devenu obsolète avec tout les softs qui permettent d'avoir une image freeboot aujourdhui
  • Retour en haut

Posté 13 octobre 2010 - 17:05

#4
hynexiumaz

hynexiumaz

    Nouveau / peu actif

  • Members
  • Pip
  • 3 messages
  • Sexe:Male
Cf src hynexaz

Modifié par hynexiumaz, 16 octobre 2010 - 12:53.

  • Retour en haut

Posté 16 octobre 2010 - 13:02

#5
hynexaz

hynexaz

    Sunriseur

  • Members
  • PipPip
  • 23 messages
  • Sexe:Male

Cf src hynexaz


Voilà ^^ :

Compile le Xell même avec des erreurs (vérifier bien votre NAND) :


# we need to build an image with:

# SMC fitting to system type + hack
# CB = 1920+, zeropaired
# CD for CB
# CE
# CF 4558, zeropaired
# CG
# Xell
# exploit buffer

# where in flash to find the XELL image

# you need to fill in this
secret_1BL = "\xDD\x88\xAD\x0C\x9E\xD6\x69\xE7\xB5\x67\x94\xFB\x68\x56\x3E\xFA"

XELL_BASE_FLASH = 0xc0000
CODE_BASE = 0x1c000000
EXPLOIT_BASE = 0x200
SMC_CONFIG_START = 0xff7e00
SMC_CONFIG_END = 0xffbe00
FLASH_END = 0x1080000

CROSS_COMPILE = "powerpc64-linux-gnu-"

# don't change anything from here.

# so we can do updates properly
SCRIPT_VERSION = 0x00

Keyvault = None
SMC = None
SMC_CONFIG = None
CB = None
CD = None
CE = None
CF = None
CG = None
Xell = ""
Exploit = None
CONSOLE = None

if secret_1BL is None:
        secret_1BL = open("key_1BL.bin", "rb").read()

 # Import Psyco if available
try:
        import psyco
        psyco.full()
except ImportError:
        pass

# first, unpack base input image. We are ignoring any updates here
import hmac, sha, struct, sys
try:
        import Crypto.Cipher.ARC4 as RC4
except ImportError:
        print "Error importing Crypto.Cipher.ARC4 - please install python-crypto!"
        print "You can get it from http://www.dlitz.net/software/pycrypto/"
        sys.exit(-1)

def unpack_base_image(image):
        global SMC, SMC_CONFIG, CB, CD, CE, Keyvault

        if image[0x205] == "\xFF" or image[0x415] == "\xFF" or image[0x200] == "\xFF":
                print "ECC'ed - will unecc."
                res = ""
                for s in range(0, len(image), 528):
                        res += image[s:s+512]
                image = res

        unpackstring = "!HHLLL64s5LLLLLLLL"
        (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)])
        assert not (z0 or z1 or z2 or z3 or z6), "zeros are not zero."

        block_offset = bloffset

        SMC = image[smc_start:smc_start+smc_len]

        if len(image) == 16*1024*1024:
                SMC_CONFIG = image[0xf7c000:0xf80000]

        Keyvault = image[0x4000:0x8000]

        assert smc_len == 0x3000, "never saw an SMC != 0x3000 bytes"

        for block in range(30):
                (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
                block_size += 0xF
                block_size &= ~0xF
                id = ord(block_id[1]) & 0xF

                print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
                data = image[block_offset:block_offset+block_size]

                if id == 2:
                        CB = data
                elif id == 4:
                        CD = data
                elif id == 5:
                        CE = data

                block_offset += block_size

                if id == 5:
                        break

        assert CB and CD and CE

def unpack_update(image):
        global CF, CG

        block_offset = 0
        for block in range(30):
                (block_id, block_build, block_flags, block_entry_point, block_size) = struct.unpack("!2sHLLL", image[block_offset:block_offset+16])
                block_size += 0xF
                block_size &= ~0xF
                id = ord(block_id[1]) & 0xF

                print "Found %dBL (build %d) at %08x" % (id, block_build, block_offset)
                data = image[block_offset:block_offset+block_size]

                if id == 6:
                        CF = data
                elif id == 7:
                        CG = data

                block_offset += block_size

                if id == 7:
                        break

def build(data):
        return struct.unpack(">H", data[2:4])[0]

def decrypt_CB(CB):
        secret = secret_1BL
        key = hmac.new(secret, CB[0x10:0x20], sha).digest()[0:0x10]
        CB = CB[0:0x10] + key + RC4.new(key).decrypt(CB[0x20:])
        return CB

def decrypt_CD(CD, CB, cpukey = None):
# enable this code if you want to extract CD from a flash image and you know the cup key.
# disable this when this is a zero-paired image.
#       assert cpukey or build(CD) < 1920
        secret = CB[0x10:0x20]
        key = hmac.new(secret, CD[0x10:0x20], sha).digest()[0:0x10]
#       if build(CD) >= 1920:
#               key = hmac.new(cpukey, key, sha).digest()[0:0x10]
        CD = CD[0:0x10] + key + RC4.new(key).decrypt(CD[0x20:])
        return CD

def decrypt_CE(CE, CD):
        secret = CD[0x10:0x20]
        key = hmac.new(secret, CE[0x10:0x20], sha).digest()[0:0x10]
        CE = CE[0:0x10] + key + RC4.new(key).decrypt(CE[0x20:])
        return CE

def decrypt_CF(CF):
        secret = secret_1BL
        key = hmac.new(secret, CF[0x20:0x30], sha).digest()[0:0x10]
        CF = CF[0:0x20] + key + RC4.new(key).decrypt(CF[0x30:])
        return CF

def decrypt_CG(CG, CF):
        secret = CF[0x330:0x330+0x10]
        key = hmac.new(secret, CG[0x10:0x20], sha).digest()[0:0x10]
        CG = CG[:0x10] + key + RC4.new(key).decrypt(CG[0x20:])
        return CG

def decrypt_SMC(SMC):
        key = [0x42, 0x75, 0x4e, 0x79]
        res = ""
        for i in range(len(SMC)):
                j = ord(SMC[i])
                mod = j * 0xFB
                res += chr(j ^ (key[i&3] & 0xFF))
                key[(i+1)&3] += mod
                key[(i+2)&3] += mod >> 8
        return res

def encrypt_CB(CB, random):
        secret = secret_1BL
        key = hmac.new(secret, random, sha).digest()[0:0x10]
        CB = CB[0:0x10] + random + RC4.new(key).encrypt(CB[0x20:])
        return CB, key

def encrypt_CD(CD, CB_key, random):
        secret = CB_key
        key = hmac.new(secret, random, sha).digest()[0:0x10]
        CD = CD[0:0x10] + random + RC4.new(key).encrypt(CD[0x20:])
        return CD, key

def encrypt_CE(CE, CD_key, random):
        secret = CD_key
        key = hmac.new(secret, random, sha).digest()[0:0x10]
        CE = CE[0:0x10] + random + RC4.new(key).encrypt(CE[0x20:])
        return CE

def encrypt_CF(CF, random):
        secret = secret_1BL
        key = hmac.new(secret, random, sha).digest()[0:0x10]
        CF_key = CF[0x330:0x330+0x10]
        CF = CF[0:0x20] + random + RC4.new(key).encrypt(CF[0x30:])
        return CF, CF_key

def encrypt_CG(CG, CF_key, random):
        secret = CF_key
        key = hmac.new(secret, random, sha).digest()[0:0x10]
        CG = CG[:0x10] + random + RC4.new(key).encrypt(CG[0x20:])
        return CG

def encrypt_SMC(SMC):
        key = [0x42, 0x75, 0x4e, 0x79]
        res = ""
        for i in range(len(SMC)):
                j = ord(SMC[i]) ^ (key[i&3] & 0xFF)
                mod = j * 0xFB
                res += chr(j)
                key[(i+1)&3] += mod
                key[(i+2)&3] += mod >> 8
        return res

import sys

for i in sys.argv[1:]:

				print " * found flash image, unpacking and decrypting..."
                unpack_base_image(image)
                CB = decrypt_CB(CB)
                CD = decrypt_CD(CD, CB)
                CE = decrypt_CE(CE, CD)
                SMC = decrypt_SMC(SMC)
				print " * found (hopefully) decrypted CB"
                CB = image
				print " * found (hopefully) raw CD"
                CD = image
				print " * found update"
                unpack_update(image)
                CF = decrypt_CF(CF)
                CG = decrypt_CG(CG, CF)
				print " * found decrypted SMC"
                SMC = image
				print " * found encrypted SMC (i hope so)"
                SMC = decrypt_SMC(image)
				print " * found XeLL binary, must be linked to %08x" % CODE_BASE
                assert len(image) <= 256*1024
                image = (image + "\0" * 256*1024)[:256*1024]
                Xell += image
				
print " * we found the following parts:"
print "CB:", CB and build(CB) or "missing"
print "CD:", CD and build(CD) or "missing"
print "CE:", CE and build(CE) or "missing"
print "CF:", CF and build(CF) or "missing"
print "CG:", CG and build(CG) or "missing"

open("output/CB", "wb").write(CB)
open("output/CD", "wb").write(CD)
open("output/CE", "wb").write(CE)
open("output/CF", "wb").write(CF)
open("output/CG", "wb").write(CG)
open("output/SMC", "wb").write(SMC)

def allzero(string):
        for x in string:
                if ord(x):
                        return False
        return True

def allFF(string):
        for x in string:
                if ord(x) != 0xFF:
                        return False
        return True

print " * checking if all files decrypted properly...",
assert allzero(CB[0x270:0x390])
assert allzero(CD[0x20:0x230])
assert allzero(CE[0x20:0x28])
assert allzero(CF[0x30:0x230])
assert allzero(CG[-0x20:-0x18])
assert allzero(SMC[-4:])
print "ok"

print " * checking required versions...",
assert CB and build(CB) >= 1920, "we need CB of at least 1920 (allowing zeropair-updates)"
assert CD and build(CD) == build(CB), "CD must match CB"
assert CD and build(CD) != 8453, "This CD doesn't allow 4532 or 4548 to be booted."
assert CE and build(CE) == 1888, "CE should always be 1888"
assert CF and build(CF) in [4532, 4548], "CF must be either 4532 or 4548 (exploitable)"
assert CG and build(CG) == build(CF), "CG must match CF"
print "ok"

offset_jtag = SMC.find("\xea\x00\xc0\x0f")

if offset_jtag > 0:
        print " * Fixing up the hacked SMC code with the target address"
        SMC = SMC[:offset_jtag+4] + struct.pack(">I", EXPLOIT_BASE) + SMC[offset_jtag+8:]
else:
        print " * SMC does not include the JTAG hack"

open("output/SMC", "wb").write(SMC)

xenon_builds = [1920, 1921]
zephyr_builds = [4558]
falcon_builds = [5766, 5770, 5761]
jasper_builds = [6712, 6723]

print " * this image will be valid *only* for:",
if build(CB) in xenon_builds:
        CONSOLE = "xenon"
if build(CB) in zephyr_builds:
        CONSOLE = "zephyr"
if build(CB) in falcon_builds:
        CONSOLE = "falcon"
if build(CB) in jasper_builds:
        CONSOLE = "jasper"

print CONSOLE

print " * zero-pairing..."

CB = CB[0:0x20] + "\0" * 0x20 + CB[0x40:]
CF = CF[0:0x21c] + "\0" * 4 + CF[0x220:]

print " * constructing new image..."

base_size = 0x8000 + len(CB) + len(CD) + len(CE)
base_size += 16383
base_size &=~16383

patch_offset = base_size

print " * base size: %x" % base_size

Final = ""

c = "zeropair image, version=%02x, CB=%d" % (SCRIPT_VERSION, build(CB))
Header = struct.pack(">HHLLL64s5LLLLLLLL", 0xFF4F, 1888, 0, 0x8000, base_size, c, 0, 0, 0, 0, 0x4000, patch_offset, 0x20712, 0x4000, 0, 0, 0x3000, 0x1000)

Header = (Header + "\0" * 0x1000)[:0x1000]
random = "\0" * 16
SMC = encrypt_SMC(SMC)
CB, CB_key = encrypt_CB(CB, random)
CD, CD_key = encrypt_CD(CD, CB_key, random)
CE = encrypt_CE(CE, CD_key, random)

# CF has an indirection table

update_size = ((len(CF) + len(CG) - 65536) + 16383) / 16384

patch_start = (patch_offset + 65536)/ 16384

table = [update_size] + range(patch_start, patch_start + update_size)

table = ''.join([struct.pack(">H", x) for x in table])

CF = CF[:0x30] + table + CF[0x30+len(table):]

open("output/CF", "wb").write(CF)


CF, CF_key = encrypt_CF(CF, random)
CG = encrypt_CG(CG, CF_key, random)

def calcecc(data):
        assert len(data) == 0x210
        val = 0
        for i in range(0x1066):
                if not i & 31:
                        v = ~struct.unpack("<L", data[i/8:i/8+4])[0]
                val ^= v & 1
                v >>= 1
                if val & 1:
                        val ^= 0x6954559
                val >>= 1

        val = ~val
        return data[:-4] + struct.pack("<L", (val << 6) & 0xFFFFFFFF)

def addecc(data, block = 0, off_8 = "\x00" * 4):
        global CONSOLE

        res = ""
        while len(data):
                d = (data[:0x200] + "\x00" * 0x200)[:0x200]
                data = data[0x200:]

                if CONSOLE == "jasper":
                        d += struct.pack("<BL3B4s4s", 0x00, block / 32, 0xFF, 0x00, 0x00, off_8, "\0\0\0\0")
                else:
                        d += struct.pack("<L4B4s4s", block / 32, 0x00, 0xFF, 0x00, 0x00, off_8, "\0\0\0\0")

                d = calcecc(d)
                block += 1
                res += d
        return res

# print " * compiling payload stub"

FLASH_BASE = 0xc8000000 + XELL_BASE_FLASH

# import os
# assert not os.system(CROSS_COMPILE + "gcc -nostdlib payload.S -DFLASH_BASE=0x%08x -DCODE_BASE=0x%08x -o payload.o -Ttext=0" % (FLASH_BASE, CODE_BASE))  >> 8
# assert not os.system(CROSS_COMPILE + "objcopy -O binary payload.o output/payload.bin") >> 8

Exploit = open("output/payload.bin").read()

assert len(Final) < XELL_BASE_FLASH, "Please move XELL_BASE_FLASH"


if len(Xell) <= 256*1024:
        print " * No separate recovery Xell available!"
        Xell *= 2

print " * Flash Layout:"

def add_to_flash(d, w, offset = 0):
        global Final
        print "0x%08x..0x%08x (0x%08x bytes) %s" % (offset + len(Final), offset + len(Final) + len(d) - 1, len(d), w)
        Final += d

def pad_to(loc):
        global Final
        pad = "\xFF" * (loc - len(Final))
        add_to_flash(pad, "Padding")

add_to_flash(Header[:0x200], "Header")
add_to_flash(Exploit[:0x200], "Exploit")
pad_to(0x1000)
add_to_flash(SMC, "SMC")
add_to_flash(Keyvault, "Keyvault")
add_to_flash(CB, "CB %d" % build(CB))
add_to_flash(CD, "CD %d" % build(CD))
add_to_flash(CE, "CE %d" % build(CE))
pad_to(patch_offset)
add_to_flash(CF, "CF %d" % build(CF))
add_to_flash(CG, "CG %d" % build(CG))
pad_to(XELL_BASE_FLASH)

add_to_flash(Xell[0:256*1024], "Xell (backup)")
add_to_flash(Xell[256*1024:], "Xell (main)")

print " * Encoding ECC..."

Final = addecc(Final)

SMC_CONFIG = addecc(SMC_CONFIG)
pad_to(SMC_CONFIG_START)
add_to_flash(SMC_CONFIG, "SMC config")
pad_to(FLASH_END)

exploit_base = EXPLOIT_BASE/0x200*0x210

if exploit_base < len(Final):
        Final = Final[:exploit_base]  + addecc(Final[exploit_base:exploit_base + 0x200], 0, struct.pack(">I", 0x350)) + Final[exploit_base + 0x210:]

open("output/image.bin", "wb").write(Final)

print "------------- Written into output/image.bin"

if exploit_base >= len(Final):
        Final = ""
        add_to_flash(Exploit, "Exploit buffer", EXPLOIT_BASE)
        open("output/image.bin" % EXPLOIT_BASE, "wb").write(addecc(Final, 0x50030000 * 32))
        print "------------- Written into output/image.bin" % EXPLOIT_BASE

print " ! please flash output/image.bin, and setup your JTAG device to do the DMA read from %08x" % (EXPLOIT_BASE)


  • Retour en haut




0 utilisateur(s) li(sen)t ce sujet

0 invité(s) et 0 utilisateur(s) anonyme(s)