Compare commits

..

8 Commits
5.38 ... 5.39

Author SHA1 Message Date
icex2
85a080e6b3 Update changelog for 5.39 release 2022-05-19 00:02:20 +02:00
95c6cd771e00602e3ec82fccba1b3741fdb7f7ca
28633ded37 jbhook2 and jbhook3 gfx updates
- Fix jbhook3 window mode
- Remove -f option for framed window, no value
- Add -s option to show mouse cursor on window
2022-05-13 19:26:00 +00:00
QCDLZCLW3K
721897d7b0 Separate key algorithm and core code for rp2 and rp3 2022-05-12 10:25:53 +09:00
QCDLZCLW3K
926bbf2e10 Small refactor for rp2 and rp3 + add new sign keys 2022-05-12 05:18:07 +09:00
Will Toohey
ce75e149f7 Sane default for vertical window (true) 2022-04-03 21:40:18 +10:00
Will Toohey
57d9d976ff jbhook2: get p3io sidcode from ea3-config, don't hardcode 2022-04-03 21:32:33 +10:00
Will Toohey
7e731916e2 Move p3io-specific jbhook-util funcs to their own static lib 2022-04-03 21:02:38 +10:00
icex2
dd9b8faafe Bump version to 5.39 for next development cycle 2022-04-02 11:16:58 +02:00
43 changed files with 386 additions and 337 deletions

View File

@@ -2,6 +2,11 @@
Note for CI/CD: Ensure the version formatting in the sections is kept identical to the versions
given in tags. The pipeline will pick this up and cuts out the relevant section for release notes.
## 5.39
* jbhook3: Fix window mode, remove window frame option, add show cursor on window option
* Code simplification and cleanup round plug modules
* Code structure improvements p3io jubeat
## 5.38
* sdvxhook2: Support sound voltex exceed gear

View File

@@ -142,6 +142,7 @@ include src/main/jbio-p4io/Module.mk
include src/main/jbio/Module.mk
include src/main/jbiotest/Module.mk
include src/main/jbhook-util/Module.mk
include src/main/jbhook-util-p3io/Module.mk
include src/main/jbhook1/Module.mk
include src/main/jbhook2/Module.mk
include src/main/jbhook3/Module.mk

View File

