Category Nintendo       Thread starter PSXHAX       Start date Oct 21, 2016 at 12:18 AM       21,909       57            
Status
Not open for further replies.
Today Nintendo of America tweeted news that their upcoming NX console is now officially called the Nintendo Switch which arrives in March 2017 with a preview trailer video below! :closedeyesmile:

To quote from the video's caption: Introducing Nintendo Switch! In addition to providing single and multiplayer thrills at home, the Nintendo Switch system also enables gamers to play the same title wherever, whenever and with whomever they choose.

The mobility of a handheld is now added to the power of a home gaming system to enable unprecedented new video game play styles.

And for Sony PlayStation fans, here's the PS Switch version: :closedeyetongue:
Thanks to @ArthurBishop for sharing the Nintendo Switch video link in the Shoutbox!
Nintendo Switch.jpg
 

Comments

Status
Not open for further replies.

PSXHAX

Staff Member
Moderator
Contributor
Verified
Switch backup loading using Atmosphere-NX LayeredFS

To quote from Jan4V: Switch backup loading is here:

1) Get a title id of any game you have installed from http://switchbrew.org/index.php?title=Title_list/Games (this is your target titleid)
2) Create a directory on SD : sd:/atmosphere/titles/*target_titleid*
3) use hactool to extract the romfs.bin and exefs files from your main nca from the game you want to run instead of your target (its in secure from XCI - the biggest one)
4) put romfs.bin in sd:/atmosphere/titles/*target_titleid*/romfs.bin, exefs files into sd:/atmosphere/titles/*target_titleid*/exefs/
5) Edit titleid in main.npdm (in exefs) to contain target title id (http://carlus.altervista.org/nx/title_id_patcher.html)
6) run a fs_mitm containing CFW release, run your target app (Cannot share the CFW files here, grab them from https://discordapp.com/invite/NbfhykM)

Note that saves don't work for me atm, you should wait for mememenu/similar. Minecraft works, others not tested.


Nintendo Switch EDEV Master Keys via ub3r1337:
Code:
keyblob_00 = 4C6A5CF3273BFA10166C689B8403DF55520817FFF2D84D3D5AD3C513ADFFA9C69B7EDD5B01F01D464F09DADF18D2E22EB94C067E48E83FAE2E09934574EF052C66A3576E2E86083700783EA264E14F5FA0D99A13A6EAC6C634C25308F98E50D55D10E3CCFC6D0F9146A6C64DE074689B4D77D1C7F90CC5609089450DB20E684E0F60BE8945FF612F4B07261360B27CDE
keyblob_01 = EB3B51E088A4A25FC51F062955B6AA64D07DB7BE22100E26DDAEFFC1B1C0A0DFB58FACE75DFBFFB4B2E71B44D65D262DE892FFFFC6E4A7270B586E6EA07E24BD30A279EA605E84CC363F1A25DD0CCFB3825D8135B6532C699CD059821CA876CDBE7188EBA03EFAECF6091D9E9ACA7124273657C4B4FEDDD55E6772660E8045E673E7656C75B0D1B3C0E34865800DE5D0
keyblob_02 = 827DEEFD4D18F2707025F5939704F3F58CD5ECF115F3F5E6EC05C4C8FC685C203DA4380334EE5F7ED8608E7A3B752AAEC4A2306C1BD06802C0B6F8274182F76EA413ABB04ABCC832B4D09A46A180ADE28F2F7B68812DDB6784F1C61836B1155B1C8BA45F24D8E22885E3802990A9632EF938C91F65C973069094CEAA88F4EC18A0E13786F705DF8825C90344029376F6
keyblob_03 = 00940BB4E3EFF38ED531B1AAFB4C186A8969A1AD7673CA1D199BFB6E3E76D039D653E4E24133B40E11EE5D92807E26D1F17622EAB4DC1E860A94EAFE0B0F1561C8FC1EC1BCB5ECD87FAE48EA127AD632C9E9C37B97F6361A5B328E04D93BDA1549702209FE71CED88FBF9B095D1FCAB5A27099D6A82F00D9214BC2AC21958032CAA35FA5C1BE5698F35508E843499235
keyblob_04 = 2C98F4A47B0D15D7B5D7EA6B5A77F62B4417A723BEC578CD95CA0E1E1080C924C2B9CBA398E43E4E13F291381738E7D9123ECE6273166AB2A64A2EBF1D398FEBB8112A99440B3F7B91DECD41986E0F545E725BA087E82733FFDB132315A82959CBEE0F9837D4CD320179E38390E8A8214C545A459B550AC0169902D73413097969DA1D381703EE3D2310CC8832666525
keyblob_mac_key_source = 59C7FB6FBE9BBE87656B15C0537336A5
keyblob_mac_key_00 = B8B41274B015FD263E7E2B3E640C5676
keyblob_mac_key_01 = 0135D78232C8C2DB98662EA74CCFF58F
keyblob_mac_key_02 = 13FC6BA4866D70C1D7DBF6B60E542C94
keyblob_mac_key_03 = 97D152C7ED2D8002C37824CAC6BCAD51
keyblob_mac_key_04 = 5AB660A917958631C5F27388B29D79FE
keyblob_key_source_00 = DF206F594454EFDC7074483B0DED9FD3
keyblob_key_source_01 = 0C25615D684CEB421C2379EA822512AC
keyblob_key_source_02 = 337685EE884AAE0AC28AFD7D63C0433B
keyblob_key_source_03 = 2D1F4880EDECED3E3CF248B5657DF7BE
keyblob_key_source_04 = BB5A01F988AFF5FC6CFF079E133C3980
keyblob_key_00 = 85599025D06070D63A2CE998ACF6F9EA
keyblob_key_01 = C79560F7A78F157121D94B009A69DFB0
keyblob_key_02 = A9CE8DDED92396489A10FC87CA94DF3B
keyblob_key_03 = A6619C69C1AC38FBBD8A9F25EBC8F197
keyblob_key_04 = AE51B3E2CDCB0EE79C334F74AD61EED1
master_key_source = D8A2410AC6C59001C61D6A267C513F3C
master_key_4x_source = 2DC1F48DF35B69334210AC65DA904666
devicekey_seed = 4F025F0EB66D110EDC327D4186C2F478
devicekey_4x_seed = 0C9109DB93930781073CC416227C6C28
master_key_00 = 597D677238F5C73A91B4343F8212AF61
master_key_01 = B82937D1D0E1433019C834B94F628B28
master_key_02 = 6A33B06721A15A36C1A6D795C25009CC
master_key_03 = 1D25A7201668E9B22C717CFF2CDAD54C
master_key_04 = C78B803E6521AF55A9AF128AA63146B7
package1_key_00 = 0F60BE8945FF612F4B07261360B27CDE
package1_key_01 = 73E7656C75B0D1B3C0E34865800DE5D0
package1_key_02 = A0E13786F705DF8825C90344029376F6
package1_key_03 = CAA35FA5C1BE5698F35508E843499235
package1_key_04 = 69DA1D381703EE3D2310CC8832666525
package2_key_source = FB8B6A9C7900C849EFD24D854D30A0C7
package2_key_00 = 5A5FBAE773F8B7964AE1847CFA41AAC8
package2_key_01 = 446EF2C55C88E875765AA7E7E7B44192
package2_key_02 = 275F7D21D36A711E00459A30F6C60631
package2_key_03 = 9F99C811BFE19B730629386F664643D5
package2_key_04 = DC4440B71EF8D98F6C8BD911EEC15376
titlekek_source = 1EDC7B3B60E6B4D878B81715985E629B
titlekek_00 = C467D53F4FDFEB193F61BFDA57F489D0
titlekek_01 = B0EAE34F4E270855B32401651D8AF695
titlekek_02 = 90E4F22B9B9A46E3074DA6D0AE149F8A
titlekek_03 = B25A2BAF87A5B83B4E5ED4C3254B5CDC
titlekek_04 = 7B3C64A2E949F8DC8F10ED8559F3189A
aes_kek_generation_source = 4D870986C45D20722FBA1053DA92E8A9
aes_key_generation_source = 89615EE05C31B6805FE58F3DA24F7AA8
key_area_key_application_source = 7F59971E629F36A13098066F2144C30D
key_area_key_application_00 = 3A7C3E384A8F22FF4B215719B781AD0C
key_area_key_application_01 = CE3B2A68079D99B1448D69DC5E942E48
key_area_key_application_02 = DB0479BA2D5395B27C71BD6AFE5C3EC7
key_area_key_application_03 = E6DA7856D213F0AACB2B34A71A87B6FB
key_area_key_application_04 = 027406FDF59632B88BD053AAF306D39B
key_area_key_ocean_source = 327D36085AD1758DAB4E6FBAA555D882
key_area_key_ocean_00 = C026FC7EEAEA8150C66E5799AC3C57C3
key_area_key_ocean_01 = 74BFB7BE5ED5CF69DD57604E4DFF21C7
key_area_key_ocean_02 = AF7355D87B1550F1295D01FDE52F7769
key_area_key_ocean_03 = 1D69DCF6B8319F8C55B377E0C8D570B0
key_area_key_ocean_04 = EA38E8B7D775B3747F23041F6805D65C
key_area_key_system_source = 8745F1BBA6BE79647D048BA67B5FDA4A
key_area_key_system_00 = 47BB5D75C1FB7FE6F0B2266174DC6356
key_area_key_system_01 = E12E9FA285228D08059AE4DBA9E241B8
key_area_key_system_02 = DC395137598BBFDEABB3B42BB4DA6EB5
key_area_key_system_03 = 027F9403ADD561FEDA12FF2593BE3838
key_area_key_system_04 = 2ACBED4AD66E751F0B23DC39D2397BB8
header_kek_source = 1F12913A4ACBF00D4CDE3AF6D523882A
header_key_source = 5A3ED84FDEC0D82631F7E25D197BF5D01C9B7BFAF628183D71F64D73F150B9D2
header_key = CB9A939F8272544A745D28469DCC381206312706AE62568C5B7EE69F7E010224
Title Switch - GUI Backup Manager (with LayeredFS support!) for Win/Mac/Linux by nastys

So, TX's OS is up.... Main file ("boot.dat") has a small header (0x100) and the body is AES-128-CTR encrypted with: KEY: 47E6BFB05965ABCD00E2EE4DDF540261 CTR: 8E4C7889CBAE4A3D64797DDA84BDB086 Decrypted file has another payload to "deobfuscate" the "OS"...

Code:
https://sx.xecuter.com/sx-api-server.php?u=sign
https://sx.xecuter.com/sx-api-server.php?u=retrieve
json -> {"csr_data":"4c0000000114020000000000c000000000000046b300000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000f40114001f00e8aa209d2506b0449ca771889c2254d93400310000100000ab468a5a1000686f6d6500002000000000000000ab468a5a494c56240000000068006f006d006500000014003a00310000c00200594cd15910006a74696e666f00002400000000000000594cd159594c565b000000006a00740069006e0066006f00000016003600310000100000594cee8e12002e77696e65002200000000000000594cee8e584c20b1000000002e00770069006e006500000014003c003100001000004e4c350b100064726976655f630026000000000000004e4c350b584c39ad00000000640072006900760065005f006300000016004e00310000300000584c4cad100050726f6772616d2046696c6573003200000000000000584c4cad584c4cad00000000500072006f006700720061006d002000460069006c006500730000001c005800310000300000594cf48e1000436865617420456e67696e6520362e3600003800000000000000594cf48e594cf48e0000000043006800650061007400200045006e00670069006e006500200036002e003600000020005800320088280500944a32538000436865617420456e67696e652e65786500003800000000000000944a3253594ced8e0000000043006800650061007400200045006e00670069006e0065002e00650078006500000020000000610000001c000000010000001c0000002d00000000000000600000001100000003000000952b2e111000000000433a5c50726f6772616d2046696c65735c436865617420456e67696e6520362e365c436865617420456e67696e652e6578650000220043003a005c00500072006f006700720061006d002000460069006c00650073005c0043006800650061007400200045006e00670069006e006500200036002e00360000000100000000000000", "redeem_code":"6CJ0FCRY6P3D"}
json server -> {"license":"2cbf36d92a3176d8c77ec8d52a18112e7ca6f25a8bb77a476ef6df5eab76f50d6470e1f18d3dd710f08a0862969d7fb6fea722d1875c400cc09cc82bc44fc8c6fd63a9e0dee1b6b85936ba9717e29d91f7101fcf35112655c1c5160953cc38c4a8d443f1e7f07039232502247ea1ad81be8bdf65c2923457db8799f20a24d40c4387599803c6924676cab9feb04f438c01b61344792d3ce18bc394c706719d8bf9c49a3a6f885c759d18a9b633b6db9dc159ca00a05aa16d467245d1de4f33c3c7f88a432819a6018780fa6f9daf62785c96826bb3de30442426872f4542baa7dc3764189061cfb498b8ce79b6a400ecc95bae4dda1fca2ca84a524c6966e791"}
Download: tx_unpack_data.py
tx_unpack.py (Updated):
Code:
from Crypto.Cipher import AES
from Crypto.Util import Counter
import struct

"""
typedef struct boot_dat_hdr
{
    unsigned char ident[0x10];
    unsigned char sha2_s2[0x20];
    unsigned int s2_dst;
    unsigned int s2_size;
    unsigned int s2_enc;
    unsigned char pad[0x10];
    unsigned int s3_size;
    unsigned char pad2[0x90];
    unsigned char sha2_hdr[0x20];
} boot_dat_hdr_t;
"""

def aes_ctr_dec(buf, key, iv):
    ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16))
    return AES.new(key, AES.MODE_CTR, counter=ctr).encrypt(buf)

