Posts Tagged hacking

Xbox save resigning – a technical overview

This article covers the saves signing process used by the original Xbox.  Only the standard signing process is discussed, the “noroam” signatures are not covered.  All code is based on my own work or derivative work of others.  The language used in examples is Delphi and assumes a familiarity with programming concepts such as the use of records or structures for reading in data.

The reason I’ve never previously discussed the Xbox save signing procedure in public is concern that by doing so would negatively impact Xbox Live.  Now that the original Xbox and it’s games are unable to access the Xbox Live service the following information is relatively harmless.

A brief history

The original Xbox used digital signatures to validate not only executables it was loading but save data, with this it was impossible to change or tamper with a save without updating the file’s digital signature using the correct key.  This key was generated using data contained within the default.xbe and a key used by the Xbox Operating System.  The save data was then run through a SHA1 HMAC routine and the 20 byte result appended to the save data to confirm integrity. This result, or digest, was usually found at the beginning or the end of a file although it can potentially be located anywhere in the file if the developer was feeling adventurous.

Obtaining the XBE key

Each Xbox game has a default.xbe file, this is the executable that is loaded whenever you start a game. It contains various information including the title ID, age rating, game region and the all important signature key.  Don’t get confused, this is not the key used to sign the saves but is an essential piece in the process.
The first step is to obtain the key directly from the XBE. This is stored in a certificate area of the file, the address of which is located in the XBE header. Before we can retrieve the key we need to define the structure of the XBE Header and the Certificate data we will be retrieving:

?View Code DELPHI
// XBE sections
unit xbestruct;
ByteArray = array[0..15] of byte;
TxbeHeader = record
	m_magic : cardinal;                    // magic number [should be "XBEH"]
	m_digsig : array[0..255] of char;      // digital signature
	m_base: cardinal;                      // base address
	m_sizeof_headers : cardinal;           // size of headers
	m_sizeof_image : cardinal;             // size of image
	m_sizeof_image_header : cardinal;      // size of image header
	m_timedate : cardinal;                 // timedate stamp
	m_certificate_addr : cardinal;         // certificate address
	m_sections : cardinal;                 // number of sections
	m_section_headers_addr : cardinal;     // section headers address
	m_init_flags : cardinal;
	m_entry : cardinal;                         // entry point address
	m_tls_addr : cardinal;                       // thread local storage directory address
	m_pe_stack_commit  : cardinal;                // size of stack commit
	m_pe_heap_reserve : cardinal;               // size of heap reserve
	m_pe_heap_commit  : cardinal;                 // size of heap commit
	m_pe_base_addr : cardinal;                   // original base address
	m_pe_sizeof_image : cardinal;               // size of original image
	m_pe_checksum : cardinal;                // original checksum
	m_pe_timedate : cardinal;                   // original timedate stamp
	m_debug_pathname_addr  : cardinal;            // debug pathname address
	m_debug_filename_addr : cardinal;           // debug filename address
	m_debug_unicode_filename_addr : cardinal;   // debug unicode filename address
	m_kernel_image_thunk_addr : cardinal;        // kernel image thunk address
	m_nonkernel_import_dir_addr : cardinal;      // non kernel import directory address
	m_library_versions : cardinal;               // number of library versions
	m_library_versions_addr : cardinal;          // library versions address
	m_kernel_library_version_addr : cardinal;    // kernel library version address
	m_xapi_library_version_addr : cardinal;      // xapi library version address
	m_logo_bitmap_addr : cardinal;               // logo bitmap address
	m_logo_bitmap_size : cardinal;               // logo bitmap size
pTXbeHeader = ^TXbeHeader;
TxbeCertificate  = record
	m_size : cardinal;                          // size of certificate
	m_timedate : cardinal;                     // timedate stamp
	m_titleid : cardinal;                       // title id
	m_title_name : array[0..63] of widechar;                // title name (unicode)
	m_alt_title_id : byteArray;            // alternate title ids
	m_allowed_media  : cardinal;                 // allowed media types
	m_game_region  : cardinal;               // game region
	m_game_ratings  : cardinal;                  // game ratings
	m_disk_number : cardinal;                   // disk number
	m_version : cardinal;                       // version
	m_lan_key : byteArray;                 // lan key
	m_sig_key : byteArray;                  // signature key
	m_title_alt_sig_key : array[0..15, 0..15] of byte;     // alternate signature keys