@@ -1,7 +1,7 @@
# Bemanitools 5
[![pipeline status](https://dev.s-ul.net/djhackers/bemanitools/badges/master/pipeline.svg)](https://dev.s-ul.net/djhackers/bemanitools/commits/master)
Version: 5.38
Version: 5.39
[Release history](CHANGELOG.md)

View File

@@ -46,8 +46,5 @@ gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false
# Security boot version (e.g. GEC02).
sec.boot_version=GQGLDJAA
# Security black plug mcode id string (e.g. GQC02JAA).
sec.black_plug_mcode=GQGLDJA
sec.black_plug_mcode=GQGLDJAA

View File

@@ -46,8 +46,5 @@ gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false
# Security boot version (e.g. GEC02).
sec.boot_version=GQHDDJAA
# Security black plug mcode id string (e.g. GQC02JAA).
sec.black_plug_mcode=GQHDDJA
sec.black_plug_mcode=GQHDDJAA

View File

@@ -49,8 +49,5 @@ gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false
# Security boot version (e.g. GEC02).
sec.boot_version=GQI00JAA
# Security black plug mcode id string (e.g. GQC02JAA).
sec.black_plug_mcode=GQI00JA
sec.black_plug_mcode=GQI00JAA

View File

@@ -49,8 +49,5 @@ gfx.device_adapter=-1
# Disable operator clock setting system clock time
misc.disable_clock_set=false
# Security boot version (e.g. GEC02).
sec.boot_version=GCJDJJAA
# Security black plug mcode id string (e.g. GQC02JAA).
sec.black_plug_mcode=GCJDJJA
sec.black_plug_mcode=GCJDJJAA

View File

@@ -7,4 +7,4 @@ if not exist dev\nvram\coin.xml copy prop\defaults\coin.xml dev\nvram\coin.xml
if not exist dev\nvram\eacoin.xml copy prop\defaults\eacoin.xml dev\nvram\eacoin.xml
if not exist dev\raw mkdir dev\raw
launcher -H 33554432 -K jbhook2.dll jubeat.dll
launcher -H 33554432 -K jbhook2.dll jubeat.dll -v

View File

@@ -2,7 +2,7 @@
gfx.windowed=false
# rotate the normally-horizontal game window to be vertical
gfx.vertical=false
gfx.vertical=true
# URL (e.g. http://my.eamuse.server:80/whatever) or IPV4 (e.g. 127.0.0.1:80) of the target eamuse server. The port is optional but defaults to 80.
eamuse.server=localhost:80

View File

@@ -2,7 +2,7 @@
gfx.windowed=false
# rotate the normally-horizontal game window to be vertical
gfx.vertical=false
gfx.vertical=true
# URL (e.g. http://my.eamuse.server:80/whatever) or IPV4 (e.g. 127.0.0.1:80) of the target eamuse server. The port is optional but defaults to 80.
eamuse.server=localhost:80

View File

@@ -16,6 +16,9 @@
static struct security_mcode ezusb_iidx_emu_node_security_plug_boot_version;
static uint32_t ezusb_iidx_emu_node_security_plug_boot_seeds[3];
static struct security_rp_sign_key ezusb_iidx_emu_node_security_plug_black_sign_key;
static struct security_rp_sign_key ezusb_iidx_emu_node_security_plug_white_sign_key;
static struct security_mcode ezusb_iidx_emu_node_security_plug_black_mcode;
static struct security_mcode ezusb_iidx_emu_node_security_plug_white_mcode;
@@ -62,6 +65,28 @@ void ezusb_iidx_emu_node_security_plug_set_boot_seeds(const uint32_t *seeds)
sizeof(ezusb_iidx_emu_node_security_plug_boot_seeds));
}
void ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
const struct security_rp_sign_key *sign_key)
{
log_misc("black sign key: %s", sign_key->data);
memcpy(
&ezusb_iidx_emu_node_security_plug_black_sign_key,
sign_key,
sizeof(struct security_rp_sign_key));
}
void ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
const struct security_rp_sign_key *sign_key)
{
log_misc("white sign key: %s", sign_key->data);
memcpy(
&ezusb_iidx_emu_node_security_plug_white_sign_key,
sign_key,
sizeof(struct security_rp_sign_key));
}
void ezusb_iidx_emu_node_security_plug_set_plug_black_mcode(
const struct security_mcode *mcode)
{
@@ -373,7 +398,7 @@ bool ezusb_iidx_emu_node_security_plug_read_packet_v2(
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&ezusb_iidx_emu_node_security_plug_boot_version,
&ezusb_iidx_emu_node_security_plug_black_sign_key,
&ezusb_iidx_emu_node_security_plug_black_mcode,
&ezusb_iidx_emu_node_security_plug_pcbid,
(struct security_rp2_eeprom *) pkg->payload);
@@ -415,7 +440,7 @@ bool ezusb_iidx_emu_node_security_plug_read_packet_v2(
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&ezusb_iidx_emu_node_security_plug_boot_version,
&ezusb_iidx_emu_node_security_plug_white_sign_key,
&ezusb_iidx_emu_node_security_plug_white_mcode,
&ezusb_iidx_emu_node_security_plug_eamid,
(struct security_rp2_eeprom *) pkg->payload);

View File

@@ -5,6 +5,7 @@
#include "security/id.h"
#include "security/mcode.h"
#include "security/rp-sign-key.h"
/**
* Set the boot version of the game. The boot version mcode is used for
@@ -23,6 +24,22 @@ void ezusb_iidx_emu_node_security_plug_set_boot_version(
*/
void ezusb_iidx_emu_node_security_plug_set_boot_seeds(const uint32_t *seeds);
/**
* Set the signing key for the black dongle.
*
* @param sign_key Pointer to the black dongle sign key.
*/
void ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
const struct security_rp_sign_key *sign_key);
/**
* Set the signing key for the white dongle.
*
* @param sign_key Pointer to the white dongle sign key.
*/
void ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
const struct security_rp_sign_key *sign_key);
/**
* The mcode of the target game to boot. This mcode is typically printed onto
* the black plug corresponding to the game to boot.

View File

@@ -38,6 +38,8 @@
#include "iidxhook-util/eamuse.h"
#include "iidxhook-util/settings.h"
#include "security/rp-sign-key.h"
#include "util/log.h"
#include "util/str.h"
#include "util/thread.h"
@@ -163,6 +165,10 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
ezusb_iidx_emu_node_security_plug_set_boot_version(
&config_sec.boot_version);
ezusb_iidx_emu_node_security_plug_set_boot_seeds(config_sec.boot_seeds);
ezusb_iidx_emu_node_security_plug_set_plug_black_sign_key(
&security_rp_sign_key_black_iidx);
ezusb_iidx_emu_node_security_plug_set_plug_white_sign_key(
&security_rp_sign_key_white_eamuse);
ezusb_iidx_emu_node_security_plug_set_plug_black_mcode(
&config_sec.black_plug_mcode);
ezusb_iidx_emu_node_security_plug_set_plug_white_mcode(
@@ -235,7 +241,7 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
{
if (reason == DLL_PROCESS_ATTACH) {
log_to_writer(log_writer_debug, NULL);
/* Bootstrap hook for further init tasks (see above) */
hook_table_apply(

View File

@@ -0,0 +1,6 @@
libs += jbhook-util-p3io
src_jbhook-util-p3io := \
gfx.c \
mixer.c \
p3io.c \

View File

@@ -14,7 +14,7 @@
#include "imports/glhelper.h"
#include "jbhook-util/gfx.h"
#include "jbhook-util-p3io/gfx.h"
#include "util/defs.h"
#include "util/log.h"
@@ -47,71 +47,6 @@ static const struct hook_symbol jbhook_infodisp_hook_syms[] = {
.patch = hook_infodispcore_set_angle},
};
static DWORD STDCALL my_GetGlyphOutline(
HDC hdc,
UINT uChar,
UINT uFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpvBuffer,
const MAT2 *lpmat2);
static DWORD(STDCALL *real_GetGlyphOutline)(
HDC hdc,
UINT uChar,
UINT uFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpvBuffer,
const MAT2 *lpmat2);
static const struct hook_symbol gfx_hook_syms[] = {
{.name = "GetGlyphOutlineA",
.patch = my_GetGlyphOutline,
.link = (void **) &real_GetGlyphOutline},
{
.name = "IsDBCSLeadByteEx",
.patch = my_GetGlyphOutline, // !??
.link = (void **) &real_GetGlyphOutline // !??
},
};
static DWORD STDCALL my_GetGlyphOutline(
HDC hdc,
UINT uChar,
UINT uFormat,
LPGLYPHMETRICS lpgm,
DWORD cbBuffer,
LPVOID lpvBuffer,
const MAT2 *lpmat2)
{
if (IsDBCSLeadByteEx(CP_ACP, uChar & 0xFF)) {
log_warning("!!!!!!!!");
char tmp[2];
tmp[0] = uChar & 0xFF;
tmp[1] = (uChar >> 8) & 0xFF;
MultiByteToWideChar(
CP_ACP, MB_USEGLYPHCHARS, tmp, 2, lpvBuffer, cbBuffer);
}
return real_GetGlyphOutline(
hdc, uChar, uFormat, lpgm, cbBuffer, lpvBuffer, lpmat2);
}
void jbhook_util_gfx_hook_init(void)
{
hook_table_apply(NULL, "gdi32.dll", gfx_hook_syms, lengthof(gfx_hook_syms));
log_info("Inserted gfx hooks");
}
void jbhook_util_gfx_set_windowed(bool framed)
{
}
void jbhook_util_gfx_install_vertical_hooks(void) {
hook_table_apply(
NULL,

View File

@@ -0,0 +1,4 @@
/**
* Rotate a horizontal-by-default jubeat window to vertical
*/
void jbhook_util_gfx_install_vertical_hooks(void);

View File

@@ -5,7 +5,7 @@
#include "bemanitools/jbio.h"
#include "jbhook-util/p3io.h"
#include "jbhook-util-p3io/p3io.h"
#include "p3ioemu/emu.h"
#include "p3ioemu/uart.h"

View File

@@ -6,8 +6,5 @@ libs_jbhook-util := \
src_jbhook-util := \
acio.c \
eamuse.c \
gfx.c \
mixer.c \
locale.c \
p3io.c \
p4io.c \

View File

@@ -1,25 +0,0 @@
#ifndef JBHOOK_D3D8_H
#define JBHOOK_D3D8_H
#include <stdbool.h>
/**
* Hook some gfx related functions to patch gfx related stuff
* like enabling window mode.
*/
void jbhook_util_gfx_hook_init(void);
/**
* Set the game to window mode.
*
* @param framed True to add a window frame and make the window
* movable, resizable, minizable. False for no frame.
*/
void jbhook_util_gfx_set_windowed(bool framed);
/**
* Rotate a horizontal-by-default jubeat window to vertical
*/
void jbhook_util_gfx_install_vertical_hooks(void);
#endif

View File

@@ -2,7 +2,7 @@ avsdlls += jbhook1
imps += glhelper
deplibs_jbhook1 := \
avs \
avs \
glhelper \
ldflags_jbhook1 := \
@@ -15,7 +15,8 @@ libs_jbhook1 := \
cconfig \
eamio \
jbio \
jbhook-util \
jbhook-util \
jbhook-util-p3io \
p3ioemu \
p3io \
hook \

View File

@@ -24,9 +24,10 @@
#include "jbhook-util/acio.h"
#include "jbhook-util/eamuse.h"
#include "jbhook-util/gfx.h"
#include "jbhook-util/mixer.h"
#include "jbhook-util/p3io.h"
#include "jbhook-util-p3io/gfx.h"
#include "jbhook-util-p3io/mixer.h"
#include "jbhook-util-p3io/p3io.h"
#include "p3ioemu/devmgr.h"
#include "p3ioemu/emu.h"

View File

@@ -14,6 +14,7 @@ libs_jbhook2 := \
eamio \
jbio \
jbhook-util \
jbhook-util-p3io \
p3ioemu \
p3io \
p4ioemu \

View File

@@ -22,8 +22,9 @@
#include "jbhook-util/acio.h"
#include "jbhook-util/eamuse.h"
#include "jbhook-util/gfx.h"
#include "jbhook-util/p3io.h"
#include "jbhook-util-p3io/gfx.h"
#include "jbhook-util-p3io/p3io.h"
#include "p3ioemu/devmgr.h"
#include "p3ioemu/emu.h"
@@ -40,15 +41,6 @@
static struct options options;
static const struct security_mcode security_mcode_j44 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_C,
.game = SECURITY_MCODE_GAME_JB_3,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_C,
.revision = SECURITY_MCODE_REVISION_A,
};
static bool my_dll_entry_init(char *sidcode, struct property_node *param)
{
bool eam_io_ok;
@@ -59,6 +51,8 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
log_info("--- Begin jbhook dll_entry_init ---");
log_assert(sidcode != NULL);
if(options.vertical) {
jbhook_util_gfx_install_vertical_hooks();
}
@@ -67,12 +61,20 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
iohook_push_handler(p3io_emu_dispatch_irp);
p3io_setupapi_insert_hooks(NULL);
log_assert(sidcode != NULL);
// pcbid and eamid are only used here for sec check, the ones used for
// network access are taken from ea3-config.xml.
// When booting knit append (and on no other version), the code must
// actually match, so the ID used is for append (JCA)
// actually match, so we use the one from ea3-config as well.
// Example sidcode format: `K44JBA2012072301`
struct security_mcode security_mcode_j44 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_C,
.game = {sidcode[0], sidcode[1], sidcode[2]},
.region = sidcode[3],
.cabinet = sidcode[4],
.revision = sidcode[5],
};
jbhook_util_p3io_init(
&security_mcode_j44,
&security_id_default, &security_id_default);
@@ -111,8 +113,22 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
log_info("--- End jbhook dll_entry_init ---");
char *sidcode_in_ea3_config = strdup(sidcode);
bool ret = app_hook_invoke_init(sidcode, param);
// If the game is append, the mcode `cabinet` is forced to C. This is bad if
// p3io was configured to respond as A! Help the user help themsevles...
if(strcmp(sidcode_in_ea3_config, sidcode) != 0) {
log_warning("sidcode changed after running game DLL init (%s -> %s)", sidcode_in_ea3_config, sidcode);
log_warning("This will trigger a security error. Modify ea3-config.xml <soft> section to match the second value!");
// abort the boot
return false;
}
free(sidcode_in_ea3_config);
return ret;
fail:
@@ -183,6 +199,10 @@ static HWND CDECL my_mwindow_create(
window_height = tmp;
}
if(options.show_cursor) {
ShowCursor(TRUE);
}
fullscreen = !options.windowed;
return real_mwindow_create(
@@ -214,7 +234,6 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
adapter_hook_init();
}
jbhook_util_gfx_hook_init();
jbhook_util_eamuse_hook_init();
return TRUE;

View File

@@ -34,10 +34,10 @@ void options_init_from_cmdline(struct options *options)
void options_init(struct options *options)
{
options->windowed = false;
options->window_framed = false;
options->disable_p3ioemu = false;
options->disable_cardemu = false;
options->disable_adapteremu = false;
options->show_cursor = false;
}
bool options_read_cmdline(struct options *options, int argc, const char **argv)
@@ -60,11 +60,6 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv)
break;
}
case 'f': {
options->window_framed = true;
break;
}
case 'v': {
options->vertical = true;
break;
@@ -84,6 +79,11 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv)
options->disable_p3ioemu = true;
break;
}
case 's': {
options->show_cursor = true;
break;
}
}
}
@@ -106,7 +106,8 @@ void options_print_usage(void)
" -c Disable card emulation (e.g. when running on a "
"real cab)\n"
" -p Disable p3io emulation (e.g. when running on a "
"real cab)\n");
"real cab)\n"
" -s Show mouse cursor on game window\n");
}
void options_fini(struct options *options)

