SBSA
13
docs.py
@ -3,6 +3,8 @@ import datetime
|
|||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import jinja_markdown
|
||||||
|
|
||||||
from flask import Flask, send_from_directory, render_template, make_response, url_for
|
from flask import Flask, send_from_directory, render_template, make_response, url_for
|
||||||
from livereload import Server
|
from livereload import Server
|
||||||
|
|
||||||
@ -12,7 +14,12 @@ import ini_lexer # NOQA: F401
|
|||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
app.jinja_options.setdefault('extensions', []).append('jinja2_highlight.HighlightExtension')
|
extensions = app.jinja_options.setdefault('extensions', [])
|
||||||
|
extensions.append('jinja2_highlight.HighlightExtension')
|
||||||
|
extensions.append('jinja_markdown.MarkdownExtension')
|
||||||
|
|
||||||
|
jinja_markdown.EXTENSIONS.append("mdx_spantables")
|
||||||
|
jinja_markdown.EXTENSIONS.append("toc")
|
||||||
|
|
||||||
|
|
||||||
HTAG = re.compile(r"<h(\d)[^>]*id=\"([^\"]+)\"[^>]*>([^<]*)</h")
|
HTAG = re.compile(r"<h(\d)[^>]*id=\"([^\"]+)\"[^>]*>([^<]*)</h")
|
||||||
@ -105,6 +112,9 @@ def generate_xrpc_list():
|
|||||||
if prefix:
|
if prefix:
|
||||||
prefix = prefix.replace("/", ".") + "."
|
prefix = prefix.replace("/", ".") + "."
|
||||||
for i in files:
|
for i in files:
|
||||||
|
if i.startswith("~"):
|
||||||
|
continue
|
||||||
|
|
||||||
delim = "_" if prefix else "."
|
delim = "_" if prefix else "."
|
||||||
href = f"{ROOT}/proto{base[len(proto):]}/{i}"
|
href = f"{ROOT}/proto{base[len(proto):]}/{i}"
|
||||||
output += f"<li><code><a href=\"{href}\">"
|
output += f"<li><code><a href=\"{href}\">"
|
||||||
@ -325,6 +335,7 @@ for base, _, files in os.walk(TEMPLATES + "/" + PAGES_BASE):
|
|||||||
generate_xrpc_list=generate_xrpc_list,
|
generate_xrpc_list=generate_xrpc_list,
|
||||||
generate_toc=lambda start=1: generate_toc(base, name, route, start),
|
generate_toc=lambda start=1: generate_toc(base, name, route, start),
|
||||||
generate_footer=lambda: generate_footer(base, name, route),
|
generate_footer=lambda: generate_footer(base, name, route),
|
||||||
|
relative=lambda path: os.path.join(base, path).strip("/").replace("\\", "/"),
|
||||||
part=part,
|
part=part,
|
||||||
ioctl=ioctl,
|
ioctl=ioctl,
|
||||||
)
|
)
|
||||||
|
BIN
images/factorytest-export.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
images/factorytest-sbr.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
images/factorytest-tc1.png
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
images/factorytest-tc2.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
images/factorytest-tc3.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
images/ring/PXL_20220627_191703087.jpg
Normal file
After Width: | Height: | Size: 3.9 MiB |
BIN
images/ring/PXL_20220627_191722309.jpg
Normal file
After Width: | Height: | Size: 4.3 MiB |
BIN
images/ring/jvs-annotated.png
Normal file
After Width: | Height: | Size: 1.6 MiB |
BIN
images/ring/keychip-top.jpg
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
images/ring/keychip-underside.jpg
Normal file
After Width: | Height: | Size: 1.2 MiB |
186
mdx_spantables.py
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
"""
|
||||||
|
SpanTables Extension for Python-Markdown
|
||||||
|
========================================
|
||||||
|
This is a slightly modified version of the tables extension that comes with
|
||||||
|
python-markdown.
|
||||||
|
To span cells across multiple columns make sure the cells end with multiple
|
||||||
|
consecutive vertical bars. To span cells across rows fill the cell on the last
|
||||||
|
row with at least one underscore at the start or end of its content and no
|
||||||
|
other characters than spaces or underscores.
|
||||||
|
For example:
|
||||||
|
| head1 | head2 |
|
||||||
|
|-----------------|-------|
|
||||||
|
| span two cols ||
|
||||||
|
| span two rows | |
|
||||||
|
|_ | |
|
||||||
|
See <https://pythonhosted.org/Markdown/extensions/tables.html>
|
||||||
|
for documentation of the original extension.
|
||||||
|
Original code Copyright 2009 [Waylan Limberg](http://achinghead.com)
|
||||||
|
SpanTables changes Copyright 2016 [Maurice van der Pot](griffon26@kfk4ever.com)
|
||||||
|
License: [BSD](http://www.opensource.org/licenses/bsd-license.php)
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
from markdown.extensions.tables import TableProcessor
|
||||||
|
from markdown.extensions import Extension
|
||||||
|
import xml.etree.ElementTree as etree
|
||||||
|
|
||||||
|
|
||||||
|
class SpanTableProcessor(TableProcessor):
|
||||||
|
""" Process Tables. """
|
||||||
|
def test(self, parent, block):
|
||||||
|
rows = block.split('\n')
|
||||||
|
return (len(rows) > 1 and '|' in rows[0] and
|
||||||
|
'|' in rows[1] and '-' in rows[1] and
|
||||||
|
rows[1].strip()[0] in ['|', ':', '-'])
|
||||||
|
|
||||||
|
def is_end_of_rowspan(self, td):
|
||||||
|
return ((td is not None) and
|
||||||
|
(td.text.startswith('^') or td.text.endswith('^')) and
|
||||||
|
(td.text.strip('^ ') == ''))
|
||||||
|
|
||||||
|
def apply_rowspans(self, tbody):
|
||||||
|
table_cells = {}
|
||||||
|
|
||||||
|
rows = tbody.findall('tr')
|
||||||
|
max_cols = 0
|
||||||
|
max_rows = len(rows)
|
||||||
|
for y, tr in enumerate(rows):
|
||||||
|
|
||||||
|
cols = tr.findall('td')
|
||||||
|
|
||||||
|
x = 0
|
||||||
|
for td in cols:
|
||||||
|
|
||||||
|
colspan_str = td.get('colspan')
|
||||||
|
colspan = int(colspan_str) if colspan_str else 1
|
||||||
|
|
||||||
|
# Insert the td together with its parent
|
||||||
|
table_cells[(x, y)] = (tr, td)
|
||||||
|
|
||||||
|
x += colspan
|
||||||
|
|
||||||
|
max_cols = max(max_cols, x)
|
||||||
|
|
||||||
|
for x in range(max_cols):
|
||||||
|
possible_cells_in_rowspan = 0
|
||||||
|
current_colspan = None
|
||||||
|
|
||||||
|
for y in range(max_rows):
|
||||||
|
_, td = table_cells.get((x, y), (None, None))
|
||||||
|
|
||||||
|
if td is None:
|
||||||
|
possible_cells_in_rowspan = 0
|
||||||
|
|
||||||
|
else:
|
||||||
|
colspan = td.get('colspan')
|
||||||
|
if colspan != current_colspan:
|
||||||
|
current_colspan = colspan
|
||||||
|
possible_cells_in_rowspan = 0
|
||||||
|
|
||||||
|
if not td.text:
|
||||||
|
possible_cells_in_rowspan += 1
|
||||||
|
|
||||||
|
elif self.is_end_of_rowspan(td):
|
||||||
|
td.text = ''
|
||||||
|
possible_cells_in_rowspan += 1
|
||||||
|
first_cell_of_rowspan_y = y - (possible_cells_in_rowspan - 1)
|
||||||
|
for del_y in range(y, first_cell_of_rowspan_y, -1):
|
||||||
|
tr, td = table_cells.get((x, del_y))
|
||||||
|
tr.remove(td)
|
||||||
|
_, first_cell = table_cells.get((x, first_cell_of_rowspan_y))
|
||||||
|
first_cell.set('rowspan', str(possible_cells_in_rowspan))
|
||||||
|
|
||||||
|
possible_cells_in_rowspan = 0
|
||||||
|
|
||||||
|
else:
|
||||||
|
possible_cells_in_rowspan = 1
|
||||||
|
|
||||||
|
def run(self, parent, blocks):
|
||||||
|
""" Parse a table block and build table. """
|
||||||
|
block = blocks.pop(0).split('\n')
|
||||||
|
header = block[0].strip()
|
||||||
|
seperator = block[1].strip()
|
||||||
|
rows = [] if len(block) < 3 else block[2:]
|
||||||
|
# Get format type (bordered by pipes or not)
|
||||||
|
border = False
|
||||||
|
if header.startswith('|'):
|
||||||
|
border = True
|
||||||
|
# Get alignment of columns
|
||||||
|
align = []
|
||||||
|
for c in self._split_row(seperator, border):
|
||||||
|
if c.startswith(':') and c.endswith(':'):
|
||||||
|
align.append('center')
|
||||||
|
elif c.startswith(':'):
|
||||||
|
align.append('left')
|
||||||
|
elif c.endswith(':'):
|
||||||
|
align.append('right')
|
||||||
|
else:
|
||||||
|
align.append(None)
|
||||||
|
# Build table
|
||||||
|
table = etree.SubElement(parent, 'table')
|
||||||
|
thead = etree.SubElement(table, 'thead')
|
||||||
|
self._build_row(header, thead, align, border)
|
||||||
|
tbody = etree.SubElement(table, 'tbody')
|
||||||
|
for row in rows:
|
||||||
|
self._build_row(row.strip(), tbody, align, border)
|
||||||
|
|
||||||
|
self.apply_rowspans(tbody)
|
||||||
|
|
||||||
|
def _build_row(self, row, parent, align, border):
|
||||||
|
""" Given a row of text, build table cells. """
|
||||||
|
tr = etree.SubElement(parent, 'tr')
|
||||||
|
tag = 'td'
|
||||||
|
if parent.tag == 'thead':
|
||||||
|
tag = 'th'
|
||||||
|
cells = self._split_row(row, border)
|
||||||
|
c = None
|
||||||
|
# We use align here rather than cells to ensure every row
|
||||||
|
# contains the same number of columns.
|
||||||
|
for i, a in enumerate(align):
|
||||||
|
|
||||||
|
# After this None indicates that the cell before it should span
|
||||||
|
# this column and '' indicates an cell without content
|
||||||
|
try:
|
||||||
|
text = cells[i]
|
||||||
|
if text == '':
|
||||||
|
text = None
|
||||||
|
except IndexError: # pragma: no cover
|
||||||
|
text = ''
|
||||||
|
|
||||||
|
# No text after split indicates colspan
|
||||||
|
if text is None or text.strip() == "<":
|
||||||
|
if c is not None:
|
||||||
|
colspan_str = c.get('colspan')
|
||||||
|
colspan = int(colspan_str) if colspan_str else 1
|
||||||
|
c.set('colspan', str(colspan + 1))
|
||||||
|
else:
|
||||||
|
# if this is the first cell, then fall back to creating an empty cell
|
||||||
|
text = ''
|
||||||
|
else:
|
||||||
|
c = etree.SubElement(tr, tag)
|
||||||
|
c.text = text.strip()
|
||||||
|
|
||||||
|
if a:
|
||||||
|
c.set('align', a)
|
||||||
|
|
||||||
|
def _split_row(self, row, border):
|
||||||
|
""" split a row of text into list of cells. """
|
||||||
|
if border:
|
||||||
|
if row.startswith('|'):
|
||||||
|
row = row[1:]
|
||||||
|
if row.endswith('|'):
|
||||||
|
row = row[:-1]
|
||||||
|
return self._split(row)
|
||||||
|
|
||||||
|
|
||||||
|
class TableExtension(Extension):
|
||||||
|
""" Add tables to Markdown. """
|
||||||
|
|
||||||
|
def extendMarkdown(self, md):
|
||||||
|
""" Add an instance of SpanTableProcessor to BlockParser. """
|
||||||
|
md.parser.blockprocessors.register(SpanTableProcessor(md.parser, {}), 'spantable', 1000)
|
||||||
|
|
||||||
|
|
||||||
|
def makeExtension(*args, **kwargs):
|
||||||
|
return TableExtension(*args, **kwargs)
|
1
static/SBSA-00.key
Normal file
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD>и5цA3б?mК џ<C2A0>Ќ<>
|
45
styles.css
@ -28,21 +28,29 @@ svg {
|
|||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td,
|
||||||
|
th {
|
||||||
border: 1px solid #111;
|
border: 1px solid #111;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
min-width: 32px;
|
min-width: 32px;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
table:not(.code) td {
|
table~table {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
table:not(.code) td,
|
||||||
|
table:not(.code) th {
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.code td {
|
table.code td,
|
||||||
|
table.code th {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
td a {
|
.nav a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 4px 8px;
|
padding: 4px 8px;
|
||||||
}
|
}
|
||||||
@ -71,7 +79,8 @@ dfn {
|
|||||||
cursor: help;
|
cursor: help;
|
||||||
}
|
}
|
||||||
|
|
||||||
td>code {
|
td>code,
|
||||||
|
th>code {
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +88,8 @@ code>a {
|
|||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre>code, .highlight {
|
pre>code,
|
||||||
|
.highlight {
|
||||||
display: block;
|
display: block;
|
||||||
word-break: normal;
|
word-break: normal;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
@ -100,6 +110,12 @@ pre>.highlight {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.highlight>pre>code {
|
||||||
|
border: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
@ -131,7 +147,8 @@ table.nav {
|
|||||||
padding-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
table.nav td {
|
table.nav td,
|
||||||
|
table.nav th {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
margin-right: -1px;
|
margin-right: -1px;
|
||||||
margin-bottom: -1px;
|
margin-bottom: -1px;
|
||||||
@ -211,7 +228,9 @@ footer>*:last-child {
|
|||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.part:hover>span, .part:focus>span, .part>span:hover {
|
.part:hover>span,
|
||||||
|
.part:focus>span,
|
||||||
|
.part>span:hover {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,9 +322,11 @@ mark {
|
|||||||
.ata-bad {
|
.ata-bad {
|
||||||
color: #f5417d;
|
color: #f5417d;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ata-good {
|
.ata-good {
|
||||||
color: #4df541;
|
color: #4df541;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ata-ignore {
|
.ata-ignore {
|
||||||
color: #f5ad41;
|
color: #f5ad41;
|
||||||
}
|
}
|
||||||
@ -321,7 +342,8 @@ mark {
|
|||||||
border-top: 1px solid #fff5;
|
border-top: 1px solid #fff5;
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
td,
|
||||||
|
th {
|
||||||
border: 1px solid #777;
|
border: 1px solid #777;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,11 +355,12 @@ mark {
|
|||||||
background-color: #000;
|
background-color: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.highlight, img:not(.graphic) {
|
.highlight {
|
||||||
filter: invert(1);
|
filter: invert(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:visited {
|
a,
|
||||||
|
a:visited {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #f5417d
|
color: #f5417d
|
||||||
}
|
}
|
||||||
|
@ -1,441 +1,3 @@
|
|||||||
{% extends "sega.html" %} {% block title %}Ring Keychip{% endblock %} {% block body %}
|
{% extends "sega.html" %} {% block title %}Ring Keychip{% endblock %} {% block body %}
|
||||||
<h1>Ring Keychip</h1>
|
{% markdown %}{% include relative("~keychip.md") %}{% endmarkdown %}
|
||||||
<p>
|
{% endblock %}
|
||||||
The Ring keychip is arguably simultaniously one of the most overkill while least utilised parts of the system.
|
|
||||||
On-board is a PIC microcontroller, a dedicated cryptography chip, a hardware SHA engine for authentication, and
|
|
||||||
flash storage.
|
|
||||||
</p>
|
|
||||||
<h2>Protocol</h2>
|
|
||||||
<p>
|
|
||||||
The PIC communicates with the system using a parallel bus. This bus is exposed physically on the keychip connector,
|
|
||||||
and in software can be accessed using <code>\\.\mxparallel</code>. All bus communication is encrypted using AES 128
|
|
||||||
ECB, using a different key for each data direction. Send/receive is defined from the perspective of the Ring system.
|
|
||||||
That is, the "Send" key handles data from the Ring to the keychip, and the "Receive" key handles data from the
|
|
||||||
keychip to the Ring. The initial key values are:
|
|
||||||
</p>
|
|
||||||
<h3>Initial receive key:</h3>
|
|
||||||
<pre><code>75 6f 72 61 74 6e 65 6b 61 6d 69 68 73 75 6b 75</code></pre>
|
|
||||||
<h3>Initial send key:</h3>
|
|
||||||
<pre><code>66 6E 65 6B 65 72 61 77 64 72 61 68 61 67 65 73</code></pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
All packets are first prefixed by a command ordinal (see below), then command-specific information. The base unit of
|
|
||||||
transfer is 16 bytes due to AES 128. Unused bytes can contain anything, however mxkeychip chooses to pad using
|
|
||||||
random bytes derrived from the current system time.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h3>Command Ordinals</h3>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>Ordinal</td>
|
|
||||||
<td>Command</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><code>0</code></td>
|
|
||||||
<td>SetKeyS</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>1</code></td>
|
|
||||||
<td>SetKeyR</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>2</code></td>
|
|
||||||
<td>SetIv</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>3</code></td>
|
|
||||||
<td>Decrypt</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>4</code></td>
|
|
||||||
<td>Encrypt</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>5</code></td>
|
|
||||||
<td>GetAppBootInfo</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>6</code></td>
|
|
||||||
<td>EepromWrite</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>7</code></td>
|
|
||||||
<td>EepromRead</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>8</code></td>
|
|
||||||
<td>NvramWrite</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>9</code></td>
|
|
||||||
<td>NvramRead</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>10</code></td>
|
|
||||||
<td>AddPlayCount</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>11</code></td>
|
|
||||||
<td>FlashRead</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>12</code></td>
|
|
||||||
<td>FlashErase</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>13</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>14</code></td>
|
|
||||||
<td>FlashWrite</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>15</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>16</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>17</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>18</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>19</code></td>
|
|
||||||
<td></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>20</code></td>
|
|
||||||
<td>KcGetVersion</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>21</code></td>
|
|
||||||
<td>SetMainId</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>22</code></td>
|
|
||||||
<td>GetMainId</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>23</code></td>
|
|
||||||
<td>SetKeyId</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>24</code></td>
|
|
||||||
<td>GetKeyId</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><code>25</code></td>
|
|
||||||
<td>GetPlayCounter</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<h3>SetKeyS</h3>
|
|
||||||
<p>Sets the "send" encryption key. The key is changed before communication of the reply.</p>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">"send" encryption key</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h4>Response</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>SetKeyR</h3>
|
|
||||||
<p>Sets the "receive" encryption key. The key is changed before communication of the reply.</p>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">"receive" encryption key</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h4>Response</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>SetIv</h3>
|
|
||||||
<p>Reset the game key IV to its initial value</p>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h4>Response</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Decrypt</h3>
|
|
||||||
<p>Decrypt a block of data using the game key</p>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>3</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">ciphertext to decrypt</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>3</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">decrypted plaintext</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h3>Encrypt</h3>
|
|
||||||
<p>Encrypt a block of data using the game key</p>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>4</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">plaintext to encrypt</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
<h4>Request</h4>
|
|
||||||
<table>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<td>0</td>
|
|
||||||
<td>1</td>
|
|
||||||
<td>2</td>
|
|
||||||
<td>3</td>
|
|
||||||
<td>4</td>
|
|
||||||
<td>5</td>
|
|
||||||
<td>6</td>
|
|
||||||
<td>7</td>
|
|
||||||
<td>8</td>
|
|
||||||
<td>9</td>
|
|
||||||
<td>A</td>
|
|
||||||
<td>B</td>
|
|
||||||
<td>C</td>
|
|
||||||
<td>D</td>
|
|
||||||
<td>E</td>
|
|
||||||
<td>F</td>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tr>
|
|
||||||
<td>4</td>
|
|
||||||
<td colspan="15"><i>unused</i></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td colspan="16">encrypted ciphertext</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
{% endblock %}
|
|
367
templates/pages/sega/hardware/~keychip.md
Normal file
@ -0,0 +1,367 @@
|
|||||||
|
# Ring Keychip
|
||||||
|
|
||||||
|
The Ring keychip is arguably simultaniously one of the most overkill while least utilised parts of the system. On-board is a PIC microcontroller, a dedicated cryptography chip, a hardware SHA engine for authentication, and flash storage.
|
||||||
|
|
||||||
|
## Protocol
|
||||||
|
|
||||||
|
The PIC communicates with the system using a parallel bus. This bus is exposed physically on the keychip connector, and in software can be accessed using `\\.\mxparallel`. All bus communication is encrypted using AES 128 ECB, using a different key for each data direction. Send/receive is defined from the perspective of the Ring system. That is, the "Send" key handles data from the Ring to the keychip, and the "Receive" key handles data from the keychip to the Ring. The initial key values are:
|
||||||
|
|
||||||
|
### Initial receive key:
|
||||||
|
```
|
||||||
|
75 6f 72 61 74 6e 65 6b 61 6d 69 68 73 75 6b 75
|
||||||
|
```
|
||||||
|
### Initial send key:
|
||||||
|
```
|
||||||
|
66 6E 65 6B 65 72 61 77 64 72 61 68 61 67 65 73
|
||||||
|
```
|
||||||
|
|
||||||
|
All packets are first prefixed by a command ordinal (see below), then command-specific information. The base unit of transfer is 16 bytes due to AES 128. Unused bytes can contain anything, however mxkeychip chooses to pad using random bytes derrived from the current system time.
|
||||||
|
|
||||||
|
## Storage locations
|
||||||
|
### EEPROM
|
||||||
|
Stores entries detailing the tracedata metadata. There is a copy of the structure at 0x000 and a duplicate at 0x100. Each structure is comprised of 16 entries, where each entry first has a 4 byte CRC, then 12 bytes currently unknown.
|
||||||
|
|
||||||
|
### NVRAM
|
||||||
|
| Start | End | Content |
|
||||||
|
| ---------------- | ---------------- | ------------------ |
|
||||||
|
| 1800<sub>h</sub> | 1bff<sub>h</sub> | billing public key |
|
||||||
|
| 1c00<sub>h</sub> | 1fff<sub>h</sub> | ca certificate |
|
||||||
|
|
||||||
|
Each block begins with a 4 byte integer indicating the length of the data following it (up to 1020 bytes).
|
||||||
|
|
||||||
|
### Flash
|
||||||
|
|
||||||
|
| Start | End | Content |
|
||||||
|
| ----------------- | ----------------- | ------------------ |
|
||||||
|
| 00000<sub>h</sub> | 0ffff<sub>h</sub> | tracedata sector 1 |
|
||||||
|
| 10000<sub>h</sub> | 1ffff<sub>h</sub> | tracedata sector 2 |
|
||||||
|
| 20000<sub>h</sub> | 2ffff<sub>h</sub> | tracedata sector 3 |
|
||||||
|
| 30000<sub>h</sub> | 3ffff<sub>h</sub> | tracedata sector 4 |
|
||||||
|
| 40000<sub>h</sub> | 4ffff<sub>h</sub> | tracedata sector 5 |
|
||||||
|
| 50000<sub>h</sub> | 5ffff<sub>h</sub> | tracedata sector 6 |
|
||||||
|
| 60000<sub>h</sub> | 6ffff<sub>h</sub> | tracedata sector 7 |
|
||||||
|
| 70000<sub>h</sub> | 70fff<sub>h</sub> | nvram0 |
|
||||||
|
| 71000<sub>h</sub> | 71fff<sub>h</sub> | nvram1 |
|
||||||
|
| 72000<sub>h</sub> | 72fff<sub>h</sub> | nvram2 |
|
||||||
|
| 73000<sub>h</sub> | 73fff<sub>h</sub> | nvram3 |
|
||||||
|
| 74000<sub>h</sub> | 74fff<sub>h</sub> | nvram4 |
|
||||||
|
| 75000<sub>h</sub> | 75fff<sub>h</sub> | nvram5 |
|
||||||
|
| 76000<sub>h</sub> | 76fff<sub>h</sub> | nvram6 |
|
||||||
|
| 77000<sub>h</sub> | 77fff<sub>h</sub> | nvram7 |
|
||||||
|
| 78000<sub>h</sub> | 78fff<sub>h</sub> | nvram8 |
|
||||||
|
| 79000<sub>h</sub> | 79fff<sub>h</sub> | nvram9 |
|
||||||
|
| 7a000<sub>h</sub> | 7a10b<sub>h</sub> | billing info |
|
||||||
|
| 7b000<sub>h</sub> | 7b10b<sub>h</sub> | billing info dup |
|
||||||
|
|
||||||
|
Each tracedata sector begins with a 128-byte bitfield (1024 bits) indicating which blocks in the sector have been populated. Following this are 1022 blocks, 64 bytes each. (the last two of the theorhetical 1024 would overlap into the next sector). Each slot is individually encrypted with DES ECB, using key `4D77F1748D6D1094`.
|
||||||
|
|
||||||
|
This is implemented via the `AT25DF041A` 4Mbit flash chip on the keychip PCB. The maximum address is therefore 7ffff<sub>h</sub>.
|
||||||
|
|
||||||
|
## Command Ordinals
|
||||||
|
| Ordinal | Command |
|
||||||
|
| ------- | --------------------------------- |
|
||||||
|
| `0` | [SetKeyS](#setkeys) |
|
||||||
|
| `1` | [SetKeyR](#setkeyr) |
|
||||||
|
| `2` | [SetIv](#setiv) |
|
||||||
|
| `3` | [Decrypt](#decrypt) |
|
||||||
|
| `4` | [Encrypt](#encrypt) |
|
||||||
|
| `5` | [GetAppBootInfo](#getappbootinfo) |
|
||||||
|
| `6` | [EepromWrite](#eepromwrite) |
|
||||||
|
| `7` | [EepromRead](#eepromread) |
|
||||||
|
| `8` | [NvramWrite](#nvramwrite) |
|
||||||
|
| `9` | [NvramRead](#nvramread) |
|
||||||
|
| `10` | [AddPlayCount](#addplaycount) |
|
||||||
|
| `11` | [FlashRead](#flashread) |
|
||||||
|
| `12` | [FlashErase](#flasherase) |
|
||||||
|
| `13` | ? |
|
||||||
|
| `14` | [FlashWrite](#flashwrite) |
|
||||||
|
| `15` | ? |
|
||||||
|
| `16` | ? |
|
||||||
|
| `17` | ? |
|
||||||
|
| `18` | ? |
|
||||||
|
| `19` | ? |
|
||||||
|
| `20` | [KcGetVersion](#kcgetversion) |
|
||||||
|
| `21` | [SetMainId](#setmainid) |
|
||||||
|
| `22` | [GetMainId](#getmainid) |
|
||||||
|
| `23` | [SetKeyId](#setkeyid) |
|
||||||
|
| `24` | [GetKeyId](#getkeyid) |
|
||||||
|
| `25` | [GetPlayCounter](#getplaycounter) |
|
||||||
|
|
||||||
|
## SetKeyS
|
||||||
|
Sets the "send" encryption key. The key is changed before communication of the reply.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 0 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | key | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------ |
|
||||||
|
| key | The send key |
|
||||||
|
|
||||||
|
## SetKeyR
|
||||||
|
Sets the "receive" encryption key. The key is changed before communication of the reply.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 1 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | key | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | --------------- |
|
||||||
|
| key | The receive key |
|
||||||
|
|
||||||
|
## SetIv
|
||||||
|
Reset the game key IV to its initial value
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 2 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
## Decrypt
|
||||||
|
Decrypt a block of data using the game key
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 3 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| | ct | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | pt | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------ |
|
||||||
|
| ct | The encrypted ciptertext |
|
||||||
|
| pt | The decrypted plaintext |
|
||||||
|
|
||||||
|
## Encrypt
|
||||||
|
Encrypt a block of data using the game key
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 4 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | pt | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | ct | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------ |
|
||||||
|
| pt | The decrypted plaintext |
|
||||||
|
| ct | The encrypted ciptertext |
|
||||||
|
|
||||||
|
## GetAppBootInfo
|
||||||
|
Request the AppBoot structure from the keychip. The AppBoot structure is 256 bytes, thus requires 16 packets.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------------------- | --- | --- | -------- | --------------- | --- | --- | --- | ------- | --- | --- | --- | ------ | ---------- | ----------- | --- |
|
||||||
|
| Send | 5 | 0 | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | CRC | < | < | < | Format | < | < | < | Game ID | < | < | < | Region | Model type | System flag | ? |
|
||||||
|
| | Platform ID | < | < | DVD flag | Network address | < | < | < | | | | | | | | |
|
||||||
|
| | | | | | | | | | | | | | | | | |
|
||||||
|
| | _206 bytes padding_ | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| | | | | | | | | | | | | | | | | |
|
||||||
|
| ^ | Seed | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| --------------- | ----------------------------------------------------- |
|
||||||
|
| CRC | CRC32 checksum of the reamining 252 bytes |
|
||||||
|
| Format | AppBoot format type. The described type is format `1` |
|
||||||
|
| Game ID | Four character game ID. For example, `SBTR` |
|
||||||
|
| Region | Region bitmask |
|
||||||
|
| Model type | Model type this keychip is for |
|
||||||
|
| System flag | System flag bitmask |
|
||||||
|
| DVD flag | Is update from DVD allowed |
|
||||||
|
| Network address | Permitted subnet. Fourth octet is null |
|
||||||
|
|
||||||
|
**Note:** I'm not sure what the `0` is for here. Surprises await for anything other than `0` :D
|
||||||
|
|
||||||
|
## EepromWrite
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ---- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 6 | reg | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | data | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | --------------------------------------------------------------------- |
|
||||||
|
| reg | EEPROM register to write. EEPROM is divided into 16x16 byte registers |
|
||||||
|
| data | The data to write |
|
||||||
|
|
||||||
|
## EepromRead
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ---- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 7 | reg | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | data | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | -------------------------------------------------------------------- |
|
||||||
|
| reg | EEPROM register to read. EEPROM is divided into 16x16 byte registers |
|
||||||
|
| data | The data read |
|
||||||
|
|
||||||
|
## NvramWrite
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ---- | ---- | --- | ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 8 | addr | < | blocks | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | data | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ----------------------------------------------------- |
|
||||||
|
| addr | Absolute offset in NVRAM to write at |
|
||||||
|
| blocks | The number of 16 bytes blocks to write |
|
||||||
|
| data | The data to write. This will require `blocks` packets |
|
||||||
|
|
||||||
|
## NvramRead
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ---- | ---- | --- | ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 8 | addr | < | blocks | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | data | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------------------------------- |
|
||||||
|
| addr | Absolute offset in NVRAM to read at |
|
||||||
|
| blocks | The number of 16 bytes blocks to read |
|
||||||
|
| data | The read data. This will require `blocks` packets |
|
||||||
|
|
||||||
|
## AddPlayCount
|
||||||
|
Increment the playcount value
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 10 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
## FlashRead
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ---- | --- | ---- | --- | --- | ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 11 | addr | < | < | # bytes | < | < | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ----------------------------------- |
|
||||||
|
| addr | Absolute offset in flash to read at |
|
||||||
|
| # bytes | The number of bytes to read |
|
||||||
|
|
||||||
|
**Important:** Data is returned as raw bytes transmitted over parallel, without encryption or packet encapsulation.
|
||||||
|
|
||||||
|
## FlashErase
|
||||||
|
|
||||||
|
Honestly not actually sure if this is an erase or what. Still working on it!
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | ---- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 12 | addr | < | < | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
## FlashWrite
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --- | ---- | --- | --- | ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 14 | addr | < | < | # bytes | < | < | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------------------ |
|
||||||
|
| addr | Absolute offset in flash to write at |
|
||||||
|
| # bytes | The number of bytes to write |
|
||||||
|
|
||||||
|
**Important:** Data is transmitted immediately following transmission of the first packet. Is it transmitted as raw bytes over parallel, without encryption or packet encapsulation. The response packet is transmitted after # bytes have been received in this manner.
|
||||||
|
|
||||||
|
## KcGetVersion
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 20 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | version | < | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | --------------------------------------------------------------- |
|
||||||
|
| version | Two-byte version number. Keychips are observed to return 01,04. |
|
||||||
|
|
||||||
|
## SetMainId
|
||||||
|
Set the Main ID on the keychip, if not already set.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 21 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | Main ID | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | err | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------------------------------------------------ |
|
||||||
|
| Main ID | The new keychip Main ID. No validation is performed of this value. |
|
||||||
|
| err | ? (0?) when succesful, FF<sub>h</sub> otherwise |
|
||||||
|
|
||||||
|
## GetMainId
|
||||||
|
Get the Main ID on the keychip.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 22 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | Main ID | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------- |
|
||||||
|
| Main ID | The keychip Main ID |
|
||||||
|
|
||||||
|
## SetKeyId
|
||||||
|
Set the Key ID on the keychip, if not already set.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 23 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| ^ | Key ID | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
| |
|
||||||
|
| Receive | err | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | ------------------------------------------------------------- |
|
||||||
|
| Key ID | The new keychip ID. No validation is performed of this value. |
|
||||||
|
| err | ? (0?) when succesful, FF<sub>h</sub> otherwise |
|
||||||
|
|
||||||
|
## GetKeyId
|
||||||
|
Get the Key ID on the keychip.
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | ------ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 24 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | Key ID | < | < | < | < | < | < | < | < | < | < | < | < | < | < | < |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| -------- | -------------- |
|
||||||
|
| Key ID | The keychip ID |
|
||||||
|
|
||||||
|
## GetPlayCounter
|
||||||
|
Get the current playcount value
|
||||||
|
|
||||||
|
| | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F |
|
||||||
|
| ------- | --------- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
||||||
|
| Send | 24 | * | * | * | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
| |
|
||||||
|
| Receive | playcount | < | < | < | * | * | * | * | * | * | * | * | * | * | * | * |
|
||||||
|
|
||||||
|
| Variable | |
|
||||||
|
| --------- | --------------------------- |
|
||||||
|
| playcount | The billing playcount value |
|
@ -410,26 +410,26 @@
|
|||||||
<tr class="pad-row"></tr>
|
<tr class="pad-row"></tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>0800</td>
|
<td>0800</td>
|
||||||
<td>Unknown Error.</td>
|
<td>Unexpected Failure</td>
|
||||||
<td>Generic error code. Check the event log for details</td>
|
<td>Generic error code. Check the event log for details</td>
|
||||||
<td>ALLNetProc</td>
|
<td>ALLNetProc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>0801</td>
|
<td>0801</td>
|
||||||
<td>Unknown Error.</td>
|
<td>Main board Malfunctioning</td>
|
||||||
<td>Generic error code. Check the event log for details</td>
|
<td>RTC access failed</td>
|
||||||
<td>ALLNetProc</td>
|
<td>ALLNetProc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>0802</td>
|
<td>0802</td>
|
||||||
<td>Unknown Error.</td>
|
<td>Main board Malfunctioning</td>
|
||||||
<td>Generic error code. Check the event log for details</td>
|
<td>File access failed</td>
|
||||||
<td>ALLNetProc</td>
|
<td>ALLNetProc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>0803</td>
|
<td>0803</td>
|
||||||
<td>Unknown Error.</td>
|
<td>Unknown Error.</td>
|
||||||
<td>Generic error code. Check the event log for details</td>
|
<td>Invalid billing config file</td>
|
||||||
<td>ALLNetProc</td>
|
<td>ALLNetProc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="pad-row"></tr>
|
<tr class="pad-row"></tr>
|
||||||
@ -665,7 +665,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>8111</td>
|
<td>8111</td>
|
||||||
<td>ALL.Net System error(REG)</td>
|
<td>ALL.Net System error(REG)</td>
|
||||||
<td></td>
|
<td>ALL.Net rejected the keychip</td>
|
||||||
<td>ALLNetProc</td>
|
<td>ALLNetProc</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -1458,4 +1458,29 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<!-- From nxAuth -->
|
||||||
|
0390 - nxAuth is not working
|
||||||
|
0391 - Not Set Valid App Property
|
||||||
|
0392 - Not Found Valid System File
|
||||||
|
0393 - Not Found Aime Device Firmware File
|
||||||
|
0700 - Wrong Coin Setting
|
||||||
|
0701 - Wrong Cabinet Setting
|
||||||
|
0702 - Unexpected SelectMenu Failure
|
||||||
|
0703 - Storage Device Malfunctioning
|
||||||
|
0704 - Storage Device Malfunctioning
|
||||||
|
0705 - Game Program Not Acceptable
|
||||||
|
0706 - Storage Device Malfunctioning
|
||||||
|
0707 - Game Program Not Found
|
||||||
|
0708 - Storage Device Malfunctioning
|
||||||
|
0912 - Unexpected Game Program Failure
|
||||||
|
0913 - Game Program Not Found on Storage Device
|
||||||
|
6501 - Aime Card Reader Not Found
|
||||||
|
6502 - Aime Card Reader Unknown Error
|
||||||
|
6503 - Aime Read failed
|
||||||
|
6504 - Illegal Card Found
|
||||||
|
6505 - Occupied Aime Found
|
||||||
|
6506 - Aime Card Reader Firmware Update failed
|
||||||
|
6507 - Aime Card Reader Initialize failed
|
||||||
|
6508 - Aime DB Access failed
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
3
templates/pages/sega/software/factorytest.html
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{% extends "sega.html" %} {% block title %}Ring Series ASSY TEST{% endblock %} {% block body %}
|
||||||
|
{% markdown %}{% include relative("~factorytest.md") %}{% endmarkdown %}
|
||||||
|
{% endblock %}
|
47
templates/pages/sega/software/geminifs.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
{% extends "sega.html" %}
|
||||||
|
{% block title %}geminifs{% endblock %}
|
||||||
|
{% block body %}
|
||||||
|
<h1>geminifs</h1>
|
||||||
|
<p>geminifs is an incredibly interesting driver for merging two volumes into a single mounted drive. It is comprised of
|
||||||
|
<code>geminifs.exe</code> and <code>geminifs.sys</code>. The former is the interface programs are expected to use,
|
||||||
|
and the latter is the driver itself.</p>
|
||||||
|
|
||||||
|
<h2><code>geminifs.exe</code> help</h2>
|
||||||
|
<pre><code>
|
||||||
|
Usage: geminifs.exe <original-image-path> <patch-image-path> <mount-drive> [cache=on|off] [reparse=on|off]
|
||||||
|
geminifs.exe -u <dismount-drive>
|
||||||
|
|
||||||
|
ex1: mount drive
|
||||||
|
> geminifs.exe O:\ P:\ X:
|
||||||
|
> geminifs.exe O:\ P:\ X: cache=off
|
||||||
|
> geminifs.exe O:\ P:\ X: cache=on reparse=on
|
||||||
|
|
||||||
|
ex2: dismount drive
|
||||||
|
> geminifs.exe -u X:
|
||||||
|
|
||||||
|
Options:
|
||||||
|
|
||||||
|
cache=on
|
||||||
|
Enable geminifs file-cache.
|
||||||
|
cache=off
|
||||||
|
Disable geminifs file-cache. File access memory consumption is a
|
||||||
|
minimum, have to sacrifice access speed.
|
||||||
|
|
||||||
|
reparse=on
|
||||||
|
Enable the open file as a 'Reparse Point' to the original path name.
|
||||||
|
reparse=off
|
||||||
|
When you open a file mount, the geminifs driver open the file and
|
||||||
|
read access indirectly.
|
||||||
|
|
||||||
|
The geminifs driver that can change the value of these options for each
|
||||||
|
volume to be mounted (by using these command-line). If no value is specified,
|
||||||
|
each of the following registry value is used.
|
||||||
|
|
||||||
|
[Service-Key]\Parameters\FsCache REG_DWORD 0:OFF 1:ON
|
||||||
|
[Service-Key]\Parameters\FsOpenFileAsReparse REG_DWORD 0:OFF 1:ON
|
||||||
|
|
||||||
|
If these are not specified, the default value (cache=on, reparse=on) will be
|
||||||
|
used.
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -105,7 +105,7 @@ mxshellexecute.exe -->
|
|||||||
stroke="currentColor"></rect>
|
stroke="currentColor"></rect>
|
||||||
<text x="250" y="300" fill="currentColor" dominant-baseline="middle" text-anchor="middle"
|
<text x="250" y="300" fill="currentColor" dominant-baseline="middle" text-anchor="middle"
|
||||||
font-family="monospace">
|
font-family="monospace">
|
||||||
s:\mxinstaller.exe -cmdport 40102 -bindport 40103
|
s:\mxinstaller.exe -cmdport 40102 -binport 40103
|
||||||
</text>
|
</text>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -137,4 +137,11 @@
|
|||||||
</table>
|
</table>
|
||||||
<p>These errors are also reported into the Application event log, under the source <code>mxstartup</code>.</p>
|
<p>These errors are also reported into the Application event log, under the source <code>mxstartup</code>.</p>
|
||||||
|
|
||||||
|
<h2>TrueCrypt Commands</h2>
|
||||||
|
<li>
|
||||||
|
<ul><code>TrueCrypt /k Z:\UpdateKeyFile /v [...] \Device\Harddisk%d\Partition%d /l W: /s /q</code></ul>
|
||||||
|
<ul><code>TrueCrypt /k Z:\UpdateKeyFile /v Z:\Minint\System32\DEFAULT_DRIVERS /l V: /s /q</code></ul>
|
||||||
|
<ul><code>TrueCrypt /p segahardpassword /k Z:\SystemKeyFile /v C:\System\Execute\System /l S: /w /s /q</code></ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
{% endblock %}
|
{% endblock %}
|
51
templates/pages/sega/software/~factorytest.md
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
# Ring Series ASSY TEST
|
||||||
|
|
||||||
|
## What?
|
||||||
|
This is the testing tool used for self-checking RingWide, RingEdge and RingEdge2 PC systems. The automatic operation
|
||||||
|
of the tool is controlled by a number of configuration files stored on a locally attached USB storage device.
|
||||||
|
|
||||||
|
## Known Versions
|
||||||
|
|
||||||
|
| Version | Dumped? | Notes |
|
||||||
|
| ------- | ------- | ------------------------------- |
|
||||||
|
| 1.02 | No | |
|
||||||
|
| 1.04 | Yes | Only prefactorytest.exe changed |
|
||||||
|
| 1.10 | Yes | |
|
||||||
|
| 1.13 | Yes | |
|
||||||
|
| 1.16 | Yes | |
|
||||||
|
|
||||||
|
## How can I help?
|
||||||
|
|
||||||
|
The factory testing tool is installed into the `patch1` partition. Very few Ring games utilise this partition, and the test tool is not uninstalled for some reason, meaning we can extract it from the drive!
|
||||||
|
|
||||||
|
To start with, we need to locate the [SEGA Boot Record]({{ROOT}}/sega/misc/partition.html) and check if we have SBSA present in `patch1`. While this could be done totally manually, it's a lot easier to use disk forensics software as it will handle partition identification for us. Pictured is FTK Imager (free), however Autopsy (free) and X-Ways (not free) are all viable options.
|
||||||
|
|
||||||
|
![]({{ROOT}}/images/factorytest-sbr.png)
|
||||||
|
|
||||||
|
Starting at 0x5c0, we can begin to read out the partition information. First is the game ID, `SBSA`. Following that, is the install timestamp. This is
|
||||||
|
|
||||||
|
```c
|
||||||
|
struct {
|
||||||
|
uint16_t year;
|
||||||
|
uint8_t month;
|
||||||
|
uint8_t day;
|
||||||
|
uint8_t hour;
|
||||||
|
uint8_t minute;
|
||||||
|
uint8_t second;
|
||||||
|
uint8_t rsv;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The pictured example is `02 Apr 2010, 18:26:26`. The next four bytes are the version number. `04 00 01 00` here indicates version `1.04`.
|
||||||
|
|
||||||
|
If the version here is marked as dumped in the above table, then thank you for checking, but there's nothing new to find here! If it's not, then congratulations you've just found a new version! Let's get to dumping it!
|
||||||
|
|
||||||
|
The easiest way to proceed at this point is the extract the entire partition as a file. The partition we want is the second 2GiB partition. This is partition 7, however your software may have numbered it as partition 5.
|
||||||
|
|
||||||
|
The file we have created is a TrueCrypt volume. There is no password, and the keyfile is [`88D835E64133D13F6DBAA0FF9413AC9F`]({{ROOT}}/static/SBSA-00.key) (click to download).
|
||||||
|
|
||||||
|
![]({{ROOT}}/images/factorytest-tc1.png)
|
||||||
|
![]({{ROOT}}/images/factorytest-tc2.png)
|
||||||
|
![]({{ROOT}}/images/factorytest-tc3.png)
|
||||||
|
|
||||||
|
The files can now be copied from the chosen drive letter. **Please share them!**
|