Skip to content

Commit

Permalink
Memory Operationn
Browse files Browse the repository at this point in the history
Basic example showcasing a few memory operations on both PCSX2 process as well as game data
  • Loading branch information
xCENTx committed Apr 17, 2024
1 parent 95412bd commit b2ae5a4
Show file tree
Hide file tree
Showing 11 changed files with 413 additions and 35 deletions.
9 changes: 1 addition & 8 deletions .gitignore
Expand Up @@ -6,13 +6,6 @@ release/
x86/
x64/

# exclude external libraries
*.rcnet
GamePackages/

# exclude personal settings
dllmain.cpp
*.sln
*.vcxproj
*.vcxproj.filters
*.vcxproj.user
*.code-workspace
1 change: 0 additions & 1 deletion SDK/engine_classes.h
Expand Up @@ -48,7 +48,6 @@ namespace PlayStation2
public:
Console();
Console(const char* title);
~Console();

private:
static FILE* m_pInStream; // Console Text Input Stream
Expand Down
56 changes: 41 additions & 15 deletions SDK/engine_package.cpp
Expand Up @@ -13,11 +13,39 @@ namespace PlayStation2
// CORE
//-----------------------------------------------------------------------------------

///---------------------------------------------------------------------------------------------------
bool InitSDK(const std::string& moduleName)
{
bool result{ false };

Tools::CPUTimer t;

HANDLE pHand = GetModuleHandleA(moduleName.c_str());
if (!pHand)
return result;

CGlobals::g_console = Console::GetDefaultInstance();

CGlobals::g_engine = Engine::GetDefaultInstance();

CGlobals::g_memory = Memory::GetDefaultInstance();

Console::LogMsg("[+][%.3f] PCSX2 Cheat Device Initialized!\n- PCSX2:\t0x%llX\n- PS2:\t\t0x%llX\n\n",
t.Stop(Tools::CPUTimer::ETimings::ETiming_MS),
(__int64)pHand,
PS2Memory::GetModuleBase()
);

return true;
}

///---------------------------------------------------------------------------------------------------
bool InitSDK(const std::string& moduleName, unsigned int gDevice)
{
bool result{ false };

Tools::CPUTimer t;

HANDLE pHand = GetModuleHandleA(moduleName.c_str());
if (!pHand)
return result;
Expand All @@ -27,26 +55,28 @@ namespace PlayStation2
return false;

CGlobals::g_console = Console::GetDefaultInstance();

CGlobals::g_engine = Engine::GetDefaultInstance();

CGlobals::g_memory = Memory::GetDefaultInstance();

Console::LogMsg("[+] PCSX2 Framework Client Initialized!\nmodBase:\t0x%llX\nPS2ModBase:\t0x%llX\ng_gs_device:\t0x%llX\nRenderAPI:\t%d\n",
Console::LogMsg("[+][%.3f] PCSX2 Cheat Device Initialized!\n- PCSX2:\t0x%llX\n- PS2:\t0x%llX\n- GSDevice:\t0x%llX\n- RenderAPI:\t%d\n",
t.Stop(Tools::CPUTimer::ETimings::ETiming_MS),
(__int64)pHand,
PS2Memory::GetModuleBase(),
CGlobals::g_gs_device,
GSDevice::GetRenderAPI()
GSDevice::GetRenderAPI() // @TODO: get string , its a virtual method . . .
);

return true;
}

///---------------------------------------------------------------------------------------------------
// Template Initialization function
// NOTE: offsets will not always be correct
// NOTE2: PCSX2 v1.7.5617
bool InitSDK() { return InitSDK("pcsx2-qt.exe", PCSX2::o_gs_device); }
// Template Initialization function compatible with Nightly Builds
bool InitSDK() { return InitSDK("pcsx2-qt.exe"); }

///---------------------------------------------------------------------------------------------------
void ShutdownSDK() { }
void ShutdownSDK() { Console::DestroyConsole(); }

//----------------------------------------------------------------------------------------------------
// CGLOBALS
Expand Down Expand Up @@ -117,9 +147,6 @@ namespace PlayStation2
m_isConsoleAllocated = true;
}

///---------------------------------------------------------------------------------------------------
Console::~Console() { DestroyConsole(); }

///---------------------------------------------------------------------------------------------------
Console* Console::GetDefaultInstance() { return m_instance; }

Expand Down Expand Up @@ -303,9 +330,9 @@ namespace PlayStation2

// Set the fields of the ProcessInfo struct
pInfo.m_GameWindow = hWnd;
pInfo.m_WindowTitle = szWindowTitle;
pInfo.m_ClassName = szClassName;
pInfo.m_ModulePath = szModulePath;
pInfo.m_WindowTitle = std::string(szWindowTitle, lstrlenA(szWindowTitle));
pInfo.m_ClassName = std::string(szClassName, lstrlenA(szClassName));
pInfo.m_ModulePath = std::string(szModulePath, lstrlenA(szModulePath));
pInfo.m_WindowWidth = nWidth;
pInfo.m_WindowHeight = nHeight;
pInfo.m_WindowSize = Vector2((float)nWidth, (float)nHeight);
Expand Down Expand Up @@ -434,7 +461,7 @@ namespace PlayStation2

void Tools::CPUTimer::Reset() { Start(); }

