<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>gothi &#187; games</title>
	<atom:link href="http://www.gothi.co.uk/tag/games/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gothi.co.uk</link>
	<description>A badly chosen byte</description>
	<lastBuildDate>Thu, 26 Jan 2012 22:34:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Xbox save resigning &#8211; a technical overview</title>
		<link>http://www.gothi.co.uk/2010/06/xbox-save-resigning-a-technical-overview/</link>
		<comments>http://www.gothi.co.uk/2010/06/xbox-save-resigning-a-technical-overview/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 17:52:10 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Delphi]]></category>
		<category><![CDATA[hacking]]></category>
		<category><![CDATA[Xbox]]></category>

		<guid isPermaLink="false">http://www.gothi.co.uk/?p=231</guid>
		<description><![CDATA[This article covers the saves signing process used by the original Xbox.  Only the standard signing process is discussed, the &#8220;noroam&#8221; 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 [...]]]></description>
			<content:encoded><![CDATA[<p><em>This article covers the saves signing process used by the original Xbox.  Only the standard signing process is discussed, the &#8220;noroam&#8221; 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.</em></p>
<p>The reason I&#8217;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&#8217;s games are unable to access the Xbox Live service the following information is relatively harmless.</p>
<h3>A brief history</h3>
<p>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&#8217;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 <a title="SHA1 HMAC" href="http://en.wikipedia.org/wiki/HMAC" target="_blank">SHA1 HMAC</a> 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.</p>
<h3>Obtaining the XBE key</h3>
<p>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&#8217;t get confused, this is not the key used to sign the saves but is an essential piece in the process.<br />
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:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p231code6'); return false;">View Code</a> DELPHI</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2316"><td class="code" id="p231code6"><pre class="delphi" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">// XBE sections</span>
<span style="color: #000000; font-weight: bold;">unit</span> xbestruct<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">interface</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
ByteArray <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">array</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">..</span>15<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
TxbeHeader <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
	m_magic <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                    <span style="color: #808080; font-style: italic;">// magic number [should be &quot;XBEH&quot;]</span>
	m_digsig <span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">..</span>255<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> <span style="color: #000066; font-weight: bold;">char</span><span style="color: #000066;">;</span>      <span style="color: #808080; font-style: italic;">// digital signature</span>
	m_base<span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                      <span style="color: #808080; font-style: italic;">// base address</span>
	m_sizeof_headers <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>           <span style="color: #808080; font-style: italic;">// size of headers</span>
	m_sizeof_image <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>             <span style="color: #808080; font-style: italic;">// size of image</span>
	m_sizeof_image_header <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>      <span style="color: #808080; font-style: italic;">// size of image header</span>
	m_timedate <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                 <span style="color: #808080; font-style: italic;">// timedate stamp</span>
	m_certificate_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>         <span style="color: #808080; font-style: italic;">// certificate address</span>
	m_sections <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                 <span style="color: #808080; font-style: italic;">// number of sections</span>
	m_section_headers_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>     <span style="color: #808080; font-style: italic;">// section headers address</span>
	m_init_flags <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>
	m_entry <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                         <span style="color: #808080; font-style: italic;">// entry point address</span>
	m_tls_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                       <span style="color: #808080; font-style: italic;">// thread local storage directory address</span>
	m_pe_stack_commit  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                <span style="color: #808080; font-style: italic;">// size of stack commit</span>
	m_pe_heap_reserve <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// size of heap reserve</span>
	m_pe_heap_commit  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                 <span style="color: #808080; font-style: italic;">// size of heap commit</span>
	m_pe_base_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                   <span style="color: #808080; font-style: italic;">// original base address</span>
	m_pe_sizeof_image <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// size of original image</span>
	m_pe_checksum <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                <span style="color: #808080; font-style: italic;">// original checksum</span>
	m_pe_timedate <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                   <span style="color: #808080; font-style: italic;">// original timedate stamp</span>
	m_debug_pathname_addr  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>            <span style="color: #808080; font-style: italic;">// debug pathname address</span>
	m_debug_filename_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>           <span style="color: #808080; font-style: italic;">// debug filename address</span>
	m_debug_unicode_filename_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>   <span style="color: #808080; font-style: italic;">// debug unicode filename address</span>
	m_kernel_image_thunk_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>        <span style="color: #808080; font-style: italic;">// kernel image thunk address</span>
	m_nonkernel_import_dir_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>      <span style="color: #808080; font-style: italic;">// non kernel import directory address</span>
	m_library_versions <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// number of library versions</span>
	m_library_versions_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>          <span style="color: #808080; font-style: italic;">// library versions address</span>
	m_kernel_library_version_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>    <span style="color: #808080; font-style: italic;">// kernel library version address</span>
	m_xapi_library_version_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>      <span style="color: #808080; font-style: italic;">// xapi library version address</span>
	m_logo_bitmap_addr <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// logo bitmap address</span>
	m_logo_bitmap_size <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// logo bitmap size</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
pTXbeHeader <span style="color: #000066;">=</span> <span style="color: #000066;">^</span>TXbeHeader<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">type</span>
TxbeCertificate  <span style="color: #000066;">=</span> <span style="color: #000000; font-weight: bold;">record</span>
	m_size <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                          <span style="color: #808080; font-style: italic;">// size of certificate</span>
	m_timedate <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                     <span style="color: #808080; font-style: italic;">// timedate stamp</span>
	m_titleid <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                       <span style="color: #808080; font-style: italic;">// title id</span>
	m_title_name <span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">..</span>63<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> <span style="color: #000066; font-weight: bold;">widechar</span><span style="color: #000066;">;</span>                <span style="color: #808080; font-style: italic;">// title name (unicode)</span>
	m_alt_title_id <span style="color: #000066;">:</span> byteArray<span style="color: #000066;">;</span>            <span style="color: #808080; font-style: italic;">// alternate title ids</span>
	m_allowed_media  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                 <span style="color: #808080; font-style: italic;">// allowed media types</span>
	m_game_region  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>               <span style="color: #808080; font-style: italic;">// game region</span>
	m_game_ratings  <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                  <span style="color: #808080; font-style: italic;">// game ratings</span>
	m_disk_number <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                   <span style="color: #808080; font-style: italic;">// disk number</span>
	m_version <span style="color: #000066;">:</span> <span style="color: #000066; font-weight: bold;">cardinal</span><span style="color: #000066;">;</span>                       <span style="color: #808080; font-style: italic;">// version</span>
	m_lan_key <span style="color: #000066;">:</span> byteArray<span style="color: #000066;">;</span>                 <span style="color: #808080; font-style: italic;">// lan key</span>
	m_sig_key <span style="color: #000066;">:</span> byteArray<span style="color: #000066;">;</span>                  <span style="color: #808080; font-style: italic;">// signature key</span>
	m_title_alt_sig_key <span style="color: #000066;">:</span> <span style="color: #000000; font-weight: bold;">array</span><span style="color: #000066;">&#91;</span><span style="color: #0000ff;">0</span><span style="color: #000066;">..</span>15<span style="color: #000066;">,</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">..</span>15<span style="color: #000066;">&#93;</span> <span style="color: #000000; font-weight: bold;">of</span> <span style="color: #000066; font-weight: bold;">byte</span><span style="color: #000066;">;</span>     <span style="color: #808080; font-style: italic;">// alternate signature keys</span>
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">;</span>
&nbsp;
pTxbeCertificate <span style="color: #000066;">=</span> <span style="color: #000066;">^</span> TxbeCertificate<span style="color: #000066;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">implementation</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">end</span><span style="color: #000066;">.</span></pre></td></tr></table></div>

<p>The TxbeHeader record contains a lot of data but the two most important sections are <em>m_certificate_addr</em>, and <em>m_base</em>.  These two values give us the address of the certificate.</p>
<p>The following code retrieves the key from an XBE file:</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p231code7'); return false;">View Code</a> DELPHI</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2317"><td class="code" id="p231code7"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span>
    MS <span style="color: #000066;">:</span> TMemoryStream<span style="color: #000066;">;</span>
    xbeHeader <span style="color: #000066;">:</span> pTxbeHeader<span style="color: #000066;">;</span>
    xbeCert <span style="color: #000066;">:</span> pTxbeCertificate<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
&nbsp;
    MS <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TmemoryStream<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">;</span>
    MS<span style="color: #000066;">.</span><span style="color: #006600;">LoadFromFile</span><span style="color: #000066;">&#40;</span>FileName<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">new</span><span style="color: #000066;">&#40;</span>xbeHeader<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #000066;">new</span><span style="color: #000066;">&#40;</span>xbeCert<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    <span style="color: #808080; font-style: italic;">//Read in header and certificate</span>
    MS<span style="color: #000066;">.</span><span style="color: #000066;">Read</span><span style="color: #000066;">&#40;</span>xbeHeader<span style="color: #000066;">^</span><span style="color: #000066;">,</span> <span style="color: #000066;">sizeof</span><span style="color: #000066;">&#40;</span>xbeHeader<span style="color: #000066;">^</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
    MS<span style="color: #000066;">.</span><span style="color: #006600;">Position</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> xbeHeader<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">m_certificate_addr</span> <span style="color: #000066;">-</span> xbeHeader<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">m_base</span><span style="color: #000066;">;</span>
    MS<span style="color: #000066;">.</span><span style="color: #000066;">Read</span><span style="color: #000066;">&#40;</span>xbeCert<span style="color: #000066;">^</span><span style="color: #000066;">,</span> <span style="color: #000066;">sizeof</span><span style="color: #000066;">&#40;</span>xbeCert<span style="color: #000066;">^</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>We can now access the sig_key directly</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p231code8'); return false;">View Code</a> DELPHI</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2318"><td class="code" id="p231code8"><pre class="delphi" style="font-family:monospace;">xbeCert<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">m_sig_key</span></pre></td></tr></table></div>

<h3>Generating the signing key</h3>
<p>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&#8217;t need to determine the Xbox key every time we need to sign or verify a save as it is a constant.</p>
<p>The following is a <strong>textual </strong>representation of this key, to use it you must first convert it to a 16 byte array:</p>
<p><strong>5C0733AE0401F7E8BA7993FDCD2F1FE0</strong></p>
<p>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).</p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p231code9'); return false;">View Code</a> DELPHI</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p2319"><td class="code" id="p231code9"><pre class="delphi" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">var</span>
    digest <span style="color: #000066;">:</span> T160BitDigest<span style="color: #000066;">;</span>
<span style="color: #000000; font-weight: bold;">begin</span>
    digest <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CalcHMAC_SHA1<span style="color: #000066;">&#40;</span><span style="color: #000066;">addr</span><span style="color: #000066;">&#40;</span>xboxKey<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">16</span><span style="color: #000066;">,</span> xbeCert<span style="color: #000066;">^</span><span style="color: #000066;">.</span><span style="color: #006600;">m_sig_key</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">16</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<h3>Determining the data to process</h3>
<p>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&#8242;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.</p>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<p>Once you have found the sig location you should<strong> exclude</strong> this from the HMAC routines.  If the sig is at the end of the file you should HMAC all data <strong>up to</strong> the last 20 bytes, if it is at the beginning then all data <strong>after</strong> 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&#8217;s is to treat the area containing the result of the checksum as all 0&#8242;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.</p>
<h3>Generating the signature</h3>
<p>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.</p>
<p>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<em> sigKey</em></p>

<div class="wp_codebox_msgheader"><span class="right"><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p231code10'); return false;">View Code</a> DELPHI</span><div class="codebox_clear"></div></div><div class="wp_codebox"><table><tr id="p23110"><td class="code" id="p231code10"><pre class="delphi" style="font-family:monospace;">mem <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TMemoryStream<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">;</span>
mem2 <span style="color: #000066;">:</span><span style="color: #000066;">=</span> TMemoryStream<span style="color: #000066;">.</span><span style="color: #006600;">Create</span><span style="color: #000066;">;</span>
mem<span style="color: #000066;">.</span><span style="color: #006600;">LoadFromFile</span><span style="color: #000066;">&#40;</span>FileName<span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
mem<span style="color: #000066;">.</span><span style="color: #006600;">Position</span> <span style="color: #000066;">:</span><span style="color: #000066;">=</span> <span style="color: #0000ff;">0</span><span style="color: #000066;">;</span>
mem2<span style="color: #000066;">.</span><span style="color: #006600;">CopyFrom</span><span style="color: #000066;">&#40;</span>mem<span style="color: #000066;">,</span> mem<span style="color: #000066;">.</span><span style="color: #006600;">Size</span> <span style="color: #000066;">-</span> <span style="color: #0000ff;">20</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span>
digest <span style="color: #000066;">:</span><span style="color: #000066;">=</span> CalcHMAC_SHA1<span style="color: #000066;">&#40;</span><span style="color: #000066;">addr</span><span style="color: #000066;">&#40;</span>sigKey<span style="color: #000066;">&#41;</span><span style="color: #000066;">,</span> <span style="color: #0000ff;">16</span><span style="color: #000066;">,</span> mem2<span style="color: #000066;">.</span><span style="color: #006600;">memory</span><span style="color: #000066;">^</span><span style="color: #000066;">,</span> mem2<span style="color: #000066;">.</span><span style="color: #006600;">size</span><span style="color: #000066;">&#41;</span><span style="color: #000066;">;</span></pre></td></tr></table></div>

<p>Before making any changes to a save you should confirm that the signature you generate matches that already present on an unaltered save.</p>
<p>It&#8217;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 <strong>before</strong> the digital signature should you make any changes to the file.</p>
<h2>Conclusion</h2>
<p>The process of creating a digital signature for Xbox saves is fairly simple and can be summarized as</p>
<ul>
<li>SHA1 HMAC &#8220;XBE key&#8221; using &#8220;Xbox key&#8221;</li>
<li>Truncate resulting 160 bit digest to 16 bytes to create the &#8220;signature key&#8221;</li>
<li>SHA1 HMAC Save data using &#8221;signature key&#8221;</li>
<li>Compare resulting 160 bit digest to existing signature or write back to save file.</li>
</ul>
<p>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..</p>
<!-- AdSense Now! V1.90 -->
<!-- Post[count: 2] -->
<div class="adsense adsense-leadout" style="text-align:center;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-5905155743931046";
/* 468x15, created 10/04/10 */
google_ad_slot = "2193001556";
google_ad_width = 468;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div>]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2010/06/xbox-save-resigning-a-technical-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Burnout Paradise? More like Burnout Hell</title>
		<link>http://www.gothi.co.uk/2008/02/burnout-paradise-more-like-burnout-hell/</link>
		<comments>http://www.gothi.co.uk/2008/02/burnout-paradise-more-like-burnout-hell/#comments</comments>
		<pubDate>Wed, 06 Feb 2008 12:14:00 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[Rants]]></category>
		<category><![CDATA[Burnout Paradise]]></category>
		<category><![CDATA[Xbox360]]></category>

		<guid isPermaLink="false">http://gothi.co.uk/burnout-paradise-more-like-burnout-hell/</guid>
		<description><![CDATA[I&#8217;ve been been giving the newly released Burnout paradise some serious attention over the last week and with any new game I really want to love it, but like BDSM, one man&#8217;s Paradise is anothers Hell&#8230;. Criterion Games have taken the Burnout World and turned it into a free roaming sandbox game but since this [...]]]></description>
			<content:encoded><![CDATA[<p><img id="BLOGGER_PHOTO_ID_5163849468786712578" style="float:left; margin:0 10px 10px 0;" src="http://bp1.blogger.com/_iP-gn17tyQE/R6mtu4yfIAI/AAAAAAAAAG0/h6gmABKJvQM/s200/paradise.jpg" border="0" alt="Burnout Paradise boxart" />I&#8217;ve been been giving the newly released Burnout paradise some serious attention over the last week and with any new game I really want to love it, but like BDSM, one man&#8217;s Paradise is anothers Hell&#8230;.</p>
<p>Criterion Games have taken the Burnout World and turned it into a free roaming sandbox game but since this is a driving game don&#8217;t expect any GTA style escapades.  This new style in itself isn&#8217;t too bad but some seriously bad design choices have been implemented:</p>
<dl>
<dt>No retstarts. </dt>
<dd>Criterion boasted that this wouldn&#8217;t matter as there will always be other events near by. But <strong>it does matter</strong> Criterion.  When doing a Burning Route, having to drive for 5 mins to get back to the start just because you crashed once is not fun.  When you are trying to do the last few activities in the game to complete your licence, driving back for 5 minutes back to the race you just failed <strong>is not fun</strong>.  Even Rockstar realised that the GTA series needed a quick way to get back to a mission you failed and introduced taxi cabs as restarts.  Games are meant to be fun remember Criterion? </dd>
<dt>1 crash and you&#8217;re out! </dt>
<dd>During many of the later Burning Routes and races, once single crash is all it takes to be left so far behind that there is no point in continuing.  This is <strong>not fun</strong> Criterion.  I&#8217;ll give it another shot when I fail but when you punish me needlessly I start thinking about trading your game in for something <strong>fun</strong>. </dd>
<dt>You&#8217;ve just crashed, lets see that in slow mo and waste 5 seconds! </dt>
<dd>Like the boring relative who comes round to show you 500 holiday photo&#8217;s, Criterion decided that since they had spent so much time on the crumple/crash physics (instead of making the game fun it would seem) that they would show you it at every opportunity.  You wish for an option to turn this off after 30 minutes of first play and what makes it worse, you can actually lose races due to this &#8216;feature&#8217;. </dd>
<dt>I need a navigator! </dt>
<dd> Practically any race is 10% driving, 90% pausing to look at the map!  Let us set waypoints so we know when a turn is coming up and plan our own routes.  This is not a fun way to race!  If you try to use the mini-map you will end up crashing into any number of cars and walls and don&#8217;t forget, more than 1 crash and you may as well forget the later races.  Turns come up so fast that most of the time you will not see them until you&#8217;re way past them and the turn indicator is useless and distracting when planning your own route. </dd>
<dt>Don&#8217;t look at a curb! </dt>
<dd>The game seems so desperate to show me it&#8217;s crash engine that on several occasions it has crashed me when I was nowhere near a curb, wall or car.  I sat there in disbelief as my car crumpled on the edge of a tiny railing that I wasn&#8217;t near and wouldn&#8217;t expect to damage my car in the first place. </dd>
<dt>What do you mean you want to see the road ahead? </dt>
<dd> In what can only be thought of as some kind of punishment, the default camera angle is far too low to the ground.  This may mean you get a better feeling of speed but it also means that the road ahead is often a mystery until you end up face first into a wall, car or speck of dirt that causes you to crash.  heaven forbid you think to activate your Burnout along the road of random death.  You can raise the camera angle but only by holding up on the right analog stick, without some sellotape this is an impossible task when racing!  The only other view available is a first person one and the less said about that the better.</dd>
</dl>
<p>Now Burnout Paradise is fun at times, but there&#8217;s just too much wrong with it at a basic level.  This is the sort of game that appeals to car fanatics, Burnout Brand Slaves and submissives who love being punished.  A patch is forthcoming by the sounds of it, lets hope Criterion address some of the major problems with this game and give us the Paradise that it so wants to be.</p>
<p>As for me, I&#8217;ll keep plodding along with it, for all the stress it causes and poor design there&#8217;s a fun game in there fighting to get out. Online can be a lot of fun and there&#8217;s a definite feeling of satisfaction when you beat a friends time on a road.  This is probably Burnout&#8217;s saving grace but it relegates what should have been a first class game to a nice, but sometimes uncomfortable, second class.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2008/02/burnout-paradise-more-like-burnout-hell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xbox Live Friends List Cleanout</title>
		<link>http://www.gothi.co.uk/2007/12/xbox-live-friends-list-cleanout/</link>
		<comments>http://www.gothi.co.uk/2007/12/xbox-live-friends-list-cleanout/#comments</comments>
		<pubDate>Sat, 08 Dec 2007 22:27:00 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[gothi]]></category>
		<category><![CDATA[Xbox Live]]></category>
		<category><![CDATA[Xbox360]]></category>

		<guid isPermaLink="false">http://gothi.co.uk/xbox-live-friends-list-cleanout/</guid>
		<description><![CDATA[I&#8217;ve removed a lot of people from my Xbox Live Friends List today, if I haven&#8217;t played with you in the last 2 weeks or aren&#8217;t a long standing friend then you&#8217;re gone. Don&#8217;t take it personally, anyone I play with regularly will be added again, think of it as natural selection helping my friends [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:0 10px 10px 0;" src="http://bp0.blogger.com/_iP-gn17tyQE/Rt6xDAzUcxI/AAAAAAAAAGU/uSc-kaAQd80/s200/elite.jpg" border="0" alt="Picture of Xboxc 360 Elite" id="BLOGGER_PHOTO_ID_5106713692797694738" />I&#8217;ve removed a lot of people from my Xbox Live Friends List today, if I haven&#8217;t played with you in the last 2 weeks or aren&#8217;t a long standing friend then you&#8217;re gone.  Don&#8217;t take it personally, anyone I play with regularly will be added again, think of it as natural selection helping my friends list to be less cluttered.  On a side note, I don&#8217;t accept friend requests from people who I&#8217;ve not played on the same team as unless I know you previously so you&#8217;re friends request will unfortunately be declined</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2007/12/xbox-live-friends-list-cleanout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Halo 3 Big Team Battle &#8211; Capture the Flag tip</title>
		<link>http://www.gothi.co.uk/2007/11/halo-3-big-team-battle-capture-the-flag-tip/</link>
		<comments>http://www.gothi.co.uk/2007/11/halo-3-big-team-battle-capture-the-flag-tip/#comments</comments>
		<pubDate>Fri, 23 Nov 2007 00:02:00 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[gothi]]></category>
		<category><![CDATA[Halo 3]]></category>
		<category><![CDATA[Memor32]]></category>
		<category><![CDATA[Saves]]></category>

		<guid isPermaLink="false">http://gothi.co.uk/halo-3-big-team-battle-capture-the-flag-tip/</guid>
		<description><![CDATA[Here&#8217;s a quick tip for Capture the Flag on Sandtrap: Don&#8217;t move your teams Elephant to the the other teams Elephant. Yes, I know it sounds like a good idea, the two bases next to each other so you can kill the other team grab their flag and score within minutes. However, if you move [...]]]></description>
			<content:encoded><![CDATA[<p><img id="BLOGGER_PHOTO_ID_5117553381873900450" style="float:left; margin:0 10px 10px 0;" src="http://bp3.blogger.com/_iP-gn17tyQE/RwUzr9WxW6I/AAAAAAAAAGs/n_V_X8c9zEQ/s200/halo3.jpg" border="0" alt="Halo 3 logo" />Here&#8217;s a quick tip for Capture the Flag on Sandtrap: <strong>Don&#8217;t move your teams Elephant to the the other teams Elephant</strong>.</p>
<p>Yes, I know it sounds like a good idea, the two bases next to each other so you can kill the other team grab their flag and score within minutes. However, if you move <strong>your</strong> Elephant to the other side of the map and the other team kill you, then you start spawning on the far side of the map, a long way away from the action and your flag!  All you do is allow the other team to get you flag very quickly and end the match in record time.</p>
<p>By all means move the Elephants next to each other, but bring the other team&#8217;s Elephant to your base <img src='http://www.gothi.co.uk/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>On an unrelated note, my <a href="http://www.memor32.com" target="_blank">Memor32</a> was delivered today.  I&#8217;ll be putting it through it&#8217;s paces over the next few days and a comprehensive review will be posted over at <a href="http://www.ps2savetools.com" target="_blank">PS2 Save Tools</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2007/11/halo-3-big-team-battle-capture-the-flag-tip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Should legacy formats still be secret?</title>
		<link>http://www.gothi.co.uk/2007/03/should-legacy-formats-still-be-secret/</link>
		<comments>http://www.gothi.co.uk/2007/03/should-legacy-formats-still-be-secret/#comments</comments>
		<pubDate>Mon, 12 Mar 2007 23:05:00 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[games]]></category>
		<category><![CDATA[gothi]]></category>
		<category><![CDATA[PS2]]></category>
		<category><![CDATA[Saves]]></category>

		<guid isPermaLink="false">http://gothi.co.uk/should-legacy-formats-still-be-secret/</guid>
		<description><![CDATA[Technology marches on at an outstanding rate, in a few weeks time the Playstation 3 hits Europe and gamers still clinging to their &#8216;retro&#8217; consoles will slowly start on the migration to a newer and sleeker technology heaven. Many, like myself, will still keep their old and superseded hardware along with many of their favourite [...]]]></description>
			<content:encoded><![CDATA[<p>Technology marches on at an outstanding rate, in a few weeks time the Playstation 3 hits Europe and gamers still clinging to their &#8216;retro&#8217; consoles will slowly start on the migration to a newer and sleeker technology heaven.  Many, like myself, will still keep their old and superseded hardware along with many of their favourite titles.</p>
<p>The console manufacturers want you to upgrade.  The games publishers want you to upgrade.  The third party software/hardware developers want you to upgrade.  Your old games console is obsolete and you should be playing the latest and greatest on something that costs the about the same as 100 visits to the cinema or a feast fit for a king.</p>
<p>As time passes the old file formats get abandoned, superseded with newer formats for new software and machines.</p>
<p>I would like to see software developers and hardware producers open up these archaic file formats to the public.  They&#8217;re not going to loose any money from it and it may even rekindle some interest in their particular device or software.<br />Many file formats are already cracked, but having the offical specifcations and internal structures would allow utility makers to polish their code, finish features and more.</p>
<p>
<h4>Playstation 2 saves</h4>
<p>Playstation 2 saves come in many different formats, most have been cracked by talented individuals such as Vector who created <a href="http://www.ps2savetools.com/download.php?op=viewdownloaddetails&#038;lid=74">PS2 Save Builder</a>.  However some formats, notably .max and the newer Xploder save format, remain barely documented and to this day, people still cannot support these formats in their tools.</p>
<p>Releasing these specifications to the general public would allow those utility makers to support that format natively, instead they ultimately recommend alternative formats, which are now fully documented, such as the once barely known .psu save format.  uLaunchELF has recently added .psu support to it&#8217;s feature list which has resulted in an upsurge of .psu format saves being used and new utilities to be released</p>
<p>Is it too early to release the file specifications for formats such as .max to the public? Probably.  Would it affect sales?  At this late stage it&#8217;s hard to tell.</p>
<p>One thing I do know is that my choice of products to purchase, and to recommend to others, is heavily influenced by the file format used, specifically if it is open or unencrypted.  If it is encrypted or purposely protected in such a way as to stop people sharing, or creating utilities, I will look around for other products and recommend others do the same</p>
<p>Should legacy formats still be secret?  I don&#8217;t think so and would like to see more developers giving the information to the communities built around their product rather than gathering digital dust on some developers long forgotten hard drive.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2007/03/should-legacy-formats-still-be-secret/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fragmented usernames, gamertags and profiles</title>
		<link>http://www.gothi.co.uk/2006/12/fragmented-usernames-gamertags-and-profiles/</link>
		<comments>http://www.gothi.co.uk/2006/12/fragmented-usernames-gamertags-and-profiles/#comments</comments>
		<pubDate>Sun, 17 Dec 2006 23:31:00 +0000</pubDate>
		<dc:creator>gothi</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[PS2]]></category>
		<category><![CDATA[PS3]]></category>
		<category><![CDATA[Xbox]]></category>
		<category><![CDATA[Xbox360]]></category>

		<guid isPermaLink="false">http://gothi.co.uk/fragmented-usernames-gamertags-and-profiles/</guid>
		<description><![CDATA[I love online gaming. I don&#8217;t get enough time to participate these days, nor do I own any of the &#8220;next gen&#8221; consoles, which is where I am led to believe the most enjoyable online experience can be found, particularly if you are like me and use your PC for work and your consoles for [...]]]></description>
			<content:encoded><![CDATA[<p>I love online gaming.  <br/><br/>I don&#8217;t get enough time to participate these days, nor do I own any of the &#8220;next gen&#8221; consoles, which is where I am led to believe the most enjoyable online experience can be found, particularly if you are like me and use your PC for work and your consoles for fun.<br/><br/>Earlier this week Sony opened up a service that allowed you to <a href="https://account.np.ac.playstation.net/accounts/register/beginNewAccountRegistrationFlow.action" target="_blank" rel="nofollow">pre-book your online username/gamertag/persona</a> (call it what you will) if the Playstation 3 hasn&#8217;t reached your country yet or you just don&#8217;t fancy paying the eBay prices for their latest toy.<br/>I&#8217;m all for these services and decided to see if such a service was offered by Xbox Live.  Apparently it is, so I duly entered my details only to find that my gamertag was already taken&#8230;<br/><br/>I&#8217;ve been using the online persona <i>gothi</i> since the 90&#8242;s, I&#8217;m pretty fortunate in that it&#8217;s an usual word (although at the time I was not aware of it&#8217;s religious connotations). I&#8217;ve made a name for myself by posting, and administrating, on many forums, creating <a href="http://www.ps2savetools.com" target="_blank">websites</a>, I&#8217;ve released hundreds of Xbox &#038; PS2 saves, played in online tournaments, beta tested online PS2 games, written several widely used software programs and it&#8217;s even got to the point where some people think <a href="http://www.xboxcheats.com/cheats/XIII-3099.shtml" target="_blank" rel="nofollow">entering my username into a game makes you invincible</a>.  It doesn&#8217;t by the way, however using the cheat save I made for the Xbox version of XIII, which features my profile name, does.<br/><br/>I like to think I made myself known, I even own gothi.co.uk and the fact I cannot use my username, the one I have used for about a decade, on Xbox Live frustrates me.  <br/>I like how Xbox Live operates, one username for all games, but what do you do when your username is taken?  Do I have any right to ask that the user of this name gives it up?  I appear twice in the <a href="http://www.google.com/search?q=gothi" target="_blank" rel="nofollow">top 10 google results for gothi</a> (not bad considering my username is a religous term), does all that give me enough leverage to say that &#8220;this is my online persona&#8221;?<br/><br/>As it stands both Microsoft&#8217;s and now Sony&#8217;s approach is reasonable but limited.  You choose one name, but it is only unique to that system, and when a new system is released it can be mad scramble to get your name registered. In this case I clearly lost out on Xbox Live.  To make matters worse, some games companies, seeing that users want one name across the systems, have created their own private database of usernames that allow you to have one name across their collection of games.  Rather than improving matters this makes them worse as now there are even more private areas to register for and more chances to lose possession of your name. Without your name, and the reputation that follows it, who are you?<br/><br/>What I propose is a universal system where users can choose one name for all systems and games, regardless of publisher, designer or manufacturer.<br/>By use of an open API games designers can verify ownership of a gamertag and other information, such as game specific data, can be stored on their own databases.<br/><br/>Is it too late for such a system?  Maybe.  I truly hope it isn&#8217;t and that some order can be brought to the chaos that is forming.<br/><br/>I&#8217;d like to know what others think of the fragmentation issue we&#8217;re in and how you see it in 5 years time&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.gothi.co.uk/2006/12/fragmented-usernames-gamertags-and-profiles/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

