XexTool - xorloser

:: Overview

This is a tool to extract information on an xex file. It will print out
xex information to the console, alter xex attributes, extract executable code
and other basefiles and create idc scripts files to help with disassembling
the extracted executable code.

Note: any altered or created retail xex files will not be correctly signed.

:: Xex Format Basics

An xex file consists of a basefile that the xex is built around and headers
which contain various attributes to be used with the basefile.

Usually the basefile is an executable file, however it can also be data file,
as seen with ximedic.xex from the xbox360 flash. When the basefile is an
executable file it is either an exe or dll, however it is not stored in its
normal exe or dll format but instead as a binary file.

Some of the xex header attributes are required, and others are optional. Some
of these attributes are things such as the regions the xex is made for and the
media the xex is allowed to boot from.

The basefile can be optionally encrypted using aes encryption. All contents
of the basefile are hashed and then rsa signed. Microsoft is the only one with
access to the private key required to sign xexs in order to allow them to boot
on a retail xbox360. A different key is used to sign xex files in order to
allow them to boot on a development xbox360.

:: Usage

Usage:    XexTool <options> <xex filename>
          -l = print extended info list about xex file
          -p <xexp filename> = patch xex with xexp
          -b <base filename> = dump basefile from xex
          -i <idc filename>  = dump basefile info to idc file
          -d <res. dirname>  = dump all resources to a dir (can be '.')
          -o <xex filename>  = output altered xex to a new file
          -r = remove xex limitations (a/m/r/b/k/l/c/z)
               a = remove all limits (same as "mrbtlz")
               m = remove media limits (all media)
               r = remove region limits (all regions)
               b = remove bounding pathname
               k = remove signed keyvault only limitation
               l = remove minimum library version limitations
               c = remove required revocation check
               z = zero the media id
          -m = force output xex machine format (r/d)
               r = force output xex to be retail
               d = force output xex to be devkit
          -c = force output xex compression format (c/u/b)
               c = force output xex to be compressed
               u = force output xex to be uncompressed (no zeroed data)
               b = force output xex to be binary (has zeroed data)
          -e = force output xex encryption format (d/e)
               d = force output xex to be decrypted
               e = force output xex to be encrypted

If "-o" is not used, the original xex file will be altered.
Multiple options can be given at once, eg: "-m d -r mrl".
If no options are given, a shortened xex info list will be printed.

* Media limits limit what media the xex can be booted from.
* Region limits limit what console regions an xex can be booted on.
* Bounding pathname limits a xex to being executed from a specified path only.
* Signed keyvault limits an xex to running from an xbox360 which has a signed keyvault.
* Minimum library versions require system dlls to be of a specified
  version of higher. The usual imports are from xboxkrnl.exe and xam.exe.
* Required revocation check requires the xex to be checked against
  a list of revocated xexs before allowing it to boot.
* A media id can be used to lock block an xex from running if it matches
  "banned" media ids. This is the case for xexs from the famous "kiosk disc".

:: Usage Examples

* Print basic info about an xex file to console:
xextool default.xex

* Print extended info about an xex file to console:
xextool -l default.xex

* Extract the executable basefile from default.xex into default.exe:
xextool -b default.exe default.xex

* Extract the executable file and create an idc script file from default.xex:
xextool -b default.exe -i default.idc default.xex

* Convert a retail xex into a development xex:
xextool -m d default.xex

* Convert a retail xex into a seperate development xex:
xextool -m d -o devkit.xex retail.xex

* Remove all region and media limits from an xex:
xextool -r mr default.xex

* Remove all limits and convert a retail xex into a devkit xex:
xextool -r a -m d default.xex

* Convert an xex into an unencrypted binary format:
xextool -e d -c b -o default-binary.xex default.xex

* Convert unencrypted binary xex back into an encrypted compressed xex:
xextool -e e -c c -o default.xex default-binary.xex

:: Specifics

This tool enables you to do many things with an xex file if you understand
how to do so. Some usage examples are given above, but here is some more
detailed information on a few specific cases.

  How to make a retail xexs work on a development xbox360

This is quite easy with this tool, just do the following:
xextool -ra -m d default.xex

Not only will the xex work on a devkit, it will also now work from any media
and run region independently.

  How to patch an xex file with an xexp patch file.

