diff --git a/meson.build b/meson.build index 85df2d9..bf2f779 100644 --- a/meson.build +++ b/meson.build @@ -54,6 +54,7 @@ library( 'src/bnusio.cpp', 'src/patches/jp_nov_2020.cpp', 'src/patches/cn_jun_2023.cpp', + 'src/patches/amauth.cpp', ], name_prefix: '' ) diff --git a/src/bnusio.cpp b/src/bnusio.cpp index b1b04d1..1c2e556 100644 --- a/src/bnusio.cpp +++ b/src/bnusio.cpp @@ -73,8 +73,10 @@ Keybindings P2_LEFT_RED = {}; Keybindings P2_RIGHT_RED = {}; Keybindings P2_RIGHT_BLUE = {}; -u16 drumMin = 10000; -u16 drumMax = 20000; +u16 drumMin = 10000; +u16 drumMax = 20000; +u16 drumWaitPeriod = 4; + u16 lastHitValue = drumMin; Keybindings *analogButtons[] = {&P1_LEFT_BLUE, &P1_LEFT_RED, &P1_RIGHT_RED, &P1_RIGHT_BLUE, &P2_LEFT_BLUE, &P2_LEFT_RED, &P2_RIGHT_RED, &P2_RIGHT_BLUE}; @@ -95,10 +97,10 @@ bnusio_GetAnalogIn (u8 which) { if ((isP1 && buttonQueueP1.front () == which && buttonWaitPeriodP1 == 0) || (!isP1 && buttonQueueP2.front () == which && buttonWaitPeriodP2 == 0)) { if (isP1) { buttonQueueP1.pop (); - buttonWaitPeriodP1 = 4; + buttonWaitPeriodP1 = drumWaitPeriod; } else { buttonQueueP2.pop (); - buttonWaitPeriodP2 = 4; + buttonWaitPeriodP2 = drumWaitPeriod; } lastHitValue++; @@ -118,8 +120,8 @@ bnusio_GetAnalogIn (u8 which) { buttonQueueP2.push (which); return 0; } - if (isP1) buttonWaitPeriodP1 = 4; - else buttonWaitPeriodP2 = 4; + if (isP1) buttonWaitPeriodP1 = drumWaitPeriod; + else buttonWaitPeriodP2 = drumWaitPeriod; lastHitValue++; if (lastHitValue >= drumMax) lastHitValue = drumMin; return lastHitValue; diff --git a/src/helpers.h b/src/helpers.h index fab8613..3bfa671 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -31,10 +31,10 @@ const HMODULE MODULE_HANDLE = GetModuleHandle (nullptr); #define ASLR(address) ((u64)MODULE_HANDLE + (u64)address - (u64)BASE_ADDRESS) #endif -#define HOOK(returnType, functionName, location, ...) \ - typedef returnType (*functionName) (__VA_ARGS__); \ - functionName original##functionName = NULL; \ - void *where##functionName = (void *)location; \ +#define HOOK(returnType, functionName, location, ...) \ + typedef returnType (*functionName) (__VA_ARGS__); \ + functionName original##functionName = NULL; \ + void *where##functionName = (void *)(location); \ returnType implOf##functionName (__VA_ARGS__) #define VTABLE_HOOK(returnType, className, functionName, ...) \ diff --git a/src/patches/amauth.cpp b/src/patches/amauth.cpp new file mode 100644 index 0000000..a77b65b --- /dev/null +++ b/src/patches/amauth.cpp @@ -0,0 +1,190 @@ +#include + +#include "helpers.h" +#include + +extern const char *server; + +namespace patches::AmAuth { +char server_ip[0x10]; +DWORD reg = 0; + +#ifdef DEFINE_GUID +#undef DEFINE_GUID +#endif + +#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); + +class CAuth : public IUnknown { +public: + STDMETHODIMP + QueryInterface (REFIID riid, LPVOID *ppvObj) { + wchar_t *iid_str; + StringFromCLSID (riid, &iid_str); + + if (riid == IID_IUnknown || riid == IID_CAuth) { + *ppvObj = this; + this->AddRef (); + return 0; + } else { + *ppvObj = 0; + return E_NOINTERFACE; + } + } + STDMETHODIMP_ (ULONG) AddRef () { return this->refCount++; } + STDMETHODIMP_ (ULONG) Release () { + this->refCount--; + if (this->refCount <= 0) { + // delete this; + return 0; + } + 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; + a1[10] = 27; + a1[11] = 33; + a1[12] = 41; + a1[13] = 50; + a1[14] = 59; + a1[15] = 1179656; + a1[30] = 1; + a1[46] = 1; + a1[47] = 3; + 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 + 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); + 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); + 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) { + 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 () {} + +public: + CAuth () {} + virtual ~CAuth () {} + +private: + i32 refCount = 0; +}; + +class CAuthFactory : public IClassFactory { +public: + STDMETHODIMP + 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; + return 0; + } else { + *ppvObj = 0; + 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); + CAuth *auth = new CAuth (); + return auth->QueryInterface (riid, object); + } + virtual HRESULT LockServer (i32 lock) { return 0; } +}; + +void +Init () { + CoInitializeEx (0, 0); + CoRegisterClassObject (IID_CAuthFactory, (IUnknown *)new CAuthFactory (), CLSCTX_LOCAL_SERVER, 1, ®); + + struct addrinfo *res = 0; + getaddrinfo (server, "", 0, &res); + for (struct addrinfo *i = res; i != 0; i = i->ai_next) { + if (res->ai_addr->sa_family != AF_INET) continue; + struct sockaddr_in *p = (struct sockaddr_in *)res->ai_addr; + inet_ntop (AF_INET, &p->sin_addr, server_ip, 0x10); + break; + } +} +} // namespace patches::AmAuth diff --git a/src/patches/cn_jun_2023.cpp b/src/patches/cn_jun_2023.cpp index 49377c2..26836e9 100644 --- a/src/patches/cn_jun_2023.cpp +++ b/src/patches/cn_jun_2023.cpp @@ -1,12 +1,6 @@ #include "helpers.h" namespace patches::CN_JUN_2023 { -i32 xRes = 1360; -i32 yRes = 768; -bool unlockSongs = true; -bool sharedAudio = true; -bool vsync = false; - u8 *haspBuffer; HOOK (i32, HaspDecrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_decrypt")) { return 0; } HOOK (i32, HaspEncrypt, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_encrypt")) { return 0; } @@ -27,6 +21,12 @@ HOOK (i32, HaspRead, PROC_ADDRESS ("hasp_windows_x64.dll", "hasp_read"), i32, i3 void Init () { + i32 xRes = 1360; + i32 yRes = 768; + bool unlockSongs = true; + bool sharedAudio = true; + bool vsync = false; + haspBuffer = (u8 *)malloc (0xD40); memset (haspBuffer, 0, 0xD40); strcpy ((char *)(haspBuffer + 0xD00), "284111080001"); diff --git a/src/patches/jp_nov_2020.cpp b/src/patches/jp_nov_2020.cpp index 7298ddd..57b339a 100644 --- a/src/patches/jp_nov_2020.cpp +++ b/src/patches/jp_nov_2020.cpp @@ -1,9 +1,131 @@ #include "helpers.h" +#include "patches.h" + +const u64 song_data_size = 1024 * 1024 * 64; +void *song_data; + +#define RDX_MOV 0x48, 0xBA +#define R8_MOV 0x49, 0xB8 +#define GENERATE_MOV(instruction, location) \ + instruction, (u8)(u64)(location), (u8)((u64)(location) >> 8), (u8)((u64)(location) >> 16), (u8)((u64)(location) >> 24), (u8)((u64)(location) >> 32), (u8)((u64)(location) >> 40), \ + (u8)((u64)(location) >> 48), (u8)((u64)(location) >> 56) namespace patches::JP_NOV_2020 { void Init () { - MessageBoxA (0, "08.18 is currently not supported", 0, 0); - ExitProcess (0); + i32 xRes = 1360; + i32 yRes = 768; + bool unlockSongs = true; + bool sharedAudio = true; + bool vsync = false; + + auto configPath = std::filesystem::current_path () / "config.toml"; + toml_table_t *config = openConfig (configPath); + if (config) { + auto res = openConfigSection (config, "res"); + if (res) { + xRes = readConfigInt (res, "x", xRes); + yRes = readConfigInt (res, "y", yRes); + } + unlockSongs = readConfigBool (config, "unlock_songs", unlockSongs); + sharedAudio = readConfigBool (config, "shared_audio", sharedAudio); + vsync = readConfigBool (config, "vsync", vsync); + toml_free (config); + } + + WRITE_MEMORY (ASLR (0x1400239C0), u8, 0xC3); // Stop error + if (unlockSongs) WRITE_MEMORY (ASLR (0x140314E8D), u8, 0xB0, 0x01); + if (sharedAudio) WRITE_MEMORY (ASLR (0x140692E17), u8, 0xEB); + if (!vsync) WRITE_MEMORY (ASLR (0x140517339), u8, 0xBA, 0x00, 0x00, 0x00, 0x00, 0x90); + + // Remove song limit + WRITE_MEMORY (ASLR (0x140313726), i32, 9000); + WRITE_MEMORY (ASLR (0x1402F39E6), i32, 9000); + WRITE_MEMORY (ASLR (0x1402F3AB0), i32, 9000); + WRITE_MEMORY (ASLR (0x1402F3BE4), i32, 9000); + WRITE_MEMORY (ASLR (0x14030643B), i32, 9000); + WRITE_MEMORY (ASLR (0x140306507), i32, 9000); + WRITE_MEMORY (ASLR (0x1403065D3), i32, 9000); + WRITE_MEMORY (ASLR (0x1403066FB), i32, 9000); + WRITE_MEMORY (ASLR (0x1403067C7), i32, 9000); + WRITE_MEMORY (ASLR (0x140306893), i32, 9000); + WRITE_MEMORY (ASLR (0x14030698B), i32, 9000); + WRITE_MEMORY (ASLR (0x140313666), i32, 9000); + WRITE_MEMORY (ASLR (0x1403139F4), i32, 9000); + WRITE_MEMORY (ASLR (0x140313B04), i32, 9000); + WRITE_MEMORY (ASLR (0x140313C24), i32, 9000); + WRITE_MEMORY (ASLR (0x140313CF4), i32, 9000); + WRITE_MEMORY (ASLR (0x1403140C4), i32, 9000); + WRITE_MEMORY (ASLR (0x1403147AA), i32, 9000); + WRITE_MEMORY (ASLR (0x140225FB6), i32, 9000); + WRITE_MEMORY (ASLR (0x140226146), i32, 9000); + WRITE_MEMORY (ASLR (0x140314DCC), i32, 9000); + WRITE_MEMORY (ASLR (0x140314EC9), i32, 9000); + WRITE_MEMORY (ASLR (0x140338E2C), i32, 9000); + WRITE_MEMORY (ASLR (0x1400EE0A4), i32, 9000); + WRITE_MEMORY (ASLR (0x1400EE8B5), i32, 9000); + WRITE_MEMORY (ASLR (0x1400EEDA6), i32, 9000); + WRITE_MEMORY (ASLR (0x140315608), i32, 9000); + WRITE_MEMORY (ASLR (0x14034A7EB), i32, 9000); + WRITE_MEMORY (ASLR (0x1402F3CB3), i32, 9000); + WRITE_MEMORY (ASLR (0x140314059), i32, 9000); + WRITE_MEMORY (ASLR (0x140226063), i32, 9000); + WRITE_MEMORY (ASLR (0x14022609F), i32, 9000); + WRITE_MEMORY (ASLR (0x140226296), i32, 9000); + WRITE_MEMORY (ASLR (0x140306A2E), i32, 9000); + WRITE_MEMORY (ASLR (0x140314F46), i32, 9000); + WRITE_MEMORY (ASLR (0x140314F97), i32, 9000); + + song_data = malloc (song_data_size); + memset (song_data, 0, song_data_size); + + // Song data + WRITE_MEMORY (ASLR (0x14031367B), u8, GENERATE_MOV (R8_MOV, song_data)); + // Crown data + WRITE_MEMORY (ASLR (0x1402F3AC6), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1402F39FC), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1402F3BFA), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1403140D7), u8, GENERATE_MOV (R8_MOV, song_data)); + // Score ranks + WRITE_MEMORY (ASLR (0x1403065EA), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x14030651E), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140306452), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1403068AA), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1403067DE), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140306712), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x1403069A2), u8, GENERATE_MOV (RDX_MOV, song_data)); + // Unknown + WRITE_MEMORY (ASLR (0x140313755), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140313A0B), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140313B4C), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140313D38), u8, GENERATE_MOV (RDX_MOV, song_data)); + WRITE_MEMORY (ASLR (0x140313C42), u8, GENERATE_MOV (R8_MOV, song_data)); + + // Save settings cross session without F:/ and G:/ drive + WRITE_MEMORY (ASLR (0x140B5C528), char, "./Setting1.bin"); + WRITE_MEMORY (ASLR (0x140B5C538), char, "./Setting2.bin"); + // Move F:/ files to current directory + WRITE_MEMORY (ASLR (0x140B1B4B0), char, "./"); + WRITE_MEMORY (ASLR (0x14001C941), u8, 0x02); + // Patch TLS v1.0 to v1.2 + WRITE_MEMORY (ASLR (0x14044B1A9), u8, 0x10); + + if (xRes > 0 && yRes > 0) { + WRITE_MEMORY (ASLR (0x14035FC5B), i32, xRes); + WRITE_MEMORY (ASLR (0x14035FC62), i32, yRes); + } + + // Move various files to current directory + auto amHandle = GetModuleHandle ("AMFrameWork.dll"); + WRITE_MEMORY (amHandle + 0x33EF7, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x3404A, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x34429, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x3457C, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x3497A, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x34ACD, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x148AF, u8, 0xEB); + WRITE_MEMORY (amHandle + 0x14A1A, u8, 0xEB); + + patches::AmAuth::Init (); } } // namespace patches::JP_NOV_2020 diff --git a/src/patches/patches.h b/src/patches/patches.h index a361123..d5392de 100644 --- a/src/patches/patches.h +++ b/src/patches/patches.h @@ -5,4 +5,7 @@ void Init (); namespace CN_JUN_2023 { void Init (); } // namespace CN_JUN_2023 +namespace AmAuth { +void Init (); +} // namespace AmAuth } // namespace patches