View File

@@ -6,11 +6,11 @@
struct options {
bool windowed;
bool window_framed;
bool vertical;
bool disable_p3ioemu;
bool disable_cardemu;
bool disable_adapteremu;
bool show_cursor;
};
void options_init_from_cmdline(struct options *options);

View File

@@ -22,4 +22,5 @@ libs_jbhook3 := \
src_jbhook3 := \
dllmain.c \
gfx.c \
options.c

View File

@@ -9,6 +9,7 @@
#include "bemanitools/jbio.h"
#include "hook/iohook.h"
#include "hook/table.h"
#include "hooklib/adapter.h"
#include "hooklib/app.h"
@@ -17,11 +18,11 @@
#include "imports/avs.h"
#include "jbhook3/gfx.h"
#include "jbhook3/options.h"
#include "jbhook-util/acio.h"
#include "jbhook-util/eamuse.h"
#include "jbhook-util/gfx.h"
#include "jbhook-util/p4io.h"
#include "p4ioemu/device.h"
@@ -48,6 +49,16 @@ static bool my_dll_entry_init(char *sidcode, struct property_node *param)
iohook_push_handler(p4ioemu_dispatch_irp);
iohook_push_handler(jbhook_util_ac_io_port_dispatch_irp);
jbhook3_gfx_init();
if(options.windowed) {
jbhook3_gfx_set_windowed();
}
if(options.show_cursor) {
jbhook3_gfx_set_show_cursor();
}
if (!options.disable_p4ioemu) {
log_info("Starting up jubeat IO backend");
@@ -120,7 +131,7 @@ static bool my_dll_entry_main(void)
if (!options.disable_p4ioemu) {
p4ioemu_fini();
}
options_fini(&options);
return result;
@@ -142,8 +153,7 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
if (!options.disable_adapteremu) {
adapter_hook_init();
}
jbhook_util_gfx_hook_init();
jbhook_util_eamuse_hook_init();
return TRUE;

73
src/main/jbhook3/gfx.c Normal file
View File

@@ -0,0 +1,73 @@
#define LOG_MODULE "jbhook-gfx"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hook/table.h"
#include "jbhook3/options.h"
#include "util/log.h"
static bool jbhook3_gfx_windowed;
static bool jbhook3_gfx_show_cursor;
void jbhook3_gfx_set_windowed(void)
{
jbhook3_gfx_windowed = true;
}
void jbhook3_gfx_set_show_cursor(void)
{
jbhook3_gfx_show_cursor = true;
}
static HWND CDECL my_GFWin32MainWindowRun(
HINSTANCE,
const char *,
long,
long,
DWORD);
static HWND(CDECL *real_GFWin32MainWindowRun)(
HINSTANCE,
const char *,
long,
long,
DWORD);
static const struct hook_symbol init_hook_syms[] = {
{.name = "GFWin32MainWindowRun",
.patch = my_GFWin32MainWindowRun,
.link = (void **) &real_GFWin32MainWindowRun,},
};
static HWND CDECL my_GFWin32MainWindowRun(
HINSTANCE hInstance,
const char *lpWindowName,
long X,
long Y,
DWORD dwStyle
)
{
if(jbhook3_gfx_windowed) {
log_info("--- Begin jbhook GFWin32MainWindowRun ---");
dwStyle |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE;
}
if(jbhook3_gfx_show_cursor) {
ShowCursor(TRUE);
}
return real_GFWin32MainWindowRun(hInstance, lpWindowName, X, Y, dwStyle);
}
void jbhook3_gfx_init(void)
{
hook_table_apply(
NULL, "gftools.dll", init_hook_syms, lengthof(init_hook_syms));
log_info("Inserted gfx hooks");
}

3
src/main/jbhook3/gfx.h Normal file
View File

@@ -0,0 +1,3 @@
void jbhook3_gfx_init(void);
void jbhook3_gfx_set_windowed(void);
void jbhook3_gfx_set_show_cursor(void);

View File

@@ -34,10 +34,10 @@ void options_init_from_cmdline(struct options *options)
void options_init(struct options *options)
{
options->windowed = false;
options->window_framed = false;
options->disable_p4ioemu = false;
options->disable_cardemu = false;
options->disable_adapteremu = false;
options->show_cursor = false;
}
bool options_read_cmdline(struct options *options, int argc, const char **argv)
@@ -60,11 +60,6 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv)
break;
}
case 'f': {
options->window_framed = true;
break;
}
case 'a': {
options->disable_adapteremu = true;
break;
@@ -79,6 +74,11 @@ bool options_read_cmdline(struct options *options, int argc, const char **argv)
options->disable_p4ioemu = true;
break;
}
case 's': {
options->show_cursor = true;
break;
}
}
}
@@ -95,13 +95,13 @@ void options_print_usage(void)
"\n"
" -h Print this usage message\n"
" -w Run the game windowed\n"
" -f Run the game in a framed window (needs -w option)\n"
" -a Disable adapter hook\n"
" -c Disable card emulation (e.g. when running on a "
"real cab)\n"
" -p Disable p4io emulation (e.g. when running on a "
"real cab or on a bare "
"p4io)\n");
"p4io)\n"
" -s Show mouse cursor on game window\n");
}
void options_fini(struct options *options)