pTxbeCertificate = ^ TxbeCertificate;

The TxbeHeader record contains a lot of data but the two most important sections are m_certificate_addr, and m_base.  These two values give us the address of the certificate.

The following code retrieves the key from an XBE file:

?View Code DELPHI
    MS : TMemoryStream;
    xbeHeader : pTxbeHeader;
    xbeCert : pTxbeCertificate;
    MS := TmemoryStream.Create;
    //Read in header and certificate
    MS.Read(xbeHeader^, sizeof(xbeHeader^));
    MS.Position := xbeHeader^.m_certificate_addr - xbeHeader^.m_base;
    MS.Read(xbeCert^, sizeof(xbeCert^));

We can now access the sig_key directly

?View Code DELPHI

Generating the signing key

The key we retrieved from the XBE is not used to directly sign save data, instead it is used in a SHA1 HMAC with the Xbox key to produce the actual key we need. Thankfully we don’t need to determine the Xbox key every time we need to sign or verify a save as it is a constant.

The following is a textual representation of this key, to use it you must first convert it to a 16 byte array:


Once you have this key in a byte array simply run both the XBE key and the Xbox key through a SHA1 HMAC (referring to the documentation for your SHA1 HMAC function as to whether you need to pass data or memory addresses to the function). The output should be a 160bit digest truncated to 16 bytes (the last 4 bytes are not required and should not be used or present).

?View Code DELPHI
    digest : T160BitDigest;
    digest := CalcHMAC_SHA1(addr(xboxKey), 16, xbeCert^.m_sig_key, 16);

Determining the data to process

As noted before the digital signature is usually found before or after the actual save data.  It is entirely possible to store this signature at any location in the file and treat this location as all 0’s during the HMAC process.  Since we cannot rely on all developers using the same location for the signature we must determine the location ourselves.

The fastest and easiest way to do this is to start a new game and make a save at the earliest opportunity.  If the game saves any options you change this is ideal, otherwise start playing and save as soon as you can.  Copy this save to you PC and label is SAVE A.

Load the game again and create another save with as small a difference as you can but ensuring something is different.  As before, if the game saves option changes you should change only a single item and re-save. Copy this save to your PC and label it SAVE B.

Open both saves in a hex editor and visually compare the two, with little differences between them you should easily spot the 20 byte digital signature either at the start or the end of the file.  You can use an automatic file comparison if your editor supports it but in my experience I can find the sig faster by eye.  The signature in both files should be wildly different with the actual save data very consistent, aside from the minor differences you saved earlier.

Once you have found the sig location you should exclude this from the HMAC routines.  If the sig is at the end of the file you should HMAC all data up to the last 20 bytes, if it is at the beginning then all data after the first 20 bytes should be processed.  If the signature is located at another location in the file then you will need to experiment as to what data to HMAC.  A common trick when generating checksum’s is to treat the area containing the result of the checksum as all 0’s during the processing stage and write the result back to this location once complete.  Please note, it is rare to see this, most saves store their signature at the beginning or end of the file.

Generating the signature

Now you have the correct key and the data to process you can generate or check signatures for that particular games save files.  Similar to how the key was generated, the actual signature generation is a SHA1 HMAC of the save data (excluding the existing signature) with the key.

In the following example the save signature is located at the end of the file and the data is copied to a different memory stream for processing. The previously generated key is stored in a 16 byte array named sigKey

?View Code DELPHI
mem := TMemoryStream.Create;
mem2 := TMemoryStream.Create;
mem.Position := 0;
mem2.CopyFrom(mem, mem.Size - 20);
digest := CalcHMAC_SHA1(addr(sigKey), 16, mem2.memory^, mem2.size);

Before making any changes to a save you should confirm that the signature you generate matches that already present on an unaltered save.

It’s worth bearing in mind that a lot of saves contain a checksum as well as a digital signature.  The most common being a CRC32 or a simple addition of bytes, you must recalculate this before the digital signature should you make any changes to the file.