double Tools::CPUTimer::GetElapsedTime(clock_t time, ETimings t = ETimings::ETiming_MS) const
double Tools::CPUTimer::GetElapsedTime(clock_t time, ETimings t) const
{
double res = static_cast<double>(time - m_start) / CLOCKS_PER_SEC;
switch (t)
Expand All @@ -443,7 +470,6 @@ namespace PlayStation2
case ETimings::ETiming_S: return res;
case ETimings::ETiming_M: return res / 60;
case ETimings::ETiming_HR: return res / 3600;
default: return res;
}
}

Expand Down
1 change: 1 addition & 0 deletions SDK/engine_package.h
Expand Up @@ -11,6 +11,7 @@ namespace PlayStation2
// --------------------------------------------------
// # Global functions
// --------------------------------------------------
bool InitSDK(const std::string& moduleName);
bool InitSDK(const std::string& moduleName, unsigned int gRenderer);
bool InitSDK();
void ShutdownSDK();
Expand Down
22 changes: 11 additions & 11 deletions SDK/engine_structs.h
Expand Up @@ -238,17 +238,17 @@ namespace PlayStation2

struct ProcessInfo
{
DWORD m_ModulePID{};
HANDLE m_ModuleHandle{};
uintptr_t m_ModuleBase{};

HWND m_GameWindow{};
LPCSTR m_WindowTitle;
LPCSTR m_ClassName;
LPCSTR m_ModulePath;
int m_WindowWidth;
int m_WindowHeight;
Vector2 m_WindowSize{};
DWORD m_ModulePID{};
HANDLE m_ModuleHandle{};
uintptr_t m_ModuleBase{};

HWND m_GameWindow{};
std::string m_WindowTitle;
std::string m_ClassName;
std::string m_ModulePath;
int m_WindowWidth;
int m_WindowHeight;
Vector2 m_WindowSize{};
};

enum EConsoleColors : int
Expand Down
101 changes: 101 additions & 0 deletions examples/GameMemory/dllmain.cpp
@@ -0,0 +1,101 @@
#pragma once
#include "pch.h"

static bool g_running;

//---------------------------------------------------------------------------------------------------
// Initialize Client
DWORD WINAPI MainThread(LPVOID hInstance)
{

#if _DEBUG

MessageBoxA(NULL, "Initializing PCSX2 FrameWork", "DEBUG BUILD", MB_OK | MB_ICONINFORMATION);

#endif

// initialize pcsx2 cheat dev kit
if (PlayStation2::InitSDK())
{
using namespace PlayStation2;


Tools::CPUTimer t;

// - Get PCSX2 Module Base
const auto pcsx2ModuleBase = Memory::GetModuleBase();
Console::LogMsg("[+][%.3f][Memory::GetModuleBase] 0x%llX\n", t.GetElapsedTime(clock()), pcsx2ModuleBase);

// - Read 8 bytes from module base address
long long result = Memory::ReadMemoryEx<long long>(pcsx2ModuleBase);
Console::LogMsg("[+][%.3f][Memory::ReadMemoryEx] 0x%llX\n", t.GetElapsedTime(clock()), result);

// - Get EE Memory Module Base ( ps2 game ram )
const auto eeModuleBase = PS2Memory::GetModuleBase();
Console::LogMsg("[+][%.3f][PS2Memory::GetModuleBase] 0x%llX\n", t.GetElapsedTime(clock()), eeModuleBase);

// - retrieve an offsets virtual address in memory
long long offsetAddress = PS2Memory::GetAddr(0x1000);
Console::LogMsg("[+][%.3f][PS2Memory::GetAddr] 0x%llX\n", t.GetElapsedTime(clock()), offsetAddress);

// - read 8 bytes from the offset virtual address obtained in the previous step
auto read_result_long = PS2Memory::ReadLong<long long>(offsetAddress);
Console::LogMsg("[+][%.3f][PS2Memory::ReadLong] 0x%llX\n", t.GetElapsedTime(clock()), read_result_long);

// - read 8 bytes from a virtual address in memory using a games offset
auto read_result_short = PS2Memory::ReadShort<long long>(0x2000);
Console::LogMsg("[+][%.3f][PS2Memory::ReadShort] 0x%llX\n", t.GetElapsedTime(clock()), read_result_short);


// - Obtain basic process information such as PID, handle, base address & window information
ProcessInfo pInfo;
Memory::ObtainProcessInfo(pInfo);
Console::LogMsg("[+][%.3f][Memory::ObtainProcessInfo]\n- PID:\t\t0x%X\n- PATH:\t\t%s\n- HWND:\t\t0x%X\n- TITLE:\t%s\n\n",
t.Stop(Tools::CPUTimer::ETimings::ETiming_MS),
pInfo.m_ModulePID, //
pInfo.m_ModulePath.c_str(), //
pInfo.m_GameWindow, // Might be console window
pInfo.m_WindowTitle.c_str() // Might be console window title
);

g_running = true;

// Render Loop
do
{
// Exit Module
if (GetAsyncKeyState(VK_END) & 0x8000)
g_running = false;

} while (g_running);

// cleanup
PlayStation2::ShutdownSDK();
}

// Exit
FreeLibraryAndExitThread((HMODULE)hInstance, EXIT_SUCCESS);

return EXIT_SUCCESS;
}

//---------------------------------------------------------------------------------------------------
// EntryPoint
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwCallReason, LPVOID x)
{
UNREFERENCED_PARAMETER(x);

if (dwCallReason == DLL_PROCESS_ATTACH)
{

DisableThreadLibraryCalls(hModule);

HANDLE pHand = CreateThread(0, 0, MainThread, hModule, 0, 0);

if (pHand)
CloseHandle(pHand);

}

return TRUE;
}

0 comments on commit b2ae5a4

Please sign in to comment.