View File

@@ -6,10 +6,10 @@
struct options {
bool windowed;
bool window_framed;
bool disable_p4ioemu;
bool disable_cardemu;
bool disable_adapteremu;
bool show_cursor;
};
void options_init_from_cmdline(struct options *options);

View File

@@ -53,6 +53,15 @@
#define SECURITY_MCODE_GAME_JB_1 "H44"
#define SECURITY_MCODE_GAME_JB_3 "J44"
/* DDR */
#define SECURITY_MCODE_GAME_DDR_X "HDX"
/* pop'n music */
#define SECURITY_MCODE_GAME_POPN_15 "G15"
#define SECURITY_MCODE_GAME_POPN_16 "H16"
#define SECURITY_MCODE_GAME_POPN_17 "I17"
#define SECURITY_MCODE_GAME_POPN_18 "J39"
/* Region */
#define SECURITY_MCODE_REGION_ASIA 'A'
#define SECURITY_MCODE_REGION_JAPAN 'J'

View File

@@ -3,8 +3,20 @@
const struct security_rp_sign_key security_rp_sign_key_white_eamuse = {
.data = "E-AMUSE3"};
const struct security_rp_sign_key security_rp_sign_key_black_ps2 = {
const struct security_rp_sign_key security_rp_sign_key_black_python2 = {
.data = "GENTAKAH"};
const struct security_rp_sign_key security_rp_sign_key_black_gfdmv4 = {
.data = "UDONHRKI"};
.data = "UDONHRKI"};
const struct security_rp_sign_key security_rp_sign_key_black_gfdmv8 = {
.data = "SHAMOSAN"};
const struct security_rp_sign_key security_rp_sign_key_black_ddrx = {
.data = "573PROJE"};
const struct security_rp_sign_key security_rp_sign_key_black_iidx = {
.data = "2DXGLDAC"};
const struct security_rp_sign_key security_rp_sign_key_black_popn = {
.data = "POPNG15A"};