f = open("boot.dat", "rb")
b = f.read()
f.close()

boot_ver = struct.unpack("I", b[0x0C:0x10])[0]
s2_base, s2_size = struct.unpack("II", b[0x30:0x38])

if boot_ver == 0x302E3156:
    s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
    s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")
 
    arm64_key = "35D8FFC4AA1BAB9514825EB0658FB493".decode("hex")
    arm64_ctr = "C38EA26FF3CCE98FD8D5ED431D9D5B94".decode("hex")
    arm64_off = 0x53BAB0
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "E2AC05206A701C9AA514D2B2B7C9F395".decode("hex")
    fb_ctr = "46FAB59AF0E469EF116614DEC366D15F".decode("hex")
    fb_off = 0x17BAB0
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    data_key = "030D865B7E458B10AD5706F6E227F4EB".decode("hex")
    data_ctr = "AFFC93692EBD2E3D252339F01E03416B".decode("hex")
    data_off = 0x5F40
    data_size = 0x175B70
    data_base = 0x80000000
elif boot_ver == 0x312E3156:
    s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
    s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")
 
    arm64_key = "51A39F0B46BAE4691AD39A698146E865".decode("hex")
    arm64_ctr = "7A307ED7F1ECC792F0E821ECD6999853".decode("hex")
    arm64_off = 0x53BAE0
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "27BABEE3DCFEF100C744A2388B57E957".decode("hex")
    fb_ctr = "0B88AC25AFAF9B92D81372331AD66E24".decode("hex")
    fb_off = 0x17BAE0
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    data_key = "8D6FEABE0F3936145A474D3F05D33679".decode("hex")
    data_ctr = "2846EFA9DACB065C51C71C154F0E9EA2".decode("hex")
    data_off = 0x5F50
    data_size = 0x175B90
    data_base = 0x80000000
else:
    exit()
 
f = open("stage2_{0:08X}.bin".format(s2_base), "wb")
f.write(aes_ctr_dec(b[0x100:0x100+s2_size], s2_key, s2_ctr))
f.close()

