Bits and bobs

This commit is contained in:
Bottersnike 2022-01-12 21:12:23 +00:00
parent f605f8f026
commit 0e15f97c77
7 changed files with 3959 additions and 8 deletions

View File

@ -0,0 +1,10 @@
<table>
<tr>
<td>X-Eamuse-Info</td>
<td><code>69d74627d985ee2187161570d08d93b12455035b6df0d8205df5</code></td>
</tr>
<tr>
<td>cardmng</td>
<td><code>7e924ed8d88464c65cb2deeab0b0b0ca9aca90c2b2e0f242</code></td>
</tr>
</table>

View File

@ -259,8 +259,7 @@ card[15] = <a href="#checksum">checksum(card)</a></code></pre>
needs doubled. This was presumably done to give the values more range, but I sincerely doubt it adds any
additional security.
</p>
<!-- Oh hello there. "?I'llB2c.YouXXXeMeHaYpy!" (without the quotes). Don't forget to double every byte before using
the key, giving us an actual key of 7e924ed8d88464c65cb2deeab0b0b0ca9aca90c2b2e0f242. -->
<!-- soundvoltex.dll:0x102d3e2d -->
<details>
<summary>I'm curious how Bemani implemented this in their own code!</summary>
<p>Curiosity is a great thing. Unfortunately, this is code that is implement within the game specific DLL files.

View File

