Key material
A retail XEX is encrypted, and this project ships no key. This page explains what the key is, why one is needed, and how to supply it.
What is actually encrypted
A XEX carries a per title session key in its header. That session key is what the image is encrypted with, and it is different for every game.
The session key itself is stored wrapped, encrypted with one of a small number of static key encryption keys built into the console. Retail titles use the retail one. There is a separate devkit key, and titles built for a devkit use that instead.
So decoding a retail title is two steps:
- Unwrap the session key from the header using the static key.
- Decrypt the image with the session key.
The static key is the only thing this project does not have. It is 16 bytes, it is the same for every retail title, and it has been public for well over a decade. It is not derived from your console, it is not tied to any particular game, and knowing it does not decrypt anything you do not already have.
It is not shipped here because a project that distributes it is distributing a console's key material, and there is no need to.
Supplying it
Three sources are consulted, in order:
--key-file <PATH>, if given.- The
XENOLITH_XEX_KEYenvironment variable, as 32 hexadecimal digits. ~/.config/xenolith/xex.key.
The file form is usually what you want, since it survives across shells and does not end up in your history.
mkdir -p ~/.config/xenolith
printf '%s' '<32 hexadecimal digits>' > ~/.config/xenolith/xex.key
chmod 600 ~/.config/xenolith/xex.keyWhitespace and underscores are ignored, so any grouping you find readable works.
Working without one
Every subcommand except inspect accepts --raw, which reads an image something else already decoded. That needs no key at all.
xenolith analyze image.bin --raw --base 0x82000000Nothing describes the layout of a bare image, so it is treated as one executable span. That is a worse starting point than a container, which carries a real section table, but it makes work possible on a title whose key is not to hand.
inspect without --decode reads only the headers, which are not encrypted, so it always works.
When a title is not encrypted
Some titles are stored unencrypted. inspect reports which, on the encryption line, and decoding one needs no key. The tool only asks for key material when the container says the image is encrypted.