View File

@@ -11,23 +11,55 @@ struct security_rp_sign_key {
};
/**
* Signing key used to create eeprom signitures for all white eamuse dongles.
* Signing key used to create eeprom signatures for all white eamuse dongles
*/
extern const struct security_rp_sign_key security_rp_sign_key_white_eamuse;
/**
* Signing key used to create eeprom signitures for all black dongles used
* on PS2 games (as far as we are aware of).
* Signing key used to create eeprom signatures for all black dongles used
* on Python 2 games.
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_ps2;
extern const struct security_rp_sign_key security_rp_sign_key_black_python2;
/**
* Signing key used to create eeprom signitures for all black dongles used
* Signing key used to create eeprom signatures for all black dongles used
* on the following games:
*
* - GF & DM V4 to V8 (TODO needs verification)
* - GF & DM V4 to V7
* - jubeat (1)
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_gfdmv4;
/**
* Signing key used to create eeprom signatures for all black dongles used
* on the following games:
*
* - GF & DM V8, XG to XG3, Gitadora series
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_gfdmv8;
/**
* Signing key used to create eeprom signatures for all black dongles used
* on the following games:
*
* - DDR X
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_ddrx;
/**
* Signing key used to create eeprom signatures for all black dongles used
* on the following games:
*
* - IIDX 14 to 17
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_iidx;
/**
* Signing key used to create eeprom signatures for all black dongles used
* on the following games:
*
* - pop'n music 15 to 17
*/
extern const struct security_rp_sign_key security_rp_sign_key_black_popn;
#endif