f = open("arm64_{0:08X}.bin".format(arm64_base), "wb")
f.write(aes_ctr_dec(b[arm64_off:arm64_off+arm64_size], arm64_key, arm64_ctr))
f.close()

f = open("fb_{0:08X}.bin".format(fb_base), "wb")
f.write(aes_ctr_dec(b[fb_off:fb_off+fb_size], fb_key, fb_ctr))
f.close()

f = open("data_{0:08X}.bin".format(data_base), "wb")
f.write(aes_ctr_dec(b[data_off:data_off+data_size], data_key, data_ctr))
f.close()
Spoiler
Nintendo Switch PSNES
 

PSXHAX

Staff Member
Moderator
Contributor
Verified
ReiNX WIP Switch custom firmware
Code:
###############################################
# TX SX OS unpacker - by hexkyz and naehrwert #
###############################################

from Crypto.Cipher import AES
from Crypto.Util import Counter
import os
import struct

"""
typedef struct boot_dat_hdr
{
   unsigned char ident[0x10];
   unsigned char sha2_s2[0x20];
   unsigned int s2_dst;
   unsigned int s2_size;
   unsigned int s2_enc;
   unsigned char pad[0x10];
   unsigned int s3_size;
   unsigned char pad2[0x90];
   unsigned char sha2_hdr[0x20];
} boot_dat_hdr_t;
"""

def aes_ctr_dec(buf, key, iv):
   ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16))
   return AES.new(key, AES.MODE_CTR, counter=ctr).encrypt(buf)

f = open("boot.dat", "rb")
b = f.read()
f.close()

boot_ver = struct.unpack("I", b[0x0C:0x10])[0]
s2_base, s2_size = struct.unpack("II", b[0x30:0x38])
s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")

if boot_ver == 0x302E3156:      # TX BOOT V1.0
   arm64_key = "35D8FFC4AA1BAB9514825EB0658FB493".decode("hex")
   arm64_ctr = "C38EA26FF3CCE98FD8D5ED431D9D5B94".decode("hex")
   arm64_off = 0x53BAB0
   arm64_size = 0x36370
   arm64_base = 0x80FFFE00
 
   fb_key = "E2AC05206A701C9AA514D2B2B7C9F395".decode("hex")
   fb_ctr = "46FAB59AF0E469EF116614DEC366D15F".decode("hex")
   fb_off = 0x17BAB0
   fb_size = 0x3C0000
   fb_base = 0xF0000000
 
   payload_key = "030D865B7E458B10AD5706F6E227F4EB".decode("hex")
   payload_ctr = "AFFC93692EBD2E3D252339F01E03416B".decode("hex")
   payload_off = 0x5F40
   payload_size = 0x175B70
   payload_base = 0x80000000
elif boot_ver == 0x312E3156:    # TX BOOT V1.1
   arm64_key = "51A39F0B46BAE4691AD39A698146E865".decode("hex")
   arm64_ctr = "7A307ED7F1ECC792F0E821ECD6999853".decode("hex")
   arm64_off = 0x53BAE0
   arm64_size = 0x36370
   arm64_base = 0x80FFFE00
 
   fb_key = "27BABEE3DCFEF100C744A2388B57E957".decode("hex")
   fb_ctr = "0B88AC25AFAF9B92D81372331AD66E24".decode("hex")
   fb_off = 0x17BAE0
   fb_size = 0x3C0000
   fb_base = 0xF0000000
 
   payload_key = "8D6FEABE0F3936145A474D3F05D33679".decode("hex")
   payload_ctr = "2846EFA9DACB065C51C71C154F0E9EA2".decode("hex")
   payload_off = 0x5F50
   payload_size = 0x175B90
   payload_base = 0x80000000
elif boot_ver == 0x322E3156:    # TX BOOT V1.2
   arm64_key = "22429923901AF74ED6944992C824ACFE".decode("hex")
   arm64_ctr = "590BE04550CC6139921D1C95241F34AC".decode("hex")
   arm64_off = 0x53BAD0
   arm64_size = 0x36370
   arm64_base = 0x80FFFE00
 
   fb_key = "E483A884AB59D5D0014404C2EB698517".decode("hex")
   fb_ctr = "55A60F59F29DD518B4CAA59D0E3D1629".decode("hex")
   fb_off = 0x17BAD0
   fb_size = 0x3C0000
   fb_base = 0xF0000000
 
   payload_key = "AF8F5811D075F5317924E5C1DD70A531".decode("hex")
   payload_ctr = "78219A2BB518BF9E302AFF75CE5862E1".decode("hex")
   payload_off = 0x5F50
   payload_size = 0x175B80
   payload_base = 0x80000000
elif boot_ver == 0x332E3156:    # TX BOOT V1.3
   arm64_key = "0DA0D677361625E81FD6DF236B9450D5".decode("hex")
   arm64_ctr = "B368ECA0F8C078908F6B979613D0E52A".decode("hex")
   arm64_off = 0x53BB00
   arm64_size = 0x36370
   arm64_base = 0x80FFFE00
 
   fb_key = "1E76718F0BAF7D8BB72ECCE4F657DAF8".decode("hex")
   fb_ctr = "4B0D81D9F44B8458F1EA93324C40BCD1".decode("hex")
   fb_off = 0x17BB00
   fb_size = 0x3C0000
   fb_base = 0xF0000000
 
   payload_key = "5B52BF7DED400C967FB0B2E013B55E68".decode("hex")
   payload_ctr = "A1E038CE082F2C26052BE75F111CE3D1".decode("hex")
   payload_off = 0x5F70
   payload_size = 0x175B90
   payload_base = 0x80000000
else:
   exit()

# Create main folder
if not os.path.exists("./sxos/"):
   os.mkdir("./sxos/")
os.chdir("./sxos/")

# Create folder for the initial boot files
if not os.path.exists("./init/"):
   os.mkdir("./init/")
os.chdir("./init/")
 
# Decrypt Stage2 IRAM payload
f = open("stage2_{0:08X}.bin".format(s2_base), "wb")
f.write(aes_ctr_dec(b[0x100:0x100+s2_size], s2_key, s2_ctr))
f.close()

# Decrypt ARM64 memory training blob
f = open("arm64_{0:08X}.bin".format(arm64_base), "wb")
f.write(aes_ctr_dec(b[arm64_off:arm64_off+arm64_size], arm64_key, arm64_ctr))
f.close()

# Decrypt initial framebuffer binary
f = open("fb_{0:08X}.bin".format(fb_base), "wb")
f.write(aes_ctr_dec(b[fb_off:fb_off+fb_size], fb_key, fb_ctr))
f.close()

# Create folder for the obfuscation payloads
if not os.path.exists("../payloads/"):
   os.mkdir("../payloads/")
os.chdir("../payloads/")

# Decrypt first layer's obfuscation payload
f = open("payload_{0:08X}.bin".format(payload_base), "wb")
f.write(aes_ctr_dec(b[payload_off:payload_off+payload_size], payload_key, payload_ctr))
f.close()

