diff --git a/dist/config.toml b/dist/config.toml index 7a68a0a..8a5e5de 100644 --- a/dist/config.toml +++ b/dist/config.toml @@ -1,5 +1,9 @@ [amauth] server = "127.0.0.1" +port = "54430" +chassis_id = "000000000000" +shop_id = "TAIKO ARCADE LOADER" +game_ver = "00.00" [patches] version = "auto" diff --git a/meson.build b/meson.build index 999d809..9c0f8c0 100644 --- a/meson.build +++ b/meson.build @@ -56,6 +56,7 @@ library( 'src/bnusio.cpp', 'src/patches/jp_nov_2020.cpp', 'src/patches/cn_jun_2023.cpp', + 'src/patches/jp_apr_2023.cpp', 'src/patches/amauth.cpp', 'src/patches/qr.cpp', ], diff --git a/src/constants.h b/src/constants.h index 007f48d..e3ec9c4 100644 --- a/src/constants.h +++ b/src/constants.h @@ -5,4 +5,5 @@ enum class GameVersion : XXH64_hash_t { UNKNOWN = 0, JP_NOV_2020 = 0x67C0F3042746D488, CN_JUN_2023 = 0xA7EE39F2CC2C57C8, + JP_APR_2023 = 0x49F643ADB6B18705, }; \ No newline at end of file diff --git a/src/dllmain.cpp b/src/dllmain.cpp index e52732d..d317bfc 100644 --- a/src/dllmain.cpp +++ b/src/dllmain.cpp @@ -7,11 +7,15 @@ GameVersion gameVersion = GameVersion::UNKNOWN; std::vector plugins; -const char *server = "127.0.0.1"; -char accessCode1[21] = "00000000000000000001"; -char accessCode2[21] = "00000000000000000002"; -char chipId1[33] = "00000000000000000000000000000001"; -char chipId2[33] = "00000000000000000000000000000002"; +const char *server = "127.0.0.1"; +const char *port = "54430"; +const char *chassisId = "000000000000"; +const char *shopId = "TAIKO ARCADE LOADER"; +const char *gameVerNum = "00.00"; +char accessCode1[21] = "00000000000000000001"; +char accessCode2[21] = "00000000000000000002"; +char chipId1[33] = "00000000000000000000000000000001"; +char chipId2[33] = "00000000000000000000000000000002"; HOOK (i32, ShowMouse, PROC_ADDRESS ("user32.dll", "ShowCursor"), bool) { return originalShowMouse (true); } HOOK (i32, ExitWindows, PROC_ADDRESS ("user32.dll", "ExitWindowsEx")) { @@ -28,7 +32,7 @@ HOOK (i32, ssleay_Shutdown, PROC_ADDRESS ("ssleay32.dll", "SSL_shutdown")) { ret HOOK (i64, UsbFinderInitialize, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderInitialize")) { return 0; } HOOK (i64, UsbFinderRelease, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderRelease")) { return 0; } HOOK (i64, UsbFinderGetSerialNumber, PROC_ADDRESS ("nbamUsbFinder.dll", "nbamUsbFinderGetSerialNumber"), i32 a1, char *a2) { - strcpy (a2, "284111080001"); + strcpy (a2, chassisId); return 0; } @@ -65,7 +69,8 @@ GetGameVersion () { switch (gameVersion) { case GameVersion::JP_NOV_2020: - case GameVersion::CN_JUN_2023: break; + case GameVersion::CN_JUN_2023: + case GameVersion::JP_APR_2023: break; default: MessageBoxA (0, "Unknown game version", 0, MB_OK); ExitProcess (0); } } @@ -97,7 +102,13 @@ DllMain (HMODULE module, DWORD reason, LPVOID reserved) { toml_table_t *config = openConfig (configPath); if (config) { auto amauth = openConfigSection (config, "amauth"); - if (amauth) server = readConfigString (amauth, "server", server); + if (amauth) { + server = readConfigString (amauth, "server", server); + port = readConfigString (amauth, "port", port); + chassisId = readConfigString (amauth, "chassis_id", chassisId); + shopId = readConfigString (amauth, "shop_id", shopId); + gameVerNum = readConfigString (amauth, "game_ver", gameVerNum); + } auto patches = openConfigSection (config, "patches"); if (patches) version = readConfigString (patches, "version", version); toml_free (config); @@ -109,6 +120,8 @@ DllMain (HMODULE module, DWORD reason, LPVOID reserved) { gameVersion = GameVersion::JP_NOV_2020; } else if (!strcmp (version, "cn_jun_2023")) { gameVersion = GameVersion::CN_JUN_2023; + } else if (!strcmp (version, "jp_apr_2023")) { + gameVersion = GameVersion::JP_APR_2023; } else { MessageBoxA (0, "Unknown patch version", 0, MB_OK); ExitProcess (0); @@ -159,6 +172,7 @@ DllMain (HMODULE module, DWORD reason, LPVOID reserved) { case GameVersion::UNKNOWN: break; case GameVersion::JP_NOV_2020: patches::JP_NOV_2020::Init (); break; case GameVersion::CN_JUN_2023: patches::CN_JUN_2023::Init (); break; + case GameVersion::JP_APR_2023: patches::JP_APR_2023::Init (); break; } } return true; diff --git a/src/patches/amauth.cpp b/src/patches/amauth.cpp index fe20470..8f18bfb 100644 --- a/src/patches/amauth.cpp +++ b/src/patches/amauth.cpp @@ -1,21 +1,261 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include "helpers.h" -#include +/* + * Reference: https://gitea.tendokyu.moe/Hay1tsme/bananatools/src/branch/master/amcus/iauth.c + * https://github.com/BroGamer4256/TaikoArcadeLoader/blob/master/plugins/amauth/dllmain.cpp + */ extern const char *server; +extern const char *port; +extern const char *chassisId; +extern const char *shopId; +extern const char *gameVerNum; namespace patches::AmAuth { -char server_ip[0x10]; -DWORD reg = 0; +const GUID IID_CAuth{0x045A5150, 0xD2B3, 0x4590, {0xA3, 0x8B, 0xC1, 0x15, 0x86, 0x78, 0xE1, 0xAC}}; -#ifdef DEFINE_GUID -#undef DEFINE_GUID -#endif +const GUID IID_CAuthFactory{0x4603BB03, 0x058D, 0x43D9, {0xB9, 0x6F, 0x63, 0x9B, 0xE9, 0x08, 0xC1, 0xED}}; -#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} -DEFINE_GUID (IID_CAuthFactory, 0x4603BB03, 0x058D, 0x43D9, 0xB9, 0x6F, 0x63, 0x9B, 0xE9, 0x08, 0xC1, 0xED); -DEFINE_GUID (IID_CAuth, 0x045A5150, 0xD2B3, 0x4590, 0xA3, 0x8B, 0xC1, 0x15, 0x86, 0x78, 0xE1, 0xAC); +typedef struct amcus_network_state { + char mode[16]; + char pcbid[16]; + char dongle_serial[16]; + char shop_router_ip[16]; + char auth_server_ip[16]; + char local_ip[16]; + char subnet_mask[16]; + char gateway[16]; + char primary_dns[16]; + int hop_count; + uint32_t line_type; + uint32_t line_status; + uint32_t content_router_status; + uint32_t shop_router_status; + uint32_t hop_status; +} amcus_network_state_t; + +typedef struct amcus_auth_server_resp { + char uri[257]; + char host[257]; + char shop_name[256]; + char shop_nickname[256]; + char region0[16]; + char region_name0[256]; + char region_name1[256]; + char region_name2[256]; + char region_name3[256]; + char place_id[16]; + char setting[16]; + char country[16]; + char timezone[32]; + char res_class[64]; +} amcus_auth_server_resp_t; + +typedef struct amcus_version_info { + char game_rev[4]; + char auth_type[16]; + char game_id[8]; + char game_ver[8]; + char game_cd[8]; + char cacfg_game_ver[8]; + char game_board_type[4]; + char game_board_id[4]; + char auth_url[256]; +} amcus_version_info_t; + +struct allnet_state {}; + +/* Memory Size: 144 */ +struct mucha_state { + /* Offset: 0 */ /* ENUM32 */ uint32_t state; + /* Offset: 4 */ /* ENUM32 */ uint32_t error; + /* Offset: 8 */ int32_t auth_state; + /* Offset: 12 */ int32_t auth_count; + /* Offset: 16 */ int32_t state_dlexec; + /* Offset: 20 */ int32_t state_dlstep; + /* Offset: 24 */ int32_t state_dllan; + /* Offset: 28 */ int32_t state_dlwan; + /* Offset: 32 */ int32_t state_io; + /* Offset: 36 */ int16_t cacfg_ver_major; + /* Offset: 38 */ int16_t cacfg_ver_minor; + /* Offset: 40 */ int16_t app_ver_major; + /* Offset: 42 */ int16_t app_ver_minor; + /* Offset: 44 */ int16_t dl_ver_major; + /* Offset: 46 */ int16_t dl_ver_minor; + /* Offset: 48 */ int32_t dl_ver_total; + /* Offset: 52 */ int32_t dl_ver_done; + /* Offset: 56 */ int64_t dl_total; + /* Offset: 64 */ int64_t dl_done; + /* Offset: 72 */ int64_t dl_pc_done; + /* Offset: 80 */ int64_t dl_io_total; + /* Offset: 88 */ int64_t dl_io_done; + /* Offset: 96 */ int32_t dl_check_complete; + /* Offset: 100 */ int32_t token_consumed; + /* Offset: 104 */ int32_t token_charged; + /* Offset: 108 */ int32_t token_unit; + /* Offset: 112 */ int32_t token_lower; + /* Offset: 116 */ int32_t token_upper; + /* Offset: 120 */ int32_t token_added; + /* Offset: 124 */ int32_t token_month_lower; + /* Offset: 128 */ int32_t token_month_upper; + /* Offset: 132 */ int32_t is_forced_boot; + /* Offset: 136 */ int32_t Member88; + /* Offset: 140 */ int32_t unknown_a; + /* Offset: 144 */ int32_t unknown_b; +}; + +/* Memory Size: 208 */ +typedef struct amcus_state { + /* Offset: 0 */ /* ENUM32 */ uint32_t allnet_state; + /* Offset: 4 */ /* ENUM32 */ uint32_t allnet_error; + /* Offset: 8 */ int32_t allnet_auth_state; + /* Offset: 12 */ int32_t allnet_auth_count; + /* Offset: 16 */ int32_t allnet_last_error; + /* Offset: 24 */ struct mucha_state mucha_state; + /* Offset: 176 */ int64_t clock_status; + /* Offset: 184 */ int64_t name_resolution_timeout; + /* Offset: 192 */ /* ENUM32 */ uint32_t auth_type; + /* Offset: 196 */ /* ENUM32 */ uint32_t cab_mode; + /* Offset: 200 */ /* ENUM32 */ uint32_t state; + /* Offset: 204 */ /* ENUM32 */ uint32_t err; +} amcus_state_t; + +typedef struct mucha_boardauth_resp { + /* Offset: 0 */ char url_charge[256]; + /* Offset: 256 */ char url_file[256]; + /* Offset: 512 */ char url_url1[256]; + /* Offset: 768 */ char url_url2[256]; + /* Offset: 1024 */ char url_url3[256]; + + /* Offset: 1280 */ char place_id[16]; + /* Offset: 1296 */ char country_cd[16]; + /* Offset: 1312 */ char shop_name[256]; + /* Offset: 1568 */ char shop_nickname[128]; + /* Offset: 1696 */ char area0[64]; + /* Offset: 1760 */ char area1[64]; + /* Offset: 1824 */ char area2[64]; + /* Offset: 1888 */ char area3[64]; + /* Offset: 1952 */ char area_full0[256]; + /* Offset: 2208 */ char area_full1[256]; + /* Offset: 2464 */ char area_full2[256]; + /* Offset: 2720 */ char area_full3[256]; + + /* Offset: 2976 */ char shop_name_en[64]; + /* Offset: 3040 */ char shop_nickname_en[32]; + /* Offset: 3072 */ char area0_en[32]; + /* Offset: 3104 */ char area1_en[32]; + /* Offset: 3136 */ char area2_en[32]; + /* Offset: 3168 */ char area3_en[32]; + /* Offset: 3200 */ char area_full0_en[128]; + /* Offset: 3328 */ char area_full1_en[128]; + /* Offset: 3456 */ char area_full2_en[128]; + /* Offset: 3584 */ char area_full3_en[128]; + + /* Offset: 3712 */ char prefecture_id[16]; + /* Offset: 3728 */ char expiration_date[16]; + /* Offset: 3744 */ char use_token[16]; + /* Offset: 3760 */ char consume_token[32]; + /* Offset: 3792 */ char dongle_flag[8]; + /* Offset: 3800 */ char force_boot[8]; + /* Offset: 3808 */ char auth_token[384]; + /* Offset: 4192 */ char division_code[16]; +} mucha_boardauth_resp_t; + +enum daemon_state { + DAEMON_UNKNOWN, + DAEMON_GET_HOP, + DAEMON_GET_TIP, + DAEMON_GET_AIP, + DAEMON_GET_NET_INFO, + DAEMON_INIT, + DAEMON_AUTH_START, + DAEMON_AUTH_BUSY, + DAEMON_AUTH_RETRY, + DAEMON_DL, + DAEMON_EXPORT, + DAEMON_IMPORT, + DAEMON_CONSUME_CHARGE, + DAEMON_NOTIFY_CHARGE, + DAEMON_CHECK_LAN, + DAEMON_IDLE, + DAEMON_FINALIZE, + DAEMON_BUSY +}; + +enum dllan_state { + DLLAN_UNKNOWN = 40, + DLLAN_NONE, + DLLAN_REQ, + DLLAN_DISABLE, + DLLAN_SERVER_NOTHING, + DLLAN_SERVER_VER_NOTHING, + DLLAN_SERVER_CHECKCODE_NOTHING, + DLLAN_SERVER_IMGCHUNK_NOTHING, + DLLAN_COMPLETE +}; + +enum dlwan_state { + DLWAN_UNKNOWN = 49, + DLWAN_NONE, + DLWAN_REQ, + DLWAN_COMPLETE, + DLWAN_DISABLE, + DLWAN_WANENV_INVALID, + DLWAN_BASICAUTHKEY_INVALID, + DLWAN_SERVER_VERINFO_NOTHING, + DLWAN_SERVER_VERINFO_VERSION_NOTHING, +}; + +enum daemon_io_info { + DAEMON_IO_UNKNOWN = 58, + DAEMON_IO_NONE, + DAEMON_IO_IDLE, + DAEMON_IO_EXPORT, + DAEMON_IO_IMPORT, + DAEMON_IO_FAIL, + DAEMON_IO_SUCCESS, +}; + +enum dlexec_state { + DLEXEC_UNKNOWN = 25, + DLEXEC_NONE, + DLEXEC_PROC, + DLEXEC_STOP, + DLEXEC_STOPPING, +}; + +enum dlstep_state { + DLSTEP_UNKNOWN = 30, + DLSTEP_NONE, + DLSTEP_IDLE, + DLSTEP_PARTIMG_CHECK, + DLSTEP_STOP_REQ, + DLSTEP_LAN_VERINFO, + DLSTEP_LAN_CHECKCODE, + DLSTEP_LAN_IMGCHUNK, + DLSTEP_WAN_CHECKCODE, + DLSTEP_WAN_IMGCHUNK, +}; + +enum auth_type { AUTH_TYPE_OFFLINE, AUTH_TYPE_ALLNET, AUTH_TYPE_NBLINE, AUTH_TYPE_CHARGE_NORMAL, AUTH_TYPE_CHARGE_MONTHLY }; + +enum daemon_mode { + DAEMON_MODE_UNKNOWN, + DAEMON_MODE_SERVER, + DAEMON_MODE_CLIENT, + DAEMON_MODE_STANDALONE, +}; class CAuth : public IUnknown { public: @@ -33,6 +273,7 @@ public: return E_NOINTERFACE; } } + STDMETHODIMP_ (ULONG) AddRef () { return this->refCount++; } STDMETHODIMP_ (ULONG) Release () { this->refCount--; @@ -43,20 +284,80 @@ public: return this->refCount; } - virtual i64 Unk3 (u32 a1) { return 1; } - virtual i64 Unk4 () { return 1; } - virtual i32 Unk5 () { return 0; } - virtual i64 Unk6 () { return 1; } - virtual i32 Unk7 () { return 0; } - virtual i32 Unk8 () { return 0; } - virtual i32 Unk9 (i32 *a1) { - memset (a1, 0, sizeof (i32) * 0x31); - a1[0] = 15; - a1[2] = 2; - a1[3] = 1; - a1[6] = 9; - a1[8] = 2; - a1[9] = 1; + virtual int64_t Unk3 (uint32_t a1) { + // printf ("Unk3 called\n"); + return 1; + } + + virtual int64_t Unk4 () { + // printf ("Unk4 called\n"); + return 1; + } + + virtual int32_t Unk5 () { + // printf ("Unk5 called\n"); + return 0; + } + + virtual int64_t Unk6 () { + // printf ("Unk6 called\n"); + return 1; + } + + virtual int32_t Unk7 () { + // printf ("Unk7 called\n"); + return 0; + } + + virtual int32_t Unk8 () { + // printf ("Unk8 called\n"); + return 0; + } + + virtual int32_t IAuth_GetUpdaterState (amcus_state_t *arr) { + // printf("IAuth_GetUpdaterState called\n"); + memset (arr, 0, sizeof (*arr)); + // Convert gameVerNum from string to double + double ver_d = std::stod (gameVerNum); + + int ver_top = (int)ver_d; + int ver_btm = (int)(ver_d * 100); + + if (ver_top != 0) ver_btm %= (ver_top * 100); + + arr->allnet_state = DAEMON_IDLE; + arr->allnet_auth_state = 2; + arr->allnet_auth_count = 1; + + arr->mucha_state.state = DAEMON_DL; + arr->mucha_state.auth_state = 2; + arr->mucha_state.auth_count = 1; + arr->mucha_state.state_dlexec = DLEXEC_PROC; + arr->mucha_state.state_dlstep = DLSTEP_IDLE; + arr->mucha_state.state_dllan = DLLAN_DISABLE; + arr->mucha_state.state_dlwan = DLWAN_COMPLETE; + arr->mucha_state.state_io = DAEMON_IO_NONE; + arr->mucha_state.cacfg_ver_major = ver_top; + arr->mucha_state.cacfg_ver_minor = ver_btm; + arr->mucha_state.app_ver_major = ver_top; + arr->mucha_state.app_ver_minor = ver_btm; + arr->mucha_state.dl_check_complete = 1; + arr->mucha_state.token_added = 100; + arr->mucha_state.token_charged = 100; + arr->mucha_state.token_unit = 1; + + arr->clock_status = 1; + arr->auth_type = AUTH_TYPE_ALLNET; + arr->cab_mode = DAEMON_MODE_STANDALONE; + arr->state = DAEMON_IDLE; + + /*memset(a1, 0, sizeof(int32_t) * 0x31); + a1[0] = 15; + a1[2] = 2; + a1[3] = 1; + a1[6] = 9; + a1[8] = 2; + a1[9] = 1; a1[10] = 27; a1[11] = 33; a1[12] = 41; @@ -66,83 +367,221 @@ public: a1[30] = 1; a1[46] = 1; a1[47] = 3; - a1[48] = 9; + a1[48] = 9;*/ return 0; } - virtual i32 Unk10 (char *a1) { - memset (a1, 0, 0xB0); - strncpy_s (a1, 0x10, "STANDALONE", 0xF); - strncpy_s (a1 + 0x10, 0x10, "TAL0000001", 0xF); // PCB ID - strncpy_s (a1 + 0x20, 0x10, "000000-00000", 0xF); // ignored by game - strncpy_s (a1 + 0x30, 0x10, server_ip, 0xF); - strncpy_s (a1 + 0x40, 0x10, server_ip, 0xF); - strncpy_s (a1 + 0x50, 0x10, server_ip, 0xF); - strncpy_s (a1 + 0x60, 0x10, "***.***.***.***", 0xF); // Subnet mask - strncpy_s (a1 + 0x70, 0x10, "***.***.***.***", 0xF); // GATEWAY - strncpy_s (a1 + 0x80, 0x10, "***.***.***.***", 0xF); // PRIMARY DNS + + virtual int32_t IAuth_GetCabinetConfig (amcus_network_state_t *state) { + // printf("IAuth_GetCabinetConfig called\n"); + memset (state, 0, sizeof (*state)); + strcpy_s (state->mode, "STANDALONE"); + strcpy_s (state->pcbid, "ABLN1080001"); + strcpy_s (state->dongle_serial, chassisId); + strcpy_s (state->auth_server_ip, server); + strcpy_s (state->local_ip, "127.0.0.1"); + strcpy_s (state->shop_router_ip, "127.0.0.1"); + strcpy_s (state->subnet_mask, "***.***.***.***"); + strcpy_s (state->gateway, "***.***.***.***"); + strcpy_s (state->primary_dns, "***.***.***.***"); + + state->hop_count = 1; + state->line_type = 1; + state->line_status = 1; + state->content_router_status = 1; + state->shop_router_status = 1; + state->hop_status = 1; return 0; } - virtual i32 Unk11 (char *a1) { - memset (a1, 0, 0x13C); - strncpy_s (a1, 4, "1", 3); - strncpy_s (a1 + 4, 0x10, "ALLNET", 0xF); - strncpy_s (a1 + 20, 8, "SBWY", 7); - strncpy_s (a1 + 28, 8, "12.00", 7); - strncpy_s (a1 + 36, 8, "TAL0", 7); // ignored by game - strncpy_s (a1 + 44, 8, "08.18", 7); // GAME VERSION - strncpy_s (a1 + 52, 4, "0", 3); - strncpy_s (a1 + 56, 4, "PCB", 3); + + virtual int32_t IAuth_GetVersionInfo (amcus_version_info_t *version) { + // printf("IAuth_GetVersionInfo called\n"); + memset (version, 0, sizeof (*version)); + strcpy_s (version->game_rev, "1"); + strcpy_s (version->auth_type, "CHARGE_NORMAL"); + strcpy_s (version->game_id, "S122"); + strcpy_s (version->game_ver, "12.20"); + strcpy_s (version->game_cd, "TAL0"); + strcpy_s (version->cacfg_game_ver, gameVerNum); + strcpy_s (version->game_board_type, "0"); + strcpy_s (version->game_board_id, "PCB"); + strcpy_s (version->auth_url, server); return 0; } - virtual i32 Unk12 () { return 1; } - virtual i32 Unk13 () { return 1; } - virtual i32 Unk14 (char *a1) { - memset (a1, 0, 0x8A2); - strncpy_s (a1, 0x101, server, 0x100); - strncpy_s (a1 + 0x101, 0x101, server, 0x100); - strncpy_s (a1 + 0x202, 0x100, "TAIKO ARCADE LOADER", 0xFF); // ALL.Net SHOP NAME - strncpy_s (a1 + 0x302, 0x100, "TAIKO ARCADE LOADER", 0xFF); - strncpy_s (a1 + 0x402, 0x10, "1", 0xF); - strncpy_s (a1 + 0x412, 0x100, "TAIKO ARCADE LOADER", 0xFF); - strncpy_s (a1 + 0x512, 0x100, "X", 0xFF); - strncpy_s (a1 + 0x612, 0x100, "Y", 0xFF); - strncpy_s (a1 + 0x712, 0x100, "Z", 0xFF); - strncpy_s (a1 + 0x812, 0x10, "JPN0123", 0xF); - strncpy_s (a1 + 0x832, 0x10, "JPN", 0xF); - strncpy_s (a1 + 0x842, 0x10, "002,00", 0xF); - strncpy_s (a1 + 0x842, 0x10, "PowerOnResponseVer2", 0xF); + + virtual int32_t Unk12 () { + // printf ("Unk12 called\n"); + return 1; + } + + virtual int32_t Unk13 () { + // printf ("Unk13 called\n"); + return 1; + } + + virtual int32_t IAuth_GetAuthServerResp (amcus_auth_server_resp_t *resp) { + // printf("IAuth_GetAuthServerResp called\n"); + memset (resp, 0, sizeof (*resp)); + strcpy_s (resp->uri, server); + strcpy_s (resp->host, server); + + strcpy_s (resp->shop_name, shopId); + strcpy_s (resp->shop_nickname, shopId); + + strcpy_s (resp->region0, "01035"); + + strcpy_s (resp->region_name0, "NAMCO"); + strcpy_s (resp->region_name1, "X"); + strcpy_s (resp->region_name2, "Y"); + strcpy_s (resp->region_name3, "Z"); + strcpy_s (resp->place_id, "JPN0FFF0"); + strcpy_s (resp->setting, ""); + strcpy_s (resp->country, "JPN"); + strcpy_s (resp->timezone, "+0900"); + strcpy_s (resp->res_class, "PowerOnResponseVer3"); return 0; } - virtual i32 Unk15 () { return 0; } - virtual i32 Unk16 () { return 0; } - virtual i32 Unk17 () { return 0; } - virtual i32 Unk18 (void *a1) { return 0; } - virtual i32 Unk19 (u8 *a1) { + + virtual int32_t Unk15 () { + // printf ("Unk15 called\n"); + return 0; + } + + virtual int32_t Unk16 () { + // printf ("Unk16 called\n"); + return 0; + } + + virtual int32_t Unk17 () { + // printf ("Unk17 called\n"); + return 0; + } + + virtual int32_t IAuth_GetMuchaAuthResponse (mucha_boardauth_resp_t *arr) { + // printf("IAuth_GetMuchaAuthResponse called\n"); + + memset (arr, 0, sizeof (*arr)); + + char fullAddress[256] = {'\0'}; + std::strcat (fullAddress, server); + std::strcat (fullAddress, ":"); + std::strcat (fullAddress, port); + + strcpy_s (arr->shop_name, sizeof (arr->shop_name), shopId); + strcpy_s (arr->shop_name_en, sizeof (arr->shop_name_en), shopId); + strcpy_s (arr->shop_nickname, sizeof (arr->shop_nickname), shopId); + strcpy_s (arr->shop_nickname_en, sizeof (arr->shop_nickname_en), shopId); + strcpy_s (arr->place_id, sizeof (arr->place_id), "JPN0FFF0"); + strcpy_s (arr->country_cd, sizeof (arr->country_cd), "JPN"); + + strcpy_s (arr->area0, sizeof (arr->area0), "008"); + strcpy_s (arr->area0_en, sizeof (arr->area0_en), "008"); + strcpy_s (arr->area1, sizeof (arr->area1), "009"); + strcpy_s (arr->area1_en, sizeof (arr->area1_en), "009"); + strcpy_s (arr->area2, sizeof (arr->area2), "010"); + strcpy_s (arr->area2_en, sizeof (arr->area2_en), "010"); + strcpy_s (arr->area3, sizeof (arr->area3), "011"); + strcpy_s (arr->area3_en, sizeof (arr->area3_en), "011"); + + strcpy_s (arr->prefecture_id, sizeof (arr->prefecture_id), "1"); + strcpy_s (arr->expiration_date, sizeof (arr->expiration_date), ""); + strcpy_s (arr->consume_token, sizeof (arr->consume_token), "10"); + strcpy_s (arr->force_boot, sizeof (arr->force_boot), "0"); + strcpy_s (arr->use_token, sizeof (arr->use_token), "11"); + strcpy_s (arr->dongle_flag, sizeof (arr->dongle_flag), "1"); + strcpy_s (arr->auth_token, sizeof (arr->auth_token), "1"); + strcpy_s (arr->division_code, sizeof (arr->division_code), "1"); + + strcpy_s (arr->url_charge, sizeof (arr->url_charge), "http://127.0.0.1/charge/"); + strcpy_s (arr->url_file, sizeof (arr->url_file), "http://127.0.0.1/file/"); + strcpy_s (arr->url_url1, sizeof (arr->url_url1), fullAddress); + strcpy_s (arr->url_url2, sizeof (arr->url_url2), fullAddress); + strcpy_s (arr->url_url3, sizeof (arr->url_url3), "http://127.0.0.1/url3/"); + return 0; + } + + virtual int32_t Unk19 (uint8_t *a1) { + // printf("Unk19 called\n"); memset (a1, 0, 0x38); a1[0] = 1; return 1; } - virtual i32 Unk20 () { return 0; } - virtual i32 Unk21 () { return 1; } - virtual i32 Unk22 () { return 0; } - virtual i32 Unk23 () { return 0; } - virtual i32 Unk24 () { return 0; } - virtual i32 Unk25 () { return 1; } - virtual i32 Unk26 () { return 0; } - virtual i32 Unk27 () { return 1; } - virtual i32 Unk28 () { return 0; } - virtual i32 Unk29 () { return 0; } - virtual i32 Unk30 () { return 0; } - virtual i32 PrintDebugInfo () { return 0; } - virtual i32 Unk32 (void *a1) { return 0; } - virtual void Unk33 () {} + + virtual int32_t Unk20 () { + // printf ("Unk20 called\n"); + return 0; + } + + virtual int32_t Unk21 () { + // printf ("Unk21 called\n"); + return 1; + } + + virtual int32_t Unk22 () { + // printf ("Unk22 called\n"); + return 0; + } + + virtual int32_t Unk23 () { + // printf ("Unk23 called\n"); + return 0; + } + + virtual int32_t Unk24 () { + // printf ("Unk24 called\n"); + return 0; + } + + virtual int32_t Unk25 () { + // printf ("Unk25 called\n"); + return 1; + } + + virtual int32_t Unk26 () { + // printf ("Unk26 called\n"); + return 0; + } + + virtual int32_t Unk27 () { + // printf ("Unk27 called\n"); + return 1; + } + + virtual int32_t Unk28 () { + // printf ("Unk28 called\n"); + return 0; + } + + virtual int32_t Unk29 () { + // printf ("Unk29 called\n"); + return 0; + } + + virtual int32_t Unk30 () { + // printf ("Unk30 called\n"); + return 0; + } + + virtual int32_t PrintDebugInfo () { + // printf ("Unk31 called\n"); + return 0; + } + + virtual int32_t Unk32 (void *a1) { + // printf ("Unk32 called\n"); + return 0; + } + + virtual void Unk33 () { + // printf ("Unk33 called\n"); + } public: CAuth () {} + virtual ~CAuth () {} private: - i32 refCount = 0; + int32_t refCount = 0; }; class CAuthFactory final : public IClassFactory { @@ -152,7 +591,6 @@ public: QueryInterface (REFIID riid, LPVOID *ppvObj) { wchar_t *iid_str; StringFromCLSID (riid, &iid_str); - printf ("QueryInterface %ls\n", iid_str); if (riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_CAuthFactory) { *ppvObj = this; @@ -162,35 +600,47 @@ public: return E_NOINTERFACE; } } + STDMETHODIMP_ (ULONG) AddRef () { return 2; } STDMETHODIMP_ (ULONG) Release () { return 1; } + virtual HRESULT CreateInstance (IUnknown *outer, REFIID riid, void **object) { - if (outer != 0) return CLASS_E_NOAGGREGATION; - wchar_t *iid_str; - StringFromCLSID (riid, &iid_str); + if (outer != nullptr) return CLASS_E_NOAGGREGATION; + CAuth *auth = new CAuth (); return auth->QueryInterface (riid, object); } - virtual HRESULT LockServer (i32 lock) { return 0; } + + virtual HRESULT LockServer (int32_t lock) { return 0; } }; -HRESULT (STDAPICALLTYPE *gOriCoCreateInstance) (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, LPVOID *ppv); +static HRESULT (STDAPICALLTYPE *g_origCoCreateInstance) (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, LPVOID *ppv); -HRESULT STDAPICALLTYPE +static HRESULT STDAPICALLTYPE CoCreateInstanceHook (const IID *const rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, const IID *const riid, LPVOID *ppv) { - if (IsEqualGUID (*rclsid, IID_CAuthFactory)) { - if (IsEqualGUID (*riid, IID_CAuth)) { - auto cauth = new CAuth (); - return cauth->QueryInterface (*riid, ppv); - } + HRESULT result; + + LPOLESTR clsidStr = nullptr; + LPOLESTR iidStr = nullptr; + StringFromIID (*rclsid, &clsidStr); + StringFromIID (*riid, &iidStr); + + if (IsEqualGUID (*rclsid, IID_CAuthFactory) && IsEqualGUID (*riid, IID_CAuth)) { + auto cauth = new CAuth (); + result = cauth->QueryInterface (*riid, ppv); + } else { + result = g_origCoCreateInstance (rclsid, pUnkOuter, dwClsContext, riid, ppv); } - return gOriCoCreateInstance (rclsid, pUnkOuter, dwClsContext, riid, ppv); + + CoTaskMemFree (clsidStr); + CoTaskMemFree (iidStr); + return result; } void Init () { MH_Initialize (); - MH_CreateHookApi (L"ole32.dll", "CoCreateInstance", (LPVOID)CoCreateInstanceHook, (void **)&gOriCoCreateInstance); + MH_CreateHookApi (L"ole32.dll", "CoCreateInstance", (LPVOID)CoCreateInstanceHook, (void **)&g_origCoCreateInstance); // NOLINT(clang-diagnostic-microsoft-cast) MH_EnableHook (nullptr); } } // namespace patches::AmAuth diff --git a/src/patches/cn_jun_2023.cpp b/src/patches/cn_jun_2023.cpp index e2ee06e..91f3eb7 100644 --- a/src/patches/cn_jun_2023.cpp +++ b/src/patches/cn_jun_2023.cpp @@ -2,6 +2,8 @@ #include "patches.h" #include +extern const char *chassisId; + namespace patches::CN_JUN_2023 { u8 *haspBuffer; @@ -107,7 +109,7 @@ Init () { haspBuffer = (u8 *)malloc (0xD40); memset (haspBuffer, 0, 0xD40); - strcpy ((char *)(haspBuffer + 0xD00), "284111080001"); + strcpy ((char *)(haspBuffer + 0xD00), chassisId); u8 crc = 0; for (int i = 0; i < 62; i++) crc += haspBuffer[0xD00 + i]; @@ -163,11 +165,11 @@ Init () { WRITE_MEMORY (ASLR (0x14034C182), u8, 0x00); // Move various files to current dir - WRITE_MEMORY (ASLR (0x140C7B158), char, "./SettingChina1.bin"); - WRITE_MEMORY (ASLR (0x140C7B2B8), char, "./SettingChina1.bin"); - WRITE_MEMORY (ASLR (0x140C7B2A0), char, "./SettingChina2.bin"); WRITE_MEMORY (ASLR (0x140C33C40), char, "./"); WRITE_MEMORY (ASLR (0x140C33C44), char, "./"); + WRITE_MEMORY (ASLR (0x140C7B158), char, ".\\SettingChina1.bin"); + WRITE_MEMORY (ASLR (0x140C7B2B8), char, ".\\SettingChina1.bin"); + WRITE_MEMORY (ASLR (0x140C7B2A0), char, ".\\SettingChina2.bin"); // Remove datatable size limit { diff --git a/src/patches/jp_apr_2023.cpp b/src/patches/jp_apr_2023.cpp new file mode 100644 index 0000000..e4e9c40 --- /dev/null +++ b/src/patches/jp_apr_2023.cpp @@ -0,0 +1,77 @@ +#include "helpers.h" +#include "patches.h" + +namespace patches::JP_APR_2023 { + +HOOK_DYNAMIC (char, __fastcall, AMFWTerminate, i64) { return 0; } + +void +Init () { + i32 xRes = 1920; + i32 yRes = 1080; + bool vsync = false; + bool sharedAudio = true; + bool unlockSongs = true; + + auto configPath = std::filesystem::current_path () / "config.toml"; + toml_table_t *config = openConfig (configPath); + if (config) { + auto patches = openConfigSection (config, "patches"); + if (patches) { + auto res = openConfigSection (patches, "res"); + if (res) { + xRes = readConfigInt (res, "x", xRes); + yRes = readConfigInt (res, "y", yRes); + } + vsync = readConfigBool (patches, "vsync", vsync); + sharedAudio = readConfigBool (patches, "shared_audio", sharedAudio); + unlockSongs = readConfigBool (patches, "unlock_songs", unlockSongs); + } + toml_free (config); + } + + // Apply common config patch + WRITE_MEMORY (ASLR (0x140494533), i32, xRes); + WRITE_MEMORY (ASLR (0x14049453A), i32, yRes); + if (!vsync) WRITE_MEMORY (ASLR (0x14064C7E9), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); + if (sharedAudio) WRITE_MEMORY (ASLR (0x1407C8637), u8, 0xEB); + if (unlockSongs) WRITE_MEMORY (ASLR (0x1403F45CF), u8, 0xB0, 0x01); + + // Bypass Errors + WRITE_MEMORY (ASLR (0x140041A00), u8, 0xC3); + + // Use TLS v1.2 + WRITE_MEMORY (ASLR (0x140580459), u8, 0x10); + + // Disable F/G Check + WRITE_MEMORY (ASLR (0x140CD4858), char, "./"); + + // Move various files to current dir + WRITE_MEMORY (ASLR (0x140C8AB5C), char, "./"); + WRITE_MEMORY (ASLR (0x140C8AB60), char, "./"); + WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\Setting1.bin"); + WRITE_MEMORY (ASLR (0x140CD4DB0), char, ".\\Setting2.bin"); + WRITE_MEMORY (ASLR (0x140C95B40), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140CD4DC0), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + WRITE_MEMORY (ASLR (0x140CC0508), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC0580), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC05E0), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC0660), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC06C0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC0830), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140C95B78), char, ".\\TournamentData\\PlayData\\TournamentPlayData.dat"); + WRITE_MEMORY (ASLR (0x140C95BE8), char, ".\\TournamentData\\InfoData\\TournamentInfoData.dat"); + WRITE_MEMORY (ASLR (0x140CC0538), char, ".\\Garmc\\BillingData\\GarmcBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC05B0), char, ".\\Garmc\\ErrorLogData\\GarmcOErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC0620), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcBillingNetIdLocationId.dat"); + WRITE_MEMORY (ASLR (0x140CC0690), char, ".\\Garmc\\BillingData\\GarmcOBillingData.dat"); + WRITE_MEMORY (ASLR (0x140CC06F0), char, ".\\Garmc\\ErrorLogData\\GarmcErrorLogData.dat"); + WRITE_MEMORY (ASLR (0x140CC0880), char, ".\\Garmc\\BillingNetIdLocationId\\GarmcOBillingNetIdLocationId.dat"); + + // Disable live check + auto amHandle = (u64)GetModuleHandle ("AMFrameWork.dll"); + INSTALL_HOOK_DYNAMIC (AMFWTerminate, (void *)(amHandle + 0x42DE0)); + + patches::AmAuth::Init (); +} +} // namespace patches::JP_APR_2023 \ No newline at end of file diff --git a/src/patches/jp_nov_2020.cpp b/src/patches/jp_nov_2020.cpp index d737972..05a3610 100644 --- a/src/patches/jp_nov_2020.cpp +++ b/src/patches/jp_nov_2020.cpp @@ -83,9 +83,9 @@ Init () { WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10); // Move various files to current dir + WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./"); WRITE_MEMORY (ASLR (0x140B5C528), char, ".\\Setting1.bin"); WRITE_MEMORY (ASLR (0x140B5C538), char, ".\\Setting2.bin"); - WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./"); WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02); // Remove datatable size limit diff --git a/src/patches/patches.h b/src/patches/patches.h index 3b7933a..91f99c3 100644 --- a/src/patches/patches.h +++ b/src/patches/patches.h @@ -5,6 +5,9 @@ void Init (); namespace CN_JUN_2023 { void Init (); } // namespace CN_JUN_2023 +namespace JP_APR_2023 { +void Init (); +} // namespace JP_APR_2023 namespace AmAuth { void Init (); } // namespace AmAuth