Skip to content

Commit

Permalink
feat: Direct Input and code reorganization
Browse files Browse the repository at this point in the history
  • Loading branch information
Repflez committed Apr 25, 2024
1 parent 088bc30 commit 21c5827
Show file tree
Hide file tree
Showing 21 changed files with 564 additions and 125 deletions.
15 changes: 11 additions & 4 deletions AzureFlare/AzureFlare.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -95,17 +95,24 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="gameguard.cpp" />
<ClCompile Include="gameregion.cpp" />
<ClCompile Include="memory.cpp" />
<ClCompile Include="patches\gameguard.cpp" />
<ClCompile Include="patches\input.cpp" />
<ClCompile Include="patches\language.cpp" />
<ClCompile Include="patches\misc.cpp" />
<ClCompile Include="patches\patches.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="wsock32.def" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="gameguard.h" />
<ClInclude Include="gameregion.h" />
<ClInclude Include="logging.h" />
<ClInclude Include="memory.h" />
<ClInclude Include="patches\gameguard.h" />
<ClInclude Include="patches\input.h" />
<ClInclude Include="patches\language.h" />
<ClInclude Include="patches\misc.h" />
<ClInclude Include="patches\patches.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
Expand Down
31 changes: 26 additions & 5 deletions AzureFlare/AzureFlare.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@
<ClCompile Include="memory.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gameguard.cpp">
<ClCompile Include="patches\patches.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gameregion.cpp">
<ClCompile Include="patches\gameguard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="patches\language.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="patches\input.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="patches\misc.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
Expand All @@ -34,13 +43,25 @@
</None>
</ItemGroup>
<ItemGroup>
<ClInclude Include="gameguard.h">
<ClInclude Include="memory.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="memory.h">
<ClInclude Include="logging.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="patches\patches.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="patches\gameguard.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="patches\language.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="patches\input.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gameregion.h">
<ClInclude Include="patches\misc.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
Expand Down
33 changes: 6 additions & 27 deletions AzureFlare/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#include <detours/detours.h>
#include <toml++/toml.hpp>

#include "gameguard.h"
#include "gameregion.h"
#include "logging.h"
#include "patches/patches.h"

using namespace std::string_view_literals;

Expand Down Expand Up @@ -71,11 +71,7 @@ const char* fallbackUrl = "localhost";

#pragma endregion

#if _DEBUG
#define DLOG(...) printf_s(__VA_ARGS__)
#else
#define DLOG(...)
#endif


FARPROC p[ALLFUNC_COUNT] = { 0 };

Expand All @@ -86,7 +82,6 @@ OriginalGetHostByName pOriginalGetHostByName = nullptr;

bool loaded = FALSE;
bool canRedirectServers = TRUE;
bool canBypassGameGuard = false;
toml::table config;

#define AF_SERVER_REDIRECT(outBuffer, passedValue, origAddr, newAddr, comment) \
Expand Down Expand Up @@ -173,21 +168,14 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
freopen("CON", "w", stdout);
#endif

// As the configuration is loaded now, we can start setting the values we need to.
// Set the server redirection patch status here now, the rest are handled elsewhere
canRedirectServers = config.at_path("patches.redirect").value_or(false);
canBypassGameGuard = config.at_path("patches.gameguard").value_or(false);

DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());

// Bypass GameGuard if we enabled the patch
if (canBypassGameGuard)
{
PatchGameGuard(config);
}

// Set Episode 4 mode if it was set on config
PatchEpisode4Mode(config.at_path("patches.episode4_mode").value_or(false));
// Do our patches now
DoMemoryPatches(config);

DetourTransactionCommit();

Expand All @@ -202,15 +190,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());

// Clean up GameGuard if we enabled the bypass
if (canBypassGameGuard)
{
UnpatchGameGuard();
}

// Remove the Episode 4 patch
UnpatchEpisode4Mode();

// Finalize the transaction
DetourTransactionCommit();
FreeLibrary(hDLL);
Expand Down
81 changes: 68 additions & 13 deletions AzureFlare/gameguard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@
#include <windows.h>
#include <stdio.h>
#include <intrin.h>

#include <Psapi.h>
#include <iostream>

#include <toml++/toml.hpp>
#include <detours/detours.h>

#include "logging.h"
#include "signatures.h"
#include "memory.h"
#include "gameguard.h"

#pragma intrinsic(_ReturnAddress)

#define NPGAMEMON_SUCCESS 0x755

#define PSOBB_REGION_START 0x401000
#define PSOBB_REGION_END PSOBB_REGION_START + 0x638000