if boot_ver == 0x332E3156:      # TX BOOT V1.3
   payload_key = "36FC59BEBA2AABC77D124668E025350E".decode("hex")
   payload_ctr = "E773714BD860B532A356F2C6A07B843E".decode("hex")
   payload_off = 0xC0B920
   payload_size = 0xF5B20
   payload_base = 0x90000000
 
   # Decrypt second layer's obfuscation payload
   f = open("payload_{0:08X}.bin".format(payload_base), "wb")
   f.write(aes_ctr_dec(b[payload_off:payload_off+payload_size], payload_key, payload_ctr))
   f.close()
 
   payload_key = "9334A1F1943C16B2506BB1D9EBF33F93".decode("hex")
   payload_ctr = "7BE8A72FBA0943AE57E93E6F6D6FB46A".decode("hex")
   payload_off = 0xD01440
   payload_size = 0xBC290
   payload_base = 0x98000000
 
   # Decrypt third layer's obfuscation payload
   f = open("payload_{0:08X}.bin".format(payload_base), "wb")
   f.write(aes_ctr_dec(b[payload_off:payload_off+payload_size], payload_key, payload_ctr))
   f.close()
 
   payload_key = "F1AC8CB71383F07FAF34C12879025BEE".decode("hex")
   payload_ctr = "86B9D01C6FFAAF157CE31AE1162A7C48".decode("hex")
   payload_off = 0xDBD6D0
   payload_size = 0x1312E0
   payload_base = 0xA0000000
 
   # Decrypt fourth layer's obfuscation payload
   f = open("payload_{0:08X}.bin".format(payload_base), "wb")
   f.write(aes_ctr_dec(b[payload_off:payload_off+payload_size], payload_key, payload_ctr))
   f.close()
 
   # Create folder for the bootloader
   if not os.path.exists("../bootloader/"):
       os.mkdir("../bootloader/")
   os.chdir("../bootloader/")
 
   bootloader_key = "C439958095F3AC5CA361E46481A778B4".decode("hex")
   bootloader_ctr = "07E32283C45EC5215DEFDBB199AD2F5B".decode("hex")
   bootloader_off = 0x571E70
   bootloader_size = 0x20FC0
   bootloader_base = 0x88000000
   assets_key = "5E5C65FA5C93C43BD8BA5B7B93A59687".decode("hex")
   assets_ctr = "45E156D62914D27529AA7A8B7EAC8A31".decode("hex")
   assets_off = 0x592E30
   assets_size = 0x4C0400
   assets_base = 0x88020FC0
 
   # Decrypt SX OS bootloader's code and assets
   f = open("bootloader_{0:08X}.bin".format(bootloader_base), "wb")
   f.write(aes_ctr_dec(b[bootloader_off:bootloader_off+bootloader_size], bootloader_key, bootloader_ctr))
   f.write(aes_ctr_dec(b[assets_off:assets_off+assets_size], assets_key, assets_ctr))
   f.close()
 
   os.chdir("../payloads/")
 
   # Open final firmware binary (encrypted)
   f = open("payload_A0000000.bin", "rb")
   b = f.read()
   f.close()

   key = "264AAE11C24A65AB99E021788BFE6E66".decode("hex")
   ctr = "71C68F4C9CBB2203AC267B917BAC76B0".decode("hex")
   off = 0
   size = 0x1312E0
 
   # Decrypt final firmware binary
   f = open("payload_A0000000_dec.bin", "wb")
   f.write(aes_ctr_dec(b[off:off+size], key, ctr))
   f.close()

   # Open final firmware binary (decrypted)
   f = open("payload_A0000000_dec.bin", "rb")
   b = f.read()
   f.close()

   # Create folder for the patcher binaries
   if not os.path.exists("../patcher/"):
       os.mkdir("../patcher/")
   os.chdir("../patcher/")
 
   patcher_size = struct.unpack("I", b[0x00:0x04])[0]
   patcher_off = struct.unpack("I", b[0x04:0x08])[0]
   patcher_base = struct.unpack("I", b[0x08:0x0C])[0]
   patcher_crc = struct.unpack("I", b[0x0C:0x10])[0]
   patcher_hash = struct.unpack("8I", b[0x10:0x30])
 
   # Parse and store the PK11 patcher
   f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
   f.write(b[patcher_off:patcher_off+patcher_size])
   f.close()
 
   patcher_size = struct.unpack("I", b[0x30:0x34])[0]
   patcher_off = struct.unpack("I", b[0x34:0x38])[0]
   patcher_base = struct.unpack("I", b[0x38:0x3C])[0]
   patcher_crc = struct.unpack("I", b[0x3C:0x40])[0]
   patcher_hash = struct.unpack("8I", b[0x40:0x60])

   # Parse and store the KIP1/INI1 patcher
   f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
   f.write(b[patcher_off:patcher_off+patcher_size])
   f.close()
 
   patcher_size = struct.unpack("I", b[0x60:0x64])[0]
   patcher_off = struct.unpack("I", b[0x64:0x68])[0]
   patcher_base = struct.unpack("I", b[0x68:0x6C])[0]
   patcher_crc = struct.unpack("I", b[0x6C:0x70])[0]
   patcher_hash = struct.unpack("8I", b[0x70:0x90])
 
   # Parse and store the kernel patcher
   f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
   f.write(b[patcher_off:patcher_off+patcher_size])
   f.close()
 
   # Create folder for the actual firmware binaries
   if not os.path.exists("../firmware/"):
       os.mkdir("../firmware/")
   os.chdir("../firmware/")
 
   kip_size = struct.unpack("I", b[0x90:0x94])[0]
   kip_off = struct.unpack("I", b[0x94:0x98])[0]
   kip_base = struct.unpack("I", b[0x98:0x9C])[0]
   kip_crc = struct.unpack("I", b[0x9C:0xA0])[0]
   kip_hash = struct.unpack("8I", b[0xA0:0xC0])
 
   # Parse and store the Loader KIP1
   f = open("kip_{0:08X}.bin".format(kip_base), "wb")
   f.write(b[kip_off:kip_off+kip_size])
   f.close()
 
   kip_size = struct.unpack("I", b[0xC0:0xC4])[0]
   kip_off = struct.unpack("I", b[0xC4:0xC8])[0]
   kip_base = struct.unpack("I", b[0xC8:0xCC])[0]
   kip_crc = struct.unpack("I", b[0xCC:0xD0])[0]
   kip_hash = struct.unpack("8I", b[0xD0:0xF0])
 
   # Parse and store the sm KIP1
   f = open("kip_{0:08X}.bin".format(kip_base), "wb")
   f.write(b[kip_off:kip_off+kip_size])
   f.close()
 
   kip_size = struct.unpack("I", b[0xF0:0xF4])[0]
   kip_off = struct.unpack("I", b[0xF4:0xF8])[0]
   kip_base = struct.unpack("I", b[0xF8:0xFC])[0]
   kip_crc = struct.unpack("I", b[0xFC:0x100])[0]
   kip_hash = struct.unpack("8I", b[0x100:0x120])
 
   # Parse and store the fs.mitm KIP1
   f = open("kip_{0:08X}.bin".format(kip_base), "wb")
   f.write(b[kip_off:kip_off+kip_size])
   f.close()
Code:
###############################################
# TX SX Pro Custom Payload Packer - by CTCaer #
###############################################

import struct
import hashlib
from os import unlink

"""
typedef struct boot_dat_hdr
{
    unsigned char ident[0x10];
    unsigned char sha2_s2[0x20];
    unsigned int s2_dst;
    unsigned int s2_size;
    unsigned int s2_enc;
    unsigned char pad[0x10];
    unsigned int s3_size;
    unsigned char pad2[0x90];
    unsigned char sha2_hdr[0x20];
} boot_dat_hdr_t;
"""

def sha256(data):
    sha256 = hashlib.new('sha256')
    sha256.update(data)
    return sha256.digest()
 
boot_fn = 'boot.dat'
# Custom payload filename.
stage2_fn = 'hekate_ctcaer_3.2.bin'

boot = open(boot_fn, 'wb')

with open(stage2_fn, 'rb') as fh:
    stage2 = bytearray(fh.read())
    stage2 = bytes(stage2)

# Re-create the header.
header = b''

# Magic ID.
header += b'\x43\x54\x43\x61\x65\x72\x20\x42\x4F\x4F\x54\x00'

# Version 2.5.
header += b'\x56\x32\x2E\x35'

# Set sha256 hash of stage2 payload.
header += sha256(stage2)

# Set stage2 payload destination to 0x40010000.
header += b'\x00\x00\x01\x40'

# Stage2 payload size.
header += struct.pack('I', len(stage2))

# Disable Stage2 encryption.
header += struct.pack('I', 0)

# Add padding. Stage3 size is 0.
header += b'\x00' * 0xA4

# Add header's sha256 hash.
sha256 = hashlib.new('sha256')
sha256.update(header)
header += sha256.digest()