@ -8,11 +8,11 @@
going to have to reverse engineer an open source project (or a closed source one, for that matter), I might as
well just go reverse engineer an actual game (or it's stdlib, as most of my time has been spent currently).</p>
<p>For the sake of being lazy, I'll probably end up calling it eAmuse more than anything else throughout these
pages. Other names you may come across include <code>httpac</code>* and <code>xrpc</code>. The latter are the
suite of HTTP functions used in the Bemani stdlib, and the name of their communication protocol they implement
at the application layer, but whenever someone refers to any of them in the context of a rhythm game, they will
be referring to the things documented here.<br />
<small style="margin-left: 8px">*I believe <code>httpac</code> is the official name for the protocol internally.</small>
pages. Other names you may come across include <code>httpac</code> and <code>xrpc</code>*. The former is the
suite of HTTP functions used in the Bemani stdlib, and the latter then name of their communication protocol they
implement at the application layer, but whenever someone refers to any of them in the context of a rhythm game,
they will be referring to the things documented here.<br />
<small style="margin-left: 8px">*I believe <code>xrpc</code> is the officialy used name for the protocol.</small>
</p>
<p>These pages are very much a work in progress, and are being written <i>as</i> I reverse engineer parts of the
protocol. I've been asserting all my assumptions by writing my own implementation as I go, however it currently
@ -35,6 +35,9 @@
</ul>
<p>If you yoink chunks of Python code, attribution is always appreciated, but consider it under CC0 (just don't be
that person who tries to take credit for it, yeah?).</p>
<p>Assembly and C snippets often come with an accompanying filename and address. If you're interested in learning how
things work in more detail, I'd strongly recommend checking them out. Not all games come with the same version of
files; the provided addresses are for build SDVX build KFC-2019020600, using the default base offset.</p>
<h2>Contents</h2>
<ol>

View File

@ -12,6 +12,8 @@
</ul>
<p>To make matters even easier, none of these endpoints require any functioning logic! It should be noted that to follow
along, however, you will need a functioning packet encoder and decoder.</p>
<p><small>Quick tangent: If the words "Smart E-Amusement" ring a bell and have you curious, you may be interested in
<a href="{{ROOT}}/smartea.html">how that works</a>.</small></p>
<h2 id="groundwork">Groundwork</h2>
<p>Before we get started, there are a few things we need to get out of the way. One potential elephant in the room is
how we tell games to use our server. You may have configured this thousands of times, or maybe this is your first

View File

@ -0,0 +1,209 @@
{% extends "base.html" %}
{% block body %}
<h1>Smart E-Amusement</h1>
<p>So maybe you've turned on that checkbox before, and you're wondering what magic it used? Thankfully, source code for
that tool is actually shipped along with it (provided you have a legitimate copy) so we can have a look.</p>
<p>...and that's where the trail runs cold. Upon cracking open the source you will just be faced with walls of hardcoded
binary data. Let's take a serious look at what we have here instead.</p>
<p>The first important thing to note is that every single reply from easrv is hardcoded. This means their encryption is
also hardcoded, and sure enough the header is hardcoded to <code>1-53d121c7-a8b3</code> (in fact, the entire HTTP
header block is a hardcoded string!).</p>
<p>Many of these responses are only rqeuired by specific games. I've not yet compiled a list of which is for what game,
but consider it a future expansion coming later :).</p>
<h2><code>services.get</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<services>
<item name="cardmng" url="http://localhost:8080/" />
<item name="facility" url="http://localhost:8080/" />
<item name="message" url="http://localhost:8080/" />
<item name="package" url="http://localhost:8080/" />
<item name="pcbevent" url="http://localhost:8080/" />
<item name="pcbtracker" url="http://localhost:8080/" />
<item name="posevent" url="http://localhost:8080/" />
<item name="pkglist" url="http://localhost:8080/" />
<item name="dlstatus" url="http://localhost:8080/" />
<item name="eacoin" url="http://localhost:8080/" />
<item name="lobby" url="http://localhost:8080/" />
<item name="lobby2" url="http://localhost:8080/" />
<item name="local" url="http://localhost:8080/" />
<item name="local2" url="http://localhost:8080/" />
<item name="apsmanager" url="http://localhost:8080/" />
<item name="netlog" url="http://localhost:8080/" />
<item name="ntp" url="ntp://pool.ntp.org/" />
<item name="keepalive" url="http://localhost:8080/keepalive?pa=localhost&amp;ia=localhost&amp;ga=localhost&amp;ma=localhost&amp;t1=2&amp;t2=10" />
</services>
</response>{% endhighlight %}</pre>
<h2><code>pcbtracker.alive</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<pcbtracker ecenable="0" eclimit="0" expire="0" limit="0" status="0" />
</response>{% endhighlight %}</pre>
<h2><code>message.get</code></h2>
<h3>Maintenance disabled:</h3>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<message status="0" />
</response>{% endhighlight %}</pre>
<h3>Maintenance enabled:</h3>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<message expire="300" status="0">
<item end="86400" name="sys.mainte" start="0" />
<item end="86400" name="sys.eacoin.mainte" start="0" />
</message>
</response>{% endhighlight %}</pre>
<h2><code>facility.get</code></h2>
<p>This packet notably has its encoding bytes as <code>00 FF</code> which to the best of my knowledge is not a valid
encoding. I used Shift-JIS here to decode the location name.</p>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<facility>
<location>
<id __type="str">US-01</id>
<country __type="str">US</country>
<region __type="str">.</region>
<name __type="str">・ョ・ッ・ョ・・</name>
<type __type="u8">0</type>
</location>
<line>
<id __type="str">.</id>
<class __type="u8">0</class>
</line>
<portfw>
<globalip __type="ip4">1.0.0.127</globalip>
<globalport __type="s16">8888</globalport>
<privateport __type="s16">8888</privateport>
</portfw>
<public>
<flag __type="u8">1</flag>
<name __type="str">.</name>
<latitude __type="str">0</latitude>
<longitude __type="str">0</longitude>
</public>
<share>
<eacoin>
<notchamount __type="s32">0</notchamount>
<notchcount __type="s32">0</notchcount>
<supplylimit __type="s32">1000000</supplylimit>
</eacoin>
<url>
<eapass __type="str">http://localhost</eapass>
<arcadefan __type="str">http://localhost</arcadefan>
<konaminetdx __type="str">http://localhost</konaminetdx>
<konamiid __type="str">http://localhost</konamiid>
<eagate __type="str">http://localhost</eagate>
</url>
</share>
</facility>
</response>{% endhighlight %}</pre>
<h2><code>pcbevent.put</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<pcbevent />
</response>{% endhighlight %}</pre>
<h2><code>package.list</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<package expire="1200" status="0" />
</response>{% endhighlight %}</pre>
<h2><code>tax.get_phase</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<tax>
<phase __type="s32">0</phase>
</tax>
</response>{% endhighlight %}</pre>
<h2><code>eventlog.write</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<eventlog>
<gamesession __type="s64">1</gamesession>
<logsendflg __type="s32">0</logsendflg>
<logerrlevel __type="s32">0</logerrlevel>
<evtidnosendflg __type="s32">0</evtidnosendflg>
</eventlog>
</response>{% endhighlight %}</pre>
<h2><code>machine.get_control</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<machine>
<command>
<arg __type="str">nop</arg>
</command>
</machine>
</response>{% endhighlight %}</pre>
<h2><code>info2.common</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<info2>
<event_ctrl />
</info2>
</response>{% endhighlight %}</pre>
<h2><code>pcb2.boot</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<shop2>
<sinfo>
<nm __type="str">AS</nm>
<cl_enbl __type="bool">1</cl_enbl>
<cl_h __type="u8">0</cl_h>
<cl_m __type="u8">0</cl_m>
</sinfo>
</shop2>
</response>{% endhighlight %}</pre>
<h2><code>pcb2.error</code></h2>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<pcb2 status="0" />
</response>{% endhighlight %}</pre>
<h2><code>system.getmaster</code></h2>
<p>Just an error response unless the game is one of...</p>
<h3>Steel Chronicle (<code>KGG-*</code>):</h3>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<system>
<result __type="s32">1</result>
<strdata1 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata1>
<strdata2 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata2>
<updatedate __type="u64">1120367223</updatedate>
</system>
</response>{% endhighlight %}</pre>
<h3>Metal Gear Arcade (<code>I36-*</code>):</h3>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<system>
<result __type="s32">1</result>
<strdata1 __type="str">MjAxMTA4MTAwMDoxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MToxOjE6MQ==</strdata1>
<strdata2 __type="str">MSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwx</strdata2>
<updatedate __type="u64">1120367223</updatedate>
</system>
</response>{% endhighlight %}</pre>
<h2><code>hdkoperation.get</code></h2>
<p>Only used by Steel Chronicle as far as I can tell</p>
<pre>{% highlight "cxml" %}<?xml version="1.0" encoding="SHIFT_JIS"?>
<response>
<hdkoperation>
<nr_entry __type="s32">1</nr_entry>
<param __type="str">0,0,0,0,0,0,0,0,0</param>
</hdkoperation>
</response>{% endhighlight %}</pre>
<h2><code>op2_common.get_music_info</code></h2>
<p>This one is really long. <a href="{{ROOT}}/smartea.op2_common.get_music_info.html">It's got its own dedicated
page</a> if you really want to see it anyway.</p>
<p>It appears to be specifically for Nostalgia Op.2, however this may be incorrect.</p>
{% endblock %}

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@
<p>Our per-packet key is then generated using <code>md5(serial | salt | KEY)</code>. Identifying <code>KEY</code> is
left as an exercise for the reader, however should not be especially challenging. <span style="color: #fff">Check
the page source if you're stuck.</span></p>
<!-- It's 69d74627d985ee2187161570d08d93b12455035b6df0d8205df5, if you were wondering. libavs-win32-ea3.dll:0x10054160 -->
<!-- libavs-win32-ea3.dll:0x10054160 -->
<h2 id="lz77">LZ77</h2>
<p>Packets are compressed using lzss. The compressed data structure is a repeating cycle of an 8 bit flags byte,