// Signature for InitNPGameMon
// Notes: return value seems to be an unsigned int? some places say it's a DWORD, others unsigned int
// Signature from https://github.com/fuzziqersoftware/newserv/issues/336#issuecomment-2028486289 and
Expand All @@ -26,12 +31,6 @@ BYTE InitNPGameMonSignature[] = { 0x8B, 0x0D, 0xCC, 0xCC, 0xCC, 0xCC, 0x85, 0xC9
// https://github.com/fatrolls/nProtect-GameGuard/blob/164940ba81d318c300234c75f04da1412b554621/old/NPGameLib.c#L25
BYTE PreInitNPGameMonASignature[] = { 0xA1, 0xCC, 0xCC, 0xCC, 0xCC, 0x53, 0x33, 0xDB, 0x3B, 0xC3, 0x74, 0x04 };

// Signature for the function that decides if the game is Episode 4 or not
BYTE IsEp4Signature[] = { 0xB8, 0x30, 0x11, 0x00, 0x00 };

// Typedef for the GameRegion function
typedef bool (*OriginalIsEp4)();

// Pointer to the original CreateProcessA
OriginalCreateProcessA originalCreateProcessA = CreateProcessA;

Expand All @@ -44,6 +43,8 @@ OriginalPreInitNPGameMonA originalPreInitGameGuard = nullptr;
// Pointer to the original game region function
OriginalIsEp4 originalIsEp4Address = nullptr;

OriginalGetGameLanguage originalGameLanguage = nullptr;

// Pointer to the original GetStartupInfoA
auto startupInfoA = static_cast<decltype(GetStartupInfoA)*>(GetStartupInfoA);

Expand Down Expand Up @@ -98,6 +99,18 @@ int __cdecl BypassGameGuardPreInit(char* a1)
return 1;
}

int GetGameLanguage() {
// 0: Japanese (j)
// 1: English (e)
// 2: German (g)
// 3: French (f)
// 4: Spanish (s)
// 5: Chinese Simplified (cs)
// 6: Chinese Traditional (ct)
// 7: Korean (h)
return 1;
}

int IsEp4()
{
return az_config.at_path("patches.episode4_mode").value_or(false);
Expand Down Expand Up @@ -129,11 +142,10 @@ void ApplyGameGuardPatches(HMODULE hModule)

void WINAPI AZ_GetStartUpInfoA(LPSTARTUPINFOA lpStartupInfo)
{
uintptr_t baseAddress = reinterpret_cast<uintptr_t>(_ReturnAddress());
const auto caller = GetOwningModule(baseAddress);
const auto caller = GetOwningModule(reinterpret_cast<uintptr_t>(_ReturnAddress()));
if (caller == GetModuleHandleA("PsoBB.exe"))
{
uintptr_t address = ScanProcessMemory(InitNPGameMonSignature, "xx????xxxxxxxx????x", 0, 0x01000000);
uintptr_t address = ScanProcessMemory(InitNPGameMonSignature, "xx????xxxxxxxx????x", PSOBB_REGION_START, PSOBB_REGION_END);

// Restarting the entire detours process makes it work. No idea why.
if (address != 0) {
Expand All @@ -145,8 +157,7 @@ void WINAPI AZ_GetStartUpInfoA(LPSTARTUPINFOA lpStartupInfo)
DetourTransactionCommit();
}

address = ScanProcessMemory(PreInitNPGameMonASignature, "x????xxxxxxx", 0, 0x01000000);

address = ScanProcessMemory(PreInitNPGameMonASignature, "x????xxxxxxx", PSOBB_REGION_START, PSOBB_REGION_END);
if (address != 0) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
Expand All @@ -157,24 +168,68 @@ void WINAPI AZ_GetStartUpInfoA(LPSTARTUPINFOA lpStartupInfo)
}

// Patch episode 4 data now
address = ScanProcessMemory(IsEp4Signature, "xxxxx", 0, 0x01000000);
address = ScanProcessMemory(IsEp4Signature, "xxxxx", PSOBB_REGION_START, PSOBB_REGION_END);
if (address != 0) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());

originalIsEp4Address = reinterpret_cast<OriginalIsEp4>(address);
DetourAttach(&reinterpret_cast<PVOID&>(originalIsEp4Address), IsEp4);

DetourTransactionCommit();
}

// Game Language
address = ScanProcessMemory(GameLanguageSignature, "xxxxx", PSOBB_REGION_START, PSOBB_REGION_END);
if (address != 0) {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());

originalGameLanguage = reinterpret_cast<OriginalGetGameLanguage>(address);
DetourAttach(&reinterpret_cast<PVOID&>(originalGameLanguage), GetGameLanguage);

DetourTransactionCommit();
}


address = ScanProcessMemory(IMESignature, "xxxxxxxxxx", PSOBB_REGION_START, PSOBB_REGION_END);
if (address != 0) {
int FinalAddress = address + 0x56;

*(int*)FinalAddress = 0x008EC39C;
}
}

return startupInfoA(lpStartupInfo);
}


#ifdef _DEBUG
auto handleFIleA = static_cast<decltype(CreateFileA)*>(CreateFileA);
HANDLE WINAPI MyCreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
DLOG("CreateFileA: %s\n", lpFileName);
auto demhandle = handleFIleA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);

return demhandle;
}
#endif

void PatchGameGuard(toml::table config)
{
az_config = config;

#ifdef _DEBUG
DetourAttach(&reinterpret_cast<PVOID&>(handleFIleA), MyCreateFileA);
#endif

// Patch the GameGuard functions for unpacked versions of the client
ApplyGameGuardPatches(GetModuleHandle(NULL));

Expand Down
26 changes: 0 additions & 26 deletions AzureFlare/gameguard.h

This file was deleted.

40 changes: 0 additions & 40 deletions AzureFlare/gameregion.cpp

This file was deleted.

7 changes: 0 additions & 7 deletions AzureFlare/gameregion.h

This file was deleted.

Loading

0 comments on commit 21c5827

Please sign in to comment.