The process of creating a digital signature for Xbox saves is fairly simple and can be summarized as

  • SHA1 HMAC “XBE key” using “Xbox key”
  • Truncate resulting 160 bit digest to 16 bytes to create the “signature key”
  • SHA1 HMAC Save data using “signature key”
  • Compare resulting 160 bit digest to existing signature or write back to save file.

If you use the information above to create anything or produce a unique save, drop me a line in the comments, sometimes the most interesting time in a games life is long after it was released..

Tags: , , ,

A new year

Firstly, anyone waiting for my Memor32 review will be pleased to see it’s now up at PS2 Save Tools (after 7 revisions) 🙂

December was a challenging month to say the least and resulted in me dropping off the internet for a short while to recouperate and concentrate on that pesky thing known as Real Life. Illness combined with technology problems (including a damaged laptop, a totally destroyed phone and net connectivity akin somewhat to that of some string and a couple bean cans) left me reeling slightly but I’m getting back on top of things at last 🙂
Apologies to anyone awaiting an email responce from myself, I have 2000+ emails to sort through and will be responding as soon as I can!

Here’s to 2008, a milestone year for both myself and my girlfriend and hopefully some milestones in the hacking community!

Tags: , ,

PCSX2 memory card format revisited, again!

A while ago I took a couple of casual looks into the the format of the PS2 Memory Card images created by PCXS2. My initial thoughts were pretty basic and my follow up identified the basics of the format and also mentioned the ECC bytes I mistook for a regular checksum, thanks to alkarl and Matt for the corrections.

The other week I wrote out the code in Delphi to check and update the ECC sections and was set to delve into the format wholeheartedly. Until I found that Ross Ridge had been there and completed the work already!

Ross has put the information into the public domain, anyone interested should take a look at his excellent technical breakdown of the PlayStation 2 Memory Card File System and also give mymc, a tool for working with PCXS2 Memory Card images, a try.

Tags: ,

GTA: SA Censor Remover Online AKA Conversion Hell

I often get requests for versions of my tools that will work on non-Windows operating systems, such as Linux and MacOSX.
Because I use delphi, which is primarily a Windows programming tool, this often isn’t practical or even possible.

A few months ago I set about thinking of ways I could provide the same tools and abilities to those who don’t run Windows or have restrictions set on what they can download. I eventually decided to recreate one of my more popular tools, GTA: SA Censor Remover, in an online edition.

This wasn’t as easy a task as I had first assumed, my PHP skills were a little rusty from years of neglect in favour of Windows application development and PHP is an inherently poor language for working with binary files. I could have deviated from my original intention and written the online version in Perl, but I’m not that much of a masochist and I’m much more familiar with PHP.
After a few hours I was able to knock up a basic version that worked fine with PS2 and PC saves, even with PHP’s poor file handling routines, but came against a huge stumbling block with the Xbox saves.

Xbox saves are protected by a digital signature, change even one byte and the signature is invalidated and the save will not load. Of course I know how to fix this signature but this is where PHP let me down immensly.

PHP is a loosely type language, this means it’s great for beginners but sometimes you need to be able to control the language and it’s variables precisely, which is exactly what I needed to do. For reference, Delphi is a strongly typed language and is much better for it in my opinion. I can also access raw memory directly with Delphi which makes creating digital signatures a breeze.

I spent hours trying different ways of representing the binary data I needed to fix the digital signature in the save, I trawled the PHP manual for hints and comments. I even asked an experienced PHP programmer who writes scripts for a living daily and he was unable to help me or offer anything I hadn’t tried already.
Eventually I gave up, I’d chosen the wrong tool for the job and had paid bitterly for it.

Last night I was intrigued to see that the makers of Delphi, Codegear, are planning a “Delphi for PHP” and this rekindled my interest in PHP. Looking for a project to start I remembered about the work I had done on GTA: SA Censor Remover Online and how I had left it to rot on my dev machine.
I decided that I couldn’t let this go to waste and was a perfect challenge to get my PHP skills back on track, after all if I couldn’t find the answer from the manual and experienced users of PHP than I’d have to find it myself.
Eventually after a few tests, all producing the wrong digital signature, I commented out all the existing code and returned to the basic task: Create a binary representation of a series of bytes and pipe this along with the raw file data to the required function.

It was a matter of minutes before I had a working function. I spent a few hours tweaking the code and making sure it worked properly, again having to fight PHP’s poor file handling tooth and nail, until the final product was ready for release.