# Write header and the plaintext custom payload.
boot.write(header)
boot.write(stage2)

boot.close()
Code:
###############################################
# TX SX OS unpacker - by hexkyz and naehrwert #
###############################################

from Crypto.Cipher import AES
from Crypto.Util import Counter
import os
import struct

"""
typedef struct boot_dat_hdr
{
    unsigned char ident[0x10];
    unsigned char sha2_s2[0x20];
    unsigned int s2_dst;
    unsigned int s2_size;
    unsigned int s2_enc;
    unsigned char pad[0x10];
    unsigned int s3_size;
    unsigned char pad2[0x90];
    unsigned char sha2_hdr[0x20];
} boot_dat_hdr_t;
"""

def aes_ctr_dec(buf, key, iv):
    ctr = Counter.new(128, initial_value=long(iv.encode('hex'), 16))
    return AES.new(key, AES.MODE_CTR, counter=ctr).encrypt(buf)

f = open("boot.dat", "rb")
b = f.read()
f.close()

boot_ver = struct.unpack("I", b[0x0C:0x10])[0]
s2_base, s2_size = struct.unpack("II", b[0x30:0x38])
s2_key = "47E6BFB05965ABCD00E2EE4DDF540261".decode("hex")
s2_ctr = "8E4C7889CBAE4A3D64797DDA84BDB086".decode("hex")

if boot_ver == 0x302E3156:      # TX BOOT V1.0
    arm64_key = "35D8FFC4AA1BAB9514825EB0658FB493".decode("hex")
    arm64_ctr = "C38EA26FF3CCE98FD8D5ED431D9D5B94".decode("hex")
    arm64_off = 0x53BAB0
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "E2AC05206A701C9AA514D2B2B7C9F395".decode("hex")
    fb_ctr = "46FAB59AF0E469EF116614DEC366D15F".decode("hex")
    fb_off = 0x17BAB0
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    payload80_key = "030D865B7E458B10AD5706F6E227F4EB".decode("hex")
    payload80_ctr = "AFFC93692EBD2E3D252339F01E03416B".decode("hex")
    payload80_off = 0x5F40
    payload80_size = 0x175B70
    payload80_base = 0x80000000
elif boot_ver == 0x312E3156:    # TX BOOT V1.1
    arm64_key = "51A39F0B46BAE4691AD39A698146E865".decode("hex")
    arm64_ctr = "7A307ED7F1ECC792F0E821ECD6999853".decode("hex")
    arm64_off = 0x53BAE0
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "27BABEE3DCFEF100C744A2388B57E957".decode("hex")
    fb_ctr = "0B88AC25AFAF9B92D81372331AD66E24".decode("hex")
    fb_off = 0x17BAE0
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    payload80_key = "8D6FEABE0F3936145A474D3F05D33679".decode("hex")
    payload80_ctr = "2846EFA9DACB065C51C71C154F0E9EA2".decode("hex")
    payload80_off = 0x5F50
    payload80_size = 0x175B90
    payload80_base = 0x80000000
elif boot_ver == 0x322E3156:    # TX BOOT V1.2
    arm64_key = "22429923901AF74ED6944992C824ACFE".decode("hex")
    arm64_ctr = "590BE04550CC6139921D1C95241F34AC".decode("hex")
    arm64_off = 0x53BAD0
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "E483A884AB59D5D0014404C2EB698517".decode("hex")
    fb_ctr = "55A60F59F29DD518B4CAA59D0E3D1629".decode("hex")
    fb_off = 0x17BAD0
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    payload80_key = "AF8F5811D075F5317924E5C1DD70A531".decode("hex")
    payload80_ctr = "78219A2BB518BF9E302AFF75CE5862E1".decode("hex")
    payload80_off = 0x5F50
    payload80_size = 0x175B80
    payload80_base = 0x80000000
elif boot_ver == 0x332E3156:    # TX BOOT V1.3
    arm64_key = "0DA0D677361625E81FD6DF236B9450D5".decode("hex")
    arm64_ctr = "B368ECA0F8C078908F6B979613D0E52A".decode("hex")
    arm64_off = 0x53BB00
    arm64_size = 0x36370
    arm64_base = 0x80FFFE00
 
    fb_key = "1E76718F0BAF7D8BB72ECCE4F657DAF8".decode("hex")
    fb_ctr = "4B0D81D9F44B8458F1EA93324C40BCD1".decode("hex")
    fb_off = 0x17BB00
    fb_size = 0x3C0000
    fb_base = 0xF0000000
 
    payload80_key = "5B52BF7DED400C967FB0B2E013B55E68".decode("hex")
    payload80_ctr = "A1E038CE082F2C26052BE75F111CE3D1".decode("hex")
    payload80_off = 0x5F70
    payload80_size = 0x175B90
    payload80_base = 0x80000000
else:
    exit()

# Create main folder
if not os.path.exists("./sxos/"):
    os.mkdir("./sxos/")
os.chdir("./sxos/")

# Create folder for the initial boot files
if not os.path.exists("./init/"):
    os.mkdir("./init/")
os.chdir("./init/")
 
# Decrypt Stage2 IRAM payload
f = open("stage2_{0:08X}.bin".format(s2_base), "wb")
f.write(aes_ctr_dec(b[0x100:0x100+s2_size], s2_key, s2_ctr))
f.close()

# Decrypt ARM64 memory training blob
f = open("arm64_{0:08X}.bin".format(arm64_base), "wb")
f.write(aes_ctr_dec(b[arm64_off:arm64_off+arm64_size], arm64_key, arm64_ctr))
f.close()

# Decrypt initial framebuffer binary
f = open("fb_{0:08X}.bin".format(fb_base), "wb")
f.write(aes_ctr_dec(b[fb_off:fb_off+fb_size], fb_key, fb_ctr))
f.close()

# Create folder for the obfuscation payloads
if not os.path.exists("../payloads/"):
    os.mkdir("../payloads/")
os.chdir("../payloads/")

# Decrypt first layer's obfuscation payload
f = open("payload_{0:08X}.bin".format(payload80_base), "wb")
f.write(aes_ctr_dec(b[payload80_off:payload80_off+payload80_size], payload80_key, payload80_ctr))
f.close()

if boot_ver == 0x302E3156:      # TX BOOT V1.0
    payload90_key = "7F5ADF4D874E452E03D49127A42F1E76".decode("hex")
    payload90_ctr = "94251152C910E701397BE2DB4F1C6CA8".decode("hex")
    payload90_off = 0xC0B8D0
    payload90_size = 0xF5B20
    payload90_base = 0x90000000
 
    payload98_key = "7D3903433AFF4454E7C4494CF78B2C27".decode("hex")
    payload98_ctr = "47A6B1EE20DDB7CDBB4A486C42638D54".decode("hex")
    payload98_off = 0xD013F0
    payload98_size = 0xBC290
    payload98_base = 0x98000000
 
    payloadA0_key = "470248AF0FD18221C7920635705980F6".decode("hex")
    payloadA0_ctr = "4CC30D28126D38749F755A506B21EE15".decode("hex")
    payloadA0_off = 0xDBD680
    payloadA0_size = 0x1154D0
    payloadA0_base = 0xA0000000
 
    bootloader_key = "C9B5A5746CF37F46417DD6842B48361B".decode("hex")
    bootloader_ctr = "40FBE01C573B0C286BC7956455475788".decode("hex")
    bootloader_off = 0x571E20
    bootloader_size = 0x20FC0
    bootloader_base = 0x88000000
 
    assets_key = "677EC85A86F798AFD6B8BC046B65F0F5".decode("hex")
    assets_ctr = "31C8DBE98486D59CD69DA7C470A69A0B".decode("hex")
    assets_off = 0x592DE0
    assets_size = 0x4C0400
    assets_base = 0x88020FC0
 
    fw_key = "31756DA6C12CA907C050861D60A5E0A5".decode("hex")
    fw_ctr = "DA0F8243F83358F15F431FF6F674C099".decode("hex")
    fw_off = 0
    fw_size = 0x1154D0