View File

@@ -10,7 +10,7 @@
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* dongle. This contains a signature to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp_eeprom {

View File

@@ -1,15 +1,12 @@
#include <string.h>
#include "security/rp2.h"
#include "security/rp-util.h"
#include "security/util.h"
#include "util/crypto.h"
#include "util/log.h"
static const uint8_t security_rp2_sign_key_base_black[] = {
0x32, 0x44, 0x58, 0x47, 0x4C, 0x44, 0x41, 0x43};
static const uint8_t security_rp2_sign_key_base_white[] = {
0x45, 0x2D, 0x41, 0x4D, 0x55, 0x53, 0x45, 0x33};
static uint8_t security_rp2_signature_scramble_table[16] = {0x0C,
0x02,
0x0F,
@@ -27,7 +24,7 @@ static uint8_t security_rp2_signature_scramble_table[16] = {0x0C,
0x08,
0x06};
static void security_rp2_create_signiture(
void security_rp2_create_signature(
const uint8_t *plug_id_enc, const uint8_t *sign_key_packed, uint8_t *out)
{
uint8_t data[14];
@@ -53,70 +50,51 @@ static void security_rp2_create_signiture(
}
}
void security_rp2_generate_signed_eeprom_data_core(
const uint8_t *sign_key,
const uint8_t *plug_mcode,
const uint8_t *plug_id,
uint8_t *signature,
uint8_t *packed_payload)
{
uint8_t sign_key_tmp[8];
security_util_8_to_6_encode(sign_key, sign_key_tmp);
security_rp2_create_signature(plug_id, sign_key_tmp, signature);
security_util_8_to_6_encode(plug_mcode, packed_payload);
}
void security_rp2_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_mcode *boot_version,
const struct security_rp_sign_key *sign_key,
const struct security_mcode *plug_mcode,
const struct security_id *plug_id,
struct security_rp2_eeprom *out)
{
uint8_t sign_key[8];
uint8_t sign_key_tmp[8];
uint8_t plug_id_enc[8];
char *boot_version_str;
const uint8_t *plug_mcode_raw = (const uint8_t *) plug_mcode;
log_assert(boot_version);
log_assert(sign_key);
log_assert(plug_mcode);
log_assert(plug_id);
log_assert(out);
boot_version_str = (char *) boot_version;
for (int i = 0; i < sizeof(sign_key_tmp); i++) {
sign_key_tmp[i] = sign_key->data[i] ^ 0x40;
/* -------------------------------- */
switch (type) {
case SECURITY_RP_UTIL_RP_TYPE_BLACK:
memcpy(
sign_key, security_rp2_sign_key_base_black, sizeof(sign_key));
sign_key[0] = boot_version_str[0] ^ sign_key[0];
sign_key[1] ^= boot_version_str[1];
sign_key[2] = boot_version_str[2] ^ sign_key[2];
sign_key[3] = boot_version_str[3] ^ sign_key[3];
sign_key[4] = boot_version_str[4] ^ sign_key[4];
sign_key[5] ^= boot_version_str[5];
sign_key[6] = boot_version_str[6] ^ sign_key[6];
sign_key[7] = boot_version_str[7] ^ sign_key[7];
break;
case SECURITY_RP_UTIL_RP_TYPE_WHITE:
memcpy(
sign_key, security_rp2_sign_key_base_white, sizeof(sign_key));
break;
default:
log_assert(false);
break;
if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) {
sign_key_tmp[i] ^= plug_mcode_raw[i];
}
}
for (uint8_t i = 0; i < sizeof(sign_key); i++) {
sign_key[i] ^= 0x40;
}
security_util_8_to_6_encode(sign_key, sign_key);
plug_id_enc[0] = plug_id->checksum;
plug_id_enc[1] = plug_id->id[2];
plug_id_enc[2] = plug_id->id[3];
plug_id_enc[3] = plug_id->id[4];
plug_id_enc[4] = plug_id->id[5];
plug_id_enc[5] = plug_id->id[6];
plug_id_enc[6] = plug_id->id[7];
memcpy(&plug_id_enc[1], &plug_id->id[2], 6);
plug_id_enc[7] = plug_id->id[1];
security_rp2_create_signiture(plug_id_enc, sign_key, (uint8_t *) out);
security_util_8_to_6_encode(
(const uint8_t *) plug_mcode, out->packed_payload);
}
security_rp2_generate_signed_eeprom_data_core(
sign_key_tmp,
plug_mcode_raw,
plug_id_enc,
out->signature,
out->packed_payload);
}

View File

@@ -6,11 +6,12 @@
#include "security/id.h"
#include "security/mcode.h"
#include "security/rp-sign-key.h"
#include "security/rp-util.h"
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* dongle. This contains a signature to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp2_eeprom {
@@ -18,6 +19,24 @@ struct security_rp2_eeprom {
uint8_t packed_payload[6];
};
/**
* This is the core of the algorithm shared between rp2 and rp3 dongles.
* The keys passed to this function are assumed to already be mutated
* as required.
*
* @param sign_key The key to use for generating the signature.
* @param plug_mcode The mcode of the game to boot.
* @param plug_id The id stored on the plug.
* @param signature Pointer to the signature buffer for the resulting data.
* @param packed_payload Pointer to the payload buffer for the resulting data.
*/
void security_rp2_generate_signed_eeprom_data_core(
const uint8_t *sign_key,
const uint8_t *plug_mcode,
const uint8_t *plug_id,
uint8_t *signature,
uint8_t *packed_payload);
/**
* Generate signed eeprom data from non encrypted and unobfuscated data required
* to pass security checks on games using black (game specific) and white
@@ -25,10 +44,12 @@ struct security_rp2_eeprom {
*
* This implementation (rp 2) is used by the following games
* - iidx 14 to 17
* - pop'n music 15 to 18
*
* @param type Type of plug to sign eeprom data for (black or white).
* @param boot_version The boot version mcode that is used for bootstrapping
* the security backend (of the ezusb.dll).
* @param sign_key The key to use for generating the signature.
* This key can be extracted from the executables of the games and might
* be re-used for multiple games of the same series or generation.
* @param plug_mcode The mcode of the game to boot. Typically, this code is
* printed onto the housing of the black dongle. For white
* dongles, the "mcode" @@@@@@@@ is used.
@@ -39,7 +60,7 @@ struct security_rp2_eeprom {
*/
void security_rp2_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_mcode *boot_version,
const struct security_rp_sign_key *sign_key,
const struct security_mcode *plug_mcode,
const struct security_id *plug_id,
struct security_rp2_eeprom *out);

View File

@@ -1,54 +1,13 @@
#include <string.h>
#include "security/rp2.h"
#include "security/rp3.h"
#include "security/rp-util.h"
#include "security/util.h"
#include "util/crc.h"
#include "util/crypto.h"
#include "util/log.h"
static uint8_t security_rp3_signature_scramble_table[] = {0x0C,
0x02,
0x0F,
0x01,
0x07,
0x09,
0x04,
0x0A,
0x00,
0x0E,
0x03,
0x0D,
0x0B,
0x05,
0x08,
0x06};
static void security_rp3_create_signature(
const uint8_t *plug_id, const uint8_t *sign_key_packed, uint8_t *out)
{
uint8_t data[14];
uint8_t md5[16];
uint8_t buffer[18];
memcpy(data, plug_id, 8);
memcpy(data + 8, sign_key_packed, 6);
crypto_init();
md5_compute(data, 14, md5, sizeof(md5));
crypto_fini();
for (int i = 0; i < 16; i++) {
buffer[i] = md5[security_rp3_signature_scramble_table[i]];
}
buffer[16] = 0xDE;
buffer[17] = 0xAD;
for (int i = 0; i < 6; i++) {
out[i] = buffer[i + 12] ^ buffer[i + 6] ^ buffer[i];
}
}
void security_rp3_generate_signed_eeprom_data(
enum security_rp_util_rp_type type,
const struct security_rp_sign_key *sign_key,
@@ -57,8 +16,8 @@ void security_rp3_generate_signed_eeprom_data(
struct security_rp3_eeprom *out)
{
uint8_t sign_key_tmp[8];
uint8_t sign_key_packed[6];
uint8_t plug_id_reversed[8];
const uint8_t *plug_mcode_raw = (const uint8_t *) plug_mcode;
log_assert(sign_key);
log_assert(plug_mcode);
@@ -66,24 +25,23 @@ void security_rp3_generate_signed_eeprom_data(
log_assert(out);
memcpy(sign_key_tmp, sign_key, sizeof(sign_key_tmp));
if (type == SECURITY_RP_UTIL_RP_TYPE_BLACK) {
for (int i = 0; i < sizeof(sign_key_tmp); i++) {
sign_key_tmp[i] ^= ((const uint8_t *) plug_mcode)[i];
sign_key_tmp[i] ^= plug_mcode_raw[i];
}
}
security_util_8_to_6_encode(sign_key_tmp, sign_key_packed);
for (int i = 0; i < sizeof(plug_id_reversed); i++) {
plug_id_reversed[i] = plug_id->id[7 - i];
}
security_util_8_to_6_encode(
(const uint8_t *) plug_mcode, out->packed_payload);
memset(out->zeros, 0, sizeof(out->zeros));
security_rp2_generate_signed_eeprom_data_core(
sign_key_tmp,
plug_mcode_raw,
plug_id_reversed,
out->signature,
out->packed_payload);
security_rp3_create_signature(
plug_id_reversed, sign_key_packed, out->signature);
memset(out->zeros, 0, sizeof(out->zeros));
out->crc = crc8((uint8_t *) out, sizeof(*out) - 1, 0);
}

View File

@@ -11,7 +11,7 @@
/**
* Structure for data which is usually stored in the eeprom section of the
* dongle. This contains a signiture to verify the ROM's contents as well as
* dongle. This contains a signature to verify the ROM's contents as well as
* the game this dongle is signed for.
*/
struct security_rp3_eeprom {
@@ -26,11 +26,16 @@ struct security_rp3_eeprom {
* to pass security checks on games using black (game specific) and white
* (eamuse) roundplugs.
*
* Algorithm is the same as RP2 but plug ID is handled in reverse order
* and response has additional padding + checksum at the end of the message.
*
* Used on the following games:
* - jubeat
* - jubeat series
* - DDR series
* - GFDM V series, XG series, Gitadora series
*
* @param type Type of plug to sign eeprom data for (black or white).
* @param sign_key The key to use for generating the signiture.
* @param sign_key The key to use for generating the signature.
* This key can be extracted from the executables of the games and might
* be re-used for multiple games of the same series or generation.
* @param plug_mcode The mcode of the game to boot. Typically, this code is

View File

@@ -1,52 +1,17 @@
#include "security/id.h"
#include "security/rp2.h"
#include "security/rp-sign-key.h"
#include "test/check.h"
#include "test/test.h"
static const struct security_mcode boot_version_iidx_14 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_Q,
.game = SECURITY_MCODE_GAME_IIDX_14,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode boot_version_iidx_15 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_Q,
.game = SECURITY_MCODE_GAME_IIDX_15,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode boot_version_iidx_16 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_Q,
.game = SECURITY_MCODE_GAME_IIDX_16,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode boot_version_iidx_17 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_C,
.game = SECURITY_MCODE_GAME_IIDX_17,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode black_plug_mcode_iidx_14 = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_Q,
.game = SECURITY_MCODE_GAME_IIDX_14,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_FIELD_NULL,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode black_plug_mcode_iidx_15 = {
@@ -55,7 +20,7 @@ static const struct security_mcode black_plug_mcode_iidx_15 = {
.game = SECURITY_MCODE_GAME_IIDX_15,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_FIELD_NULL,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode black_plug_mcode_iidx_16 = {
@@ -64,7 +29,7 @@ static const struct security_mcode black_plug_mcode_iidx_16 = {
.game = SECURITY_MCODE_GAME_IIDX_16,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_FIELD_NULL,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_mcode black_plug_mcode_iidx_17 = {
@@ -73,27 +38,27 @@ static const struct security_mcode black_plug_mcode_iidx_17 = {
.game = SECURITY_MCODE_GAME_IIDX_17,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_FIELD_NULL,
.revision = SECURITY_MCODE_REVISION_A,
};
static const struct security_rp2_eeprom exp_iidx_14_black_eeprom = {
.signature = {0x17, 0xC6, 0x2B, 0x6A, 0xDA, 0x29},
.packed_payload = {0x67, 0x7C, 0xB2, 0xA4, 0x1A, 0x82},
.packed_payload = {0x67, 0x7C, 0xB2, 0xA4, 0x1A, 0x86},
};
static const struct security_rp2_eeprom exp_iidx_15_black_eeprom = {
.signature = {0xCE, 0xF8, 0xC7, 0xEF, 0xA6, 0xDF},
.packed_payload = {0x67, 0x8C, 0x92, 0xA4, 0x1A, 0x82},
.packed_payload = {0x67, 0x8C, 0x92, 0xA4, 0x1A, 0x86},
};
static const struct security_rp2_eeprom exp_iidx_16_black_eeprom = {
.signature = {0xE0, 0x58, 0xDA, 0xE4, 0x61, 0xF9},
.packed_payload = {0x67, 0x9C, 0x42, 0x90, 0x1A, 0x82},
.packed_payload = {0x67, 0x9C, 0x42, 0x90, 0x1A, 0x86},
};
static const struct security_rp2_eeprom exp_iidx_17_black_eeprom = {
.signature = {0xC3, 0x4B, 0xF8, 0xAA, 0xC1, 0x3E},
.packed_payload = {0xE7, 0xA8, 0x92, 0xAA, 0x1A, 0x82},
.packed_payload = {0xE7, 0xA8, 0x92, 0xAA, 0x1A, 0x86},
};
static const struct security_rp2_eeprom exp_iidx_14_white_eeprom = {
@@ -122,7 +87,7 @@ static void test_encode_iidx_14_black_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&boot_version_iidx_14,
&security_rp_sign_key_black_iidx,
&black_plug_mcode_iidx_14,
&security_id_default,
&result);
@@ -140,7 +105,7 @@ static void test_encode_iidx_14_white_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&boot_version_iidx_14,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&security_id_default,
&result);
@@ -158,7 +123,7 @@ static void test_encode_iidx_15_black_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&boot_version_iidx_15,
&security_rp_sign_key_black_iidx,
&black_plug_mcode_iidx_15,
&security_id_default,
&result);
@@ -176,7 +141,7 @@ static void test_encode_iidx_15_white_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&boot_version_iidx_15,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&security_id_default,
&result);
@@ -194,7 +159,7 @@ static void test_encode_iidx_16_black_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&boot_version_iidx_16,
&security_rp_sign_key_black_iidx,
&black_plug_mcode_iidx_16,
&security_id_default,
&result);
@@ -212,7 +177,7 @@ static void test_encode_iidx_16_white_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&boot_version_iidx_16,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&security_id_default,
&result);
@@ -230,7 +195,7 @@ static void test_encode_iidx_17_black_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK,
&boot_version_iidx_17,
&security_rp_sign_key_black_iidx,
&black_plug_mcode_iidx_17,
&security_id_default,
&result);
@@ -248,7 +213,7 @@ static void test_encode_iidx_17_white_dongle()
security_rp2_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE,
&boot_version_iidx_17,
&security_rp_sign_key_white_eamuse,
&security_mcode_eamuse,
&security_id_default,
&result);