It’s been a hellish struggle and at times I wondered if the task was even possible given the poor performance of PHP in this area and lack of information out there, even from PHP experts. I won’t be retro-fitting any of my other tools at this time but if the need arises, or another prgram is created that would bendfit from an online version, I’ve got a solid groundwork to enable access to my software to everyone, regardless of what operating system they use.

Tags: , , , , , ,

New save sharing communities arise, how do they fare?

With the advent of the Playstation 3 and the Nintendo Wii there’s been a couple of new sites pop up to support the save trading community.
I’ve been checking on two sites in particular and have the following opinions.

First up there’s

Missing out on the elusive .com domain hasn’t deterred these guys one bit and they’ve started to make decent inroads into building a community for sharing Playstation 3 and Playstation 2 saves, in the suitable PS3 format of course.
The site has a blossoming community forum and whilst there doesn’t appear to be much technical talk there’s a good vibe and a decent amount of trading going on with helpful users.

Unfortunately I can’t be as kind about the main site. The design and content smack of “my first website”. I’m sorry to be harsh guys but the site looks poor and the content is sparse and not organised efficiently. Top marks for putting a forum up to encourage the community but please, enlist the services of a designer and sort your main site out. At worst use a portal system to keep the site tidy and organised.
I also had some difficulty finding the site in Google as it doesn’t rank well for Playstation 3 game saves, something that should be worked upon if possible. But not all is lost as it ranks quite well for PS3 game saves.

Overall the site has a lot of potential, the forum is something that will keep the users coming back but the main site needs some serious work and was off-putting on my first visit.

Next up we have Wii Save.

In contrast to PS3 saves, Wiisave has a beautiful front end and ranks well for the obvious search query. I’ve not come across the RW::Download script before but it does it’s job perfectly here. Having the content on the front page makes it easy for users to see new additions and keeps the site looking fresh and alive.
Information seems easy to reach but I’m not a fan of the javascript drop-down menu for each system supported by the Wii. It appears that for each save on the site there is a corresponding entry in the menu for the game. Once more saves are uploaded this is going to become unworkable, can you imagine a menu with 200+ entries on it?

Whilst I really like the clarity of the front page and the easy access to information, the site isn’t without problems.
The only way to communicate with other users of the site appears to be via a comments system which allows you to add comments to each save uploaded.
This simply isn’t enough to foster a community and eventually the users will move elsewhere. At the very least the admin should install a free message board such as phpBB and hack/edit it to accept the current user base and make future signups exist on both the main site and the forum.
I’ve also noticed the use of images directly next to Google ads, this is against the Ad-Sense Terms and Conditions and a shady technique at best.

In conclusion, the content of the site and it’s simple layout are a winner here but the lack of community features will result in the site loosing out long term.

Tags: , , , ,

Tutorial series planned

There’s not many tutorials on save hacking out there and even less that apply to the recent consoles such as the PS2 and Xbox, I’m going to be working on a couple to help people start up. I’ll be concentrating on some older classics that can be picked up really cheaply if you don’t already have the game.

The first tutorial I’m planning is to recreate the infamous Antman create-a-skater from Tony Hawk’s Pro Skater 3, one of my favourite in the Tony Hawk series and a great introduction as to what can be done via save hacking.
I’ll also be making a tutorial for PSV Exporter so people who may not so familiar with the tools a lot of use on a daily basis can get a clear idea of it can be used for.

Tags: ,

The end of save hacking?

Save hacking is exactly what the name implies, the manipulation of the raw data of the file a game uses to store such things as ammo counts, collected items, unlocked levels and more. It’s been a solid and reliable way to alter many games, be it the number of lives you have all the way up to unlocking removed levels and cheats that the game designers never wanted you to see.

I’ve been interested in save hacking for many years, I was once employed to do this very task, but a worrying trend has appeared recently, particularly in console saves.

Let’s take a (short) trip into the past.

Over the years developers and even the console makers have been finding different ways to make save hacking as difficult as possible. Saves started to use checksums to verify data integrity but these were easily bypassed. Next saves were encrypted by the game, although this too was bypassed by skilled people able to determine the methods used by the game and reverse the procedure. All was still good in the land of save hacking.