elif boot_ver == 0x322E3156:      # TX BOOT V1.2
    payload90_key = "3DE87D8E1A24E06B2D50F6100AA09B4C".decode("hex")
    payload90_ctr = "94162463FF6B54FE9B6683F72CE79760".decode("hex")
    payload90_off = 0xC0B8F0
    payload90_size = 0xF5B20
    payload90_base = 0x90000000
 
    payload98_key = "5EBBF535CA7C7EE6C97A770CB1AA7E37".decode("hex")
    payload98_ctr = "BF9BA9CB3E2328ACD4676CE106081B3D".decode("hex")
    payload98_off = 0xD01410
    payload98_size = 0xBC290
    payload98_base = 0x98000000

    payloadA0_key = "9EBBBD4F4A5CC82B705431DFF5AA260A".decode("hex")
    payloadA0_ctr = "8A7923E459F12ED38CD533EFF69727D9".decode("hex")
    payloadA0_off = 0xDBD6A0
    payloadA0_size = 0x120530
    payloadA0_base = 0xA0000000
 
    bootloader_key = "F1A4E1EE2F279BB55A0C16D0373961BC".decode("hex")
    bootloader_ctr = "BC40537AB5F23088B9F1DD51FB0BB1D7".decode("hex")
    bootloader_off = 0x571E40
    bootloader_size = 0x20FC0
    bootloader_base = 0x88000000
 
    assets_key = "8D0CC65A2DE679BDB3D73C3F11734E0E".decode("hex")
    assets_ctr = "6CA93EAEEC84E218918F68DBFF8C95E9".decode("hex")
    assets_off = 0x592E00
    assets_size = 0x4C0400
    assets_base = 0x88020FC0
 
    fw_key = "84BB031A9E20D2BEAA10CE85BD4157BF".decode("hex")
    fw_ctr = "DC986E7B0FF4DD433F21D655B082BF43".decode("hex")
    fw_off = 0
    fw_size = 0x120530
elif boot_ver == 0x332E3156:      # TX BOOT V1.3
    payload90_key = "36FC59BEBA2AABC77D124668E025350E".decode("hex")
    payload90_ctr = "E773714BD860B532A356F2C6A07B843E".decode("hex")
    payload90_off = 0xC0B920
    payload90_size = 0xF5B20
    payload90_base = 0x90000000
 
    payload98_key = "9334A1F1943C16B2506BB1D9EBF33F93".decode("hex")
    payload98_ctr = "7BE8A72FBA0943AE57E93E6F6D6FB46A".decode("hex")
    payload98_off = 0xD01440
    payload98_size = 0xBC290
    payload98_base = 0x98000000
 
    payloadA0_key = "F1AC8CB71383F07FAF34C12879025BEE".decode("hex")
    payloadA0_ctr = "86B9D01C6FFAAF157CE31AE1162A7C48".decode("hex")
    payloadA0_off = 0xDBD6D0
    payloadA0_size = 0x1312E0
    payloadA0_base = 0xA0000000
 
    bootloader_key = "C439958095F3AC5CA361E46481A778B4".decode("hex")
    bootloader_ctr = "07E32283C45EC5215DEFDBB199AD2F5B".decode("hex")
    bootloader_off = 0x571E70
    bootloader_size = 0x20FC0
    bootloader_base = 0x88000000
 
    assets_key = "5E5C65FA5C93C43BD8BA5B7B93A59687".decode("hex")
    assets_ctr = "45E156D62914D27529AA7A8B7EAC8A31".decode("hex")
    assets_off = 0x592E30
    assets_size = 0x4C0400
    assets_base = 0x88020FC0
 
    fw_key = "264AAE11C24A65AB99E021788BFE6E66".decode("hex")
    fw_ctr = "71C68F4C9CBB2203AC267B917BAC76B0".decode("hex")
    fw_off = 0
    fw_size = 0x1312E0
else:
    exit()
 
# Decrypt second layer's obfuscation payload
f = open("payload_{0:08X}.bin".format(payload90_base), "wb")
f.write(aes_ctr_dec(b[payload90_off:payload90_off+payload90_size], payload90_key, payload90_ctr))
f.close()
 
# Decrypt third layer's obfuscation payload
f = open("payload_{0:08X}.bin".format(payload98_base), "wb")
f.write(aes_ctr_dec(b[payload98_off:payload98_off+payload98_size], payload98_key, payload98_ctr))
f.close()
 
# Decrypt fourth layer's obfuscation payload
f = open("payload_{0:08X}.bin".format(payloadA0_base), "wb")
f.write(aes_ctr_dec(b[payloadA0_off:payloadA0_off+payloadA0_size], payloadA0_key, payloadA0_ctr))
f.close()
 
# Create folder for the bootloader
if not os.path.exists("../bootloader/"):
    os.mkdir("../bootloader/")
os.chdir("../bootloader/")
 
# Decrypt SX OS bootloader's code and assets
f = open("bootloader_{0:08X}.bin".format(bootloader_base), "wb")
f.write(aes_ctr_dec(b[bootloader_off:bootloader_off+bootloader_size], bootloader_key, bootloader_ctr))
f.write(aes_ctr_dec(b[assets_off:assets_off+assets_size], assets_key, assets_ctr))
f.close()

os.chdir("../payloads/")

# Open final firmware binary (encrypted)
f = open("payload_A0000000.bin", "rb")
b = f.read()
f.close()

# Decrypt final firmware binary
f = open("payload_A0000000_dec.bin", "wb")
f.write(aes_ctr_dec(b[fw_off:fw_off+fw_size], fw_key, fw_ctr))
f.close()

# Open final firmware binary (decrypted)
f = open("payload_A0000000_dec.bin", "rb")
b = f.read()
f.close()

# Create folder for the patcher binaries
if not os.path.exists("../patcher/"):
    os.mkdir("../patcher/")
os.chdir("../patcher/")

if (boot_ver == 0x302E3156) or (boot_ver == 0x312E3156):      # Old layout
    patcher_size = struct.unpack("I", b[0x10:0x14])[0]
    patcher_off = struct.unpack("I", b[0x14:0x18])[0]
    patcher_base = struct.unpack("I", b[0x18:0x1C])[0]
    patcher_crc = struct.unpack("I", b[0x1C:0x20])[0]
    patcher_hash = struct.unpack("8I", b[0x50:0x70])
   
    # Parse and store the PK11 patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    patcher_size = struct.unpack("I", b[0x20:0x24])[0]
    patcher_off = struct.unpack("I", b[0x24:0x28])[0]
    patcher_base = struct.unpack("I", b[0x28:0x2C])[0]
    patcher_crc = struct.unpack("I", b[0x2C:0x30])[0]
    patcher_hash = struct.unpack("8I", b[0x70:0x90])

    # Parse and store the KIP1/INI1 patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    patcher_size = struct.unpack("I", b[0x30:0x34])[0]
    patcher_off = struct.unpack("I", b[0x34:0x38])[0]
    patcher_base = struct.unpack("I", b[0x38:0x3C])[0]
    patcher_crc = struct.unpack("I", b[0x3C:0x40])[0]
    patcher_hash = struct.unpack("8I", b[0x90:0xB0])
   
    # Parse and store the kernel patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    # Create folder for the actual firmware binaries
    if not os.path.exists("../firmware/"):
        os.mkdir("../firmware/")
    os.chdir("../firmware/")
   
    kip_size = struct.unpack("I", b[0x40:0x44])[0]
    kip_off = struct.unpack("I", b[0x44:0x48])[0]
    kip_base = struct.unpack("I", b[0x48:0x4C])[0]
    kip_crc = struct.unpack("I", b[0x4C:0x50])[0]
    kip_hash = struct.unpack("8I", b[0xB0:0xD0])

    # Parse and store the Loader KIP1
    f = open("kip_{0:08X}.bin".format(kip_base), "wb")
    f.write(b[kip_off:kip_off+kip_size])
    f.close()