Updates to games and system files are provided over xbox live in the form of
patch files. These updates are stored inside package files in the Cache folder
on you hard drive. A system update usually has "SU" as part of the filename,
and a title update (game update) usually has a "TU" as part of the filename.

A patch file will only work when used with an untouched version of the original
xex file it was created for. When you have the original xex file and the patch
file you want to use with it, do the following to create the updated xex:
xextool -p patch.xexp -o output.xex input.xex

Note: A retail xex requires a retail patch file, a devkit xex requires a devkit
patch file. If an xex has been converted from a retail to a devkit xex, you need
to use the retail patch file with the original retail xex, then convert the
resultant xex file into a devkit xex file.

  How to reverse engineer and alter the code in an xex file.

First extract the executable base file and idc script file as follows:
xextool -b default.exe -i default.idc default.xex

Xextool will tell you how to load the file into ida. If you don't have ida,
then load it into the disassembler you are using with the same parameters.
An example of the load info xextool gives you is as follows:

Load basefile into IDA with the following details
DO NOT load as a PE or EXE file as the format is not valid
File Type:       Binary file
Processor Type:  PowerPC: ppc
Load Address:    0x92000000
Entry Point:     0x9201DD38

Note: even though this file seems to be a normal exe or dll file it is not!
You MUST load this file as a binary file, not a pe, exe or dll.

Once the file has been loaded into ida, run the idc script file. It will
expect the "x360_imports.idc" file included with xextool to be in your
"ida/idc" directory.

Once you have found any areas you want to change or patch, make these
changes to the exe basefile you extracted above (default.exe).

Now you need to insert the basefile (default.exe) back into your xex file.
So do the following to get a fully decrypted and decompressed xex:
xextool -e d -c b -o default-hack.xex default.xex

Now open default-hack.xex in a hex editor and find where the basefile starts.
You can search for the "MZ" present in the exe header to find this.
(Often its around the 0x2000 byte offset mark.)
Now copy the contents of default.exe into default-hack.xex over the top of
the basefile that is inside default.xex. It should exactly fill the rest of
the default-hack.xex file from where you start inserting default.exe.
Now do:
xextool -o default-done.xex default-hack

The default-done.xex file will now be resigned and ready to use, unless its
retail in which case it won't get resigned correctly. When creating the
default-done.xex file you can also specify encryption and compression options
for the output file if you wish.

:: History

	* fixed and updated the idc file creation
	* fixed struct changes that caused invalid library imports
	+ added patching ability, lets you do: source.xex + patch.xexp = target.xex
	+ added the ability to dump resources from an xex file
	+ added "exports" and "exports by name" to idc file creation
	+ added "sections" and "resources" to idc file creation
	* fixed handling of unknown image entries
	* fixed dumping of unknown basefiles
	* fixed handling of dlls with no execution entrypoint
	+ added support for loading/saving register blocks to idc creation
	+ added support for a few new xex flags, eg ramdrive and iptv stuff
	+ added support for encrypting/decrypting retail "manufacturing" xexs
	* fixed a memory leak that occurred while encrypting/decrypting xexs
	* fixed delta compression problem that occurred when a block size was
	  the same size as the maximum allowed block size
	+ added remove required revocation check option

	* fixed delta compression problem where it was possible for the last block
	  to be oversized

	* fixed checking of revocation flag when selecting signature salt

	+ official release that supports retail xexs

	* fixed raw compression problem where it was possible for the last block to
	  be left off

no log was kept of earlier history - but there were lots of addition and fixes :)

+ = added feature
- = removed feature
* = fixed or changed feature

:: Bugs

There is a rarely occurring bug in my compression routines. Of all the files I
have tested, I have only seen about 2 or 3 files where this bug comes into play.
It is obvious when it does as xextool will crash :)

I had planned to fix this bug before releasing this tool, but it has now sat here
for over six months without being released and I still havent got around to fixing
it, so I thought I might as well release it and fix this bug later if I ever get
around to it. (The bug should only affect around 0.1% of cases)

:: Greets

xor37h, for his initial version of xextool that started me working on this one
and gave me the first hints into the structure and layout of the xex file
format. tmbinc for also providing info that helped me get started and all the
others who tested, reported bugs, gave encouragement and provided info to
further improve this tool.