Fast forward to 2001 and the advent of the original Xbox console. Saves for this system used a digital signature as standard as well as other methods such as checksums and encryption, altering even one byte rendered the save invalid and the game would not load it.

After some serious hacking of the console and its operating system a method to resign the digital signature on the saves was discovered but the details of how to do this were shrouded in secrecy. A few people, myself included, were able to (re)discover the methods used and create our own tools to assist in save hacking. The most useful of these was a tool that the public could use to resign saves, but only those allowed by those with the knowledge. This secrecy, usually a burden to endeavours like these was a necessary evil; Xbox Live had taken off a storm and, due to the information to resign the saves for Live compatible games being released, the cheaters started to appear. This wasn’t the only way to cheat on Xbox Live but it was one that could be hampered and almost stamped out, so an unofficial and unagreed stance was taken by the few; no-one was to provide information on the resigning process nor provide keys that could affect online play.

Now in 2006 we have the next generation of consoles and save hacking faces new challenges.

The Xbox360 saves contain a digital signature, the methods and keys to resign this signature are still not known, at least publicly. I’ve yet to see hard evidence of a save for this system being hacked, at least in the traditional method.
The PS3, Sony’s latest games console, uses a system based on its work with the PSP.
The virtual PS2 saves it uses, the format of which I have mapped over at PS2 Save Tools, uses a digital signature so again, even changing one byte makes the save useless.
As for the saves generated by PS3 games, these are similar to PSP saves and as such are a totally encrypted file. The only save tools available for the PSP must be run on the PSP to unencrypt the data, at this time it is not possible to unencrypt the PS3 save data on a PC.

Where does this leave us?

I had hoped that the Xbox360 would have been laid bare by now but the DVD drive firmware modification has meant that many of the people with the technical knowledge are focusing on breaking new protections Microsoft put in place. This appears to have slowed down, if not stopped completely, efforts to run unofficial software on the Xbox360, a definite step towards editing and resigning save files.
At this time we are unable to run unsigned code on either the Xbox360 or the PS3 (Linux does not come into this) and in the PS3’s case, this may be exactly what is needed as it is with the PSP.

It’s a grim future for save hacking, the security systems on both the Xbox and the PSP have been bypassed by clever manipulation of certain save files which has resulted in tighter and more complicated methods for protecting the data integrity and ensuring we cannot alter save files.
Will I still be save hacking in 3 years time? I hope so but the future’s very uncertain at this time and not looking good…

Tags: , , , ,

PCSX2 memory card format revisited

PCSX2 is a PS2 emulator, it features memory card support and produces .ps2 files which are a raw image of the memory card, here’s what I had to say about them last time:

  • The file is a raw image of a PS2 memory card.
  • I believe it’s a similar system to FAT12/16, it’s got a similar FAT usage from my quick scan.
  • Every 512 bytes is a 16 byte footer, I assume it’s some sort of checksum

Spurred on by an email I recieved earlier I decided to do some more digging, here’s some prelimerary findings:

(all addresses include the 16 byte footers)

  • .PS2 file always has Sony PS2 Memory Card Format as it’s header.
  • The FAT table starts at 0x2520 , uses word(tbc?) for each entry
  • Clusters start at: 0xA920
  • Clusters are 0x200 in size.
  • First cluster is file entry for . (2E in hex), an entry for .. also exists
  • A file/directory entry occupies an entire 0x200 byte cluster and is broken down as such:
    The first int is the file/folder attribute
    second int is the file size.
    I belive the datetime is next.
    I belive the fat entry (word or int?) to be located 0x10 bytes in.
    The filename is 0x40 bytes in and 0 terminated.
  • The first cluster I found containing the file data was always located at 0xB9A0 in the files I looked at.
  • As with other FAT implementations 0xFFFF appears to be used to indicate end of chain (EOC) in the FAT table

Using the above information it should be possible to construct a basic tool to extract files from the .ps2 file.

I’ve been thinking about the 16 byte footer and believe it may be the attributes of the preceeding sector rather than a checksum. a sector contain all 00’s and a sector containing all FF’s both have the same footer…

Please note all information above is based on a 10 minute poke around the file in a hex editor, corrections and updates are welcome!

Tags: ,