else:                                                       # New layout
    patcher_size = struct.unpack("I", b[0x00:0x04])[0]
    patcher_off = struct.unpack("I", b[0x04:0x08])[0]
    patcher_base = struct.unpack("I", b[0x08:0x0C])[0]
    patcher_crc = struct.unpack("I", b[0x0C:0x10])[0]
    patcher_hash = struct.unpack("8I", b[0x10:0x30])
   
    # Parse and store the PK11 patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    patcher_size = struct.unpack("I", b[0x30:0x34])[0]
    patcher_off = struct.unpack("I", b[0x34:0x38])[0]
    patcher_base = struct.unpack("I", b[0x38:0x3C])[0]
    patcher_crc = struct.unpack("I", b[0x3C:0x40])[0]
    patcher_hash = struct.unpack("8I", b[0x40:0x60])

    # Parse and store the KIP1/INI1 patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    patcher_size = struct.unpack("I", b[0x60:0x64])[0]
    patcher_off = struct.unpack("I", b[0x64:0x68])[0]
    patcher_base = struct.unpack("I", b[0x68:0x6C])[0]
    patcher_crc = struct.unpack("I", b[0x6C:0x70])[0]
    patcher_hash = struct.unpack("8I", b[0x70:0x90])
   
    # Parse and store the kernel patcher
    f = open("patcher_{0:08X}.bin".format(patcher_base), "wb")
    f.write(b[patcher_off:patcher_off+patcher_size])
    f.close()

    # Create folder for the actual firmware binaries
    if not os.path.exists("../firmware/"):
        os.mkdir("../firmware/")
    os.chdir("../firmware/")
   
    kip_size = struct.unpack("I", b[0x90:0x94])[0]
    kip_off = struct.unpack("I", b[0x94:0x98])[0]
    kip_base = struct.unpack("I", b[0x98:0x9C])[0]
    kip_crc = struct.unpack("I", b[0x9C:0xA0])[0]
    kip_hash = struct.unpack("8I", b[0xA0:0xC0])

    # Parse and store the Loader KIP1
    f = open("kip_{0:08X}.bin".format(kip_base), "wb")
    f.write(b[kip_off:kip_off+kip_size])
    f.close()
 
    kip_size = struct.unpack("I", b[0xC0:0xC4])[0]
    kip_off = struct.unpack("I", b[0xC4:0xC8])[0]
    kip_base = struct.unpack("I", b[0xC8:0xCC])[0]
    kip_crc = struct.unpack("I", b[0xCC:0xD0])[0]
    kip_hash = struct.unpack("8I", b[0xD0:0xF0])

    # Parse and store the sm KIP1
    f = open("kip_{0:08X}.bin".format(kip_base), "wb")
    f.write(b[kip_off:kip_off+kip_size])
    f.close()
   
    # New KIP file in V1.3
    if boot_ver == 0x332E3156:
        kip_size = struct.unpack("I", b[0xF0:0xF4])[0]
        kip_off = struct.unpack("I", b[0xF4:0xF8])[0]
        kip_base = struct.unpack("I", b[0xF8:0xFC])[0]
        kip_crc = struct.unpack("I", b[0xFC:0x100])[0]
        kip_hash = struct.unpack("8I", b[0x100:0x120])

        # Parse and store the fs.mitm KIP1
        f = open("kip_{0:08X}.bin".format(kip_base), "wb")
        f.write(b[kip_off:kip_off+kip_size])
        f.close()
Code:
# The following is adapted from https://github.com/reswitched/loaders/blob/master/nxo64.py
#
# ===========================================================================================
#
# Copyright 2017 Reswitched Team
#
# Permission to use, copy, modify, and/or distribute this software for any purpose with or
# without fee is hereby granted, provided that the above copyright notice and this permission
# notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
# THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
# OR PERFORMANCE OF THIS SOFTWARE.

import os
import struct
import lz4.block

uncompress = lz4.block.decompress

# Skip the non-standard size field
kip_skip = 0
 
def kip1_blz_decompress(compressed):
    compressed_size, init_index, uncompressed_addl_size = struct.unpack('<III', compressed[-0xC:])
    decompressed = compressed[:] + '\x00' * uncompressed_addl_size
    decompressed_size = len(decompressed)
    if len(compressed) != compressed_size:
        assert len(compressed) > compressed_size
        compressed = compressed[len(compressed) - compressed_size:]
    if not (compressed_size + uncompressed_addl_size):
        return ''
    compressed = map(ord, compressed)
    decompressed = map(ord, decompressed)
    index = compressed_size - init_index
    outindex = decompressed_size
    while outindex > 0:
        index -= 1
        control = compressed[index]
        for i in xrange(8):
            if control & 0x80:
                if index < 2:
                    raise ValueError('Compression out of bounds!')
                index -= 2
                segmentoffset = compressed[index] | (compressed[index+1] << 8)
                segmentsize = ((segmentoffset >> 12) & 0xF) + 3
                segmentoffset &= 0x0FFF
                segmentoffset += 2
                if outindex < segmentsize:
                    raise ValueError('Compression out of bounds!')
                for j in xrange(segmentsize):
                    if outindex + segmentoffset >= decompressed_size:
                        raise ValueError('Compression out of bounds!')
                    data = decompressed[outindex+segmentoffset]
                    outindex -= 1
                    decompressed[outindex] = data
            else:
                if outindex < 1:
                    raise ValueError('Compression out of bounds!')
                outindex -= 1
                index -= 1
                decompressed[outindex] = compressed[index]
            control <<= 1
            control &= 0xFF
            if not outindex:
                break
    return ''.join(map(chr, decompressed))
 
class BinFile(object):
    def __init__(self, li):
        self._f = li
 
    def read(self, arg):
        if isinstance(arg, str):
            fmt = '<' + arg
            size = struct.calcsize(fmt)
            raw = self._f.read(size)
            out = struct.unpack(fmt, raw)
            if len(out) == 1:
                return out[0]
            return out
        elif arg is None:
            return self._f.read()
        else:
            out = self._f.read(arg)
            return out
 
    def read_from(self, arg, offset):
        old = self.tell()
        try:
            self.seek(offset)
            out = self.read(arg)
        finally:
            self.seek(old)
        return out
 
    def seek(self, off):
        self._f.seek(off)
 
    def close(self):
        self._f.close()
 
    def tell(self):
        return self._f.tell()
   
def decompress_kip(fileobj):
    f = BinFile(fileobj)

    if f.read_from('4s', 0 + kip_skip) != 'KIP1':
        raise NxoException('Invalid KIP magic')
 
    tloc, tsize, tfilesize = f.read_from('III', 0x20 + kip_skip)
    rloc, rsize, rfilesize = f.read_from('III', 0x30 + kip_skip)
    dloc, dsize, dfilesize = f.read_from('III', 0x40 + kip_skip)
 
    toff = 0x100
    roff = toff + tfilesize
    doff = roff + rfilesize

    bsssize = f.read_from('I', 0x18 + kip_skip)
 
    text = kip1_blz_decompress(str(f.read_from(tfilesize, toff + kip_skip)))
    ro   = kip1_blz_decompress(str(f.read_from(rfilesize, roff + kip_skip)))
    data = kip1_blz_decompress(str(f.read_from(dfilesize, doff + kip_skip)))

    full = text
    if rloc >= len(full):
        full += '\0' * (rloc - len(full))
    else:
        full = full[:rloc]
    full += ro
    if dloc >= len(full):
        full += '\0' * (dloc - len(full))
    else:
        full = full[:dloc]
    full += data
 
    return full
 
def decompress_nso(fileobj):
    f = BinFile(fileobj)

    if f.read_from('4s', 0) != 'NSO0':
        raise NxoException('Invalid NSO magic')

    toff, tloc, tsize = f.read_from('III', 0x10)
    roff, rloc, rsize = f.read_from('III', 0x20)
    doff, dloc, dsize = f.read_from('III', 0x30)

    tfilesize, rfilesize, dfilesize = f.read_from('III', 0x60)
    bsssize = f.read_from('I', 0x3C)

    text = uncompress(f.read_from(tfilesize, toff), uncompressed_size=tsize)
    ro   = uncompress(f.read_from(rfilesize, roff), uncompressed_size=rsize)
    data = uncompress(f.read_from(dfilesize, doff), uncompressed_size=dsize)

    full = text
    if rloc >= len(full):
        full += '\0' * (rloc - len(full))
    else:
        full = full[:rloc]
    full += ro
    if dloc >= len(full):
        full += '\0' * (dloc - len(full))
    else:
        full = full[:dloc]
    full += data
 
    return full

# ===========================================================================================

f = open("boot.dat", "rb")
b = f.read()
f.close()

# Get the version from boot.dat
boot_ver = struct.unpack("I", b[0x0C:0x10])[0]

if boot_ver == 0x302E3156:      # TX BOOT V1.0
    kip_skip = 0x8
    tx_nso_off = 0x30DD8
    tx_nso_size = 0xF0F3C
    hbl_nso_off = 0x1222A0
    hbl_nso_size = 0x8F90
elif boot_ver == 0x322E3156:    # TX BOOT V1.2
    kip_skip = 0x8
    tx_nso_off = 0x31DE0
    tx_nso_size = 0xF1198
    hbl_nso_off = 0x123504
    hbl_nso_size = 0x90DC
elif boot_ver == 0x332E3156:    # TX BOOT V1.3
    kip_skip = 0x10
    tx_nso_off = 0x31CF0
    tx_nso_size = 0xED474
    hbl_nso_off = 0x11F6F0
    hbl_nso_size = 0x8E18
else:
    exit()

# Check which firmware files are present
kip_list = os.listdir("./sxos/firmware/")

# No files found
if not kip_list:
    exit()

os.chdir("./sxos/firmware/")
 
for i in xrange(len(kip_list)):
    if os.path.isfile(kip_list[i]):
        kip_file = open(kip_list[i], "rb")
        kip_file.seek(kip_skip)
        kip_magic = struct.unpack("I", kip_file.read(4))[0]
   
        # Make sure the file is a KIP1
        if kip_magic == 0x3150494B:
            kip_name = kip_file.read(12).rstrip('\x00')
       
            # Create folder for this KIP1
            if not os.path.exists("./{:s}/".format(kip_name)):
                os.mkdir("./{:s}/".format(kip_name))
            os.chdir("./{:s}/".format(kip_name))
       
            # Decompress
            dec_kip_file = open("{:s}.bin".format(kip_name), "wb")
            dec_kip_file.write(decompress_kip(kip_file))
            dec_kip_file.close()
       
            # Handle Loader's NSOs
            if kip_name == "Loader":
                # Create folder for the NSOs
                if not os.path.exists("./NSO/"):
                    os.mkdir("./NSO/")
           
                # Extract the NSOs
                dec_kip_file = open("{:s}.bin".format(kip_name), "rb")
                dec_kip_file.seek(tx_nso_off)
                tx_nso_data = dec_kip_file.read(tx_nso_size)
                dec_kip_file.seek(hbl_nso_off)
                hbl_nso_data = dec_kip_file.read(hbl_nso_size)
                dec_kip_file.close()
           
                # Save the compressed NSOs
                tx_nso_file = open("./NSO/tx.bin", "wb")
                hbl_nso_file = open("./NSO/hbl.bin", "wb")
                tx_nso_file.write(tx_nso_data)
                hbl_nso_file.write(hbl_nso_data)
                hbl_nso_file.close()
                tx_nso_file.close()
           
                os.chdir("./NSO/")
           
                # Create folders
                if not os.path.exists("./tx/".format(kip_name)):
                    os.mkdir("./tx/".format(kip_name))
                if not os.path.exists("./hbl/".format(kip_name)):
                    os.mkdir("./hbl/".format(kip_name))
           
                # Decompress
                tx_nso_file = open("tx.bin", "rb")
                hbl_nso_file = open("hbl.bin", "rb")
                dec_tx_nso_file = open("./tx/main", "wb")
                dec_hbl_nso_file = open("./hbl/main", "wb")
                dec_tx_nso_file.write(decompress_nso(tx_nso_file))
                dec_hbl_nso_file.write(decompress_nso(hbl_nso_file))
                dec_hbl_nso_file.close()
                dec_tx_nso_file.close()
                hbl_nso_file.close()
                tx_nso_file.close()
           
                os.chdir("..")
   
            os.chdir("..")
       
        kip_file.close()
 

PSXHAX

Staff Member
Moderator
Contributor
Verified
How to Jailbreak a Nintendo Switch with Free Custom Firmware

Install eShop Games, Updates & DLC With SXOS On Nintendo Switch

How To Use FTP With SXOS v1.5 For Nintendo Switch
  • Dragon Injector mod-chip for Nintendo Switch updates via MatinatorX
 

PSXHAX

Staff Member
Moderator
Contributor
Verified
MAME 0.72 Port to Nintendo Switch by Lantus:
Roms go into /roms subfolder. You need MAME 0.72 roms for this to work.

This is the first version and there are bugs. I've tested CPS1, CPS2, Konami and Midway games and they work fine. Many others probably still wont work yet.

Quick Control Guide:

In Menu
  • Left/Right Trigger - scroll rom list
  • Dpad Up/Down - go up/down a single selection
  • A - Start Rom
In Game:
  • Dpad/Analog - Movement
  • Minus - Coin Up
  • Plus - Start
  • Right Analog Down - Mame Options Menu
  • Plus + Minus - Quit back to Rom Launcher
 

PSXHAX

Staff Member
Moderator
Contributor
Verified
Atmosphere-NX: Atmosphere is a work-in-progress customized firmware (CFW) for the Nintendo Switch.
 

PSXHAX

Staff Member
Moderator
Contributor
Verified
6.2.0 cracked

Here are some SHA256 hashes in celebration :)

PK11: 7D58F68E73784DCF8453B6BB67E78CC7D88004612DDD35DBEC91C385E3AF9413

Master key: 9497E6779F5D840F2BBA1DE4E95BA1D6F21EFC94717D5AE5CA37D7EC5BD37A19

Download: DevMenu 6.x Definitive Edition_v2.zip (15.6 MB) via ub3r1337

:arrow: Following Yoshihiro calling evilsperm out over the SwitchMe, he finally released the Gerber files that should have been public and open source in the scene instead of a private and closed source money-making scheme.
 

PSXHAX

Staff Member
Moderator
Contributor
Verified

PSXHAX

Staff Member
Moderator
Contributor
Verified
Status
Not open for further replies.
Recent Articles
PS4 Exploit Host Menu Leeful Host v2 WIP Design Update and Demo
Following the PS4 X-Project Updates, Pure HEN Child Friendly Loader and X-Project GTA V Lotus Menu 1.03 Patch PlayStation 4 homebrew developer @Leeful recently shared on Twitter a work-in-progress...
PlayStation Store Offers September Savings, Up to 70% Off PSN Games
Just in time for fall, Sony's PlayStation Store September Savings sale is underway and offers discounts of up to 70% off select PS4, PS Vita and PS3 games through October 1st at 8 AM Pacific time...
NAO PS4 Control: NAO Robots with PS4 DualShock 4 Controller by Caiit
Proceeding the WiFi Rover for RPi DS4 PS4 Controller earlier this week, today developer Caiit committed on Github NAO PS4 Control which as the name implies allows you to control a NAO Robot with a...
A Breaking Bad Movie El Camino Hits Netflix on October 11, 2019
After watching Season 4 of the prequel Better Call Saul and realizing Season 5 won't arrive until 2020 🤬, it's nearly time to jump ahead as next month on October 11th Netflix (with a second run by...
Top