diff --git a/DPLFusionFix.sln b/DPLFusionFix.sln
index 010de25..6040cec 100644
--- a/DPLFusionFix.sln
+++ b/DPLFusionFix.sln
@@ -7,18 +7,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DPLFusionFix", "DPLFusionFi
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
- Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x64.ActiveCfg = Debug|x64
- {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x64.Build.0 = Debug|x64
{B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x86.ActiveCfg = Debug|Win32
{B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Debug|x86.Build.0 = Debug|Win32
- {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x64.ActiveCfg = Release|x64
- {B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x64.Build.0 = Release|x64
{B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x86.ActiveCfg = Release|Win32
{B2AC0793-8C00-4E71-95DC-CC50A879BE2A}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
diff --git a/DPLFusionFix/DPLFusionFix.vcxproj b/DPLFusionFix/DPLFusionFix.vcxproj
index 7401c6d..cebaeb1 100644
--- a/DPLFusionFix/DPLFusionFix.vcxproj
+++ b/DPLFusionFix/DPLFusionFix.vcxproj
@@ -9,49 +9,28 @@
Release
Win32
-
- Debug
- x64
-
-
- Release
- x64
-
15.0
{B2AC0793-8C00-4E71-95DC-CC50A879BE2A}
Win32Proj
DPLFusionFix
- 10.0.22621.0
+ 10.0
DynamicLibrary
true
- v141
+ v145
MultiByte
DynamicLibrary
false
- v141
+ v145
true
MultiByte
-
- DynamicLibrary
- true
- v141
- Unicode
-
-
- DynamicLibrary
- false
- v141
- true
- Unicode
-
@@ -63,27 +42,15 @@
-
-
-
-
-
-
true
.asi
-
- true
-
false
.asi
-
- false
-
NotUsing
@@ -102,22 +69,6 @@
dinput8.lib
-
-
- Use
- Level3
- Disabled
- true
- _DEBUG;DPLFUSIONFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
- pch.h
-
-
- Windows
- true
- false
-
-
NotUsing
@@ -140,26 +91,6 @@
dinput8.lib
-
-
- Use
- Level3
- MaxSpeed
- true
- true
- true
- NDEBUG;DPLFUSIONFIX_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
- true
- pch.h
-
-
- Windows
- true
- true
- true
- false
-
-
@@ -239,7 +170,6 @@
-
@@ -300,11 +230,8 @@
Create
- Create
Create
- Create
-
diff --git a/DPLFusionFix/DPLFusionFix.vcxproj.filters b/DPLFusionFix/DPLFusionFix.vcxproj.filters
index c713b8d..e1b9a92 100644
--- a/DPLFusionFix/DPLFusionFix.vcxproj.filters
+++ b/DPLFusionFix/DPLFusionFix.vcxproj.filters
@@ -33,9 +33,6 @@
Header files
-
- External
-
External\utils
@@ -422,9 +419,6 @@
dpl
-
- External
-
dpl
diff --git a/DPLFusionFix/HooksClass.cpp b/DPLFusionFix/HooksClass.cpp
index fc3e747..054371a 100644
--- a/DPLFusionFix/HooksClass.cpp
+++ b/DPLFusionFix/HooksClass.cpp
@@ -32,8 +32,8 @@ void __declspec(naked) HooksClass::Before_OnEnterGarageState()
// Low the ping in and ping out radius to prevent infinite loading
lfs->m_fPingInRadius = 100;
lfs->m_fPingOutRadius = 115;
- *(float*)(0x6414f8) = lfs->m_fPingInRadius;
- *(float*)(0x641420) = lfs->m_fPingOutRadius;
+ Memory::Patch(0x6414f8, lfs->m_fPingInRadius);
+ Memory::Patch(0x641420, lfs->m_fPingOutRadius);
// Restore registers
__asm
@@ -95,8 +95,8 @@ void __declspec(naked) HooksClass::After_OnEnterGarageState()
// Restore ping in and ping out radius
lfs->m_fPingInRadius = SettingsMgr->fInstances_Spawn_Radius - 10;
lfs->m_fPingOutRadius = SettingsMgr->fInstances_Spawn_Radius;
- *(float*)(0x6414f8) = lfs->m_fPingInRadius;
- *(float*)(0x641420) = lfs->m_fPingOutRadius;
+ Memory::Patch(0x6414f8, lfs->m_fPingInRadius);
+ Memory::Patch(0x641420, lfs->m_fPingOutRadius);
// Restore registers
__asm
@@ -617,8 +617,8 @@ void __declspec(naked) HooksClass::PS2_Glow_SFX_Settings_Patch()
*/
// Code here
- *(int*)(0x976398) = 300; // "Glow pp multiply"
- *(int*)(0x9765A4) = 3; // "Glow filter pass count"
+ Memory::Patch(0x976398, 300); // "Glow pp multiply"
+ Memory::Patch(0x9765A4, 3); // "Glow filter pass count"
/*
static int DAT_00976398 = 0x976398;
diff --git a/DPLFusionFix/core/Vector.cpp b/DPLFusionFix/core/Vector.cpp
index cc63130..3477454 100644
--- a/DPLFusionFix/core/Vector.cpp
+++ b/DPLFusionFix/core/Vector.cpp
@@ -1,6 +1,6 @@
#include "Vector.h"
-inline float RecipSqrt(float x, float y) { return x / sqrt(y); }
+inline float RecipSqrt(float x, float y) { return x / sqrtf(y); }
inline float RecipSqrt(float x) { return RecipSqrt(1.0f, x); }
void Vector::Normalise()
@@ -24,16 +24,16 @@ Vector CrossProduct(const Vector& v1, const Vector& v2)
// Returns the Y axis (in radians) facing a specific vector
float GetYAxisFromDirection(Vector direction)
{
- return atan2(direction.X, direction.Y);
+ return atan2f(direction.X, direction.Y);
}
// Returns a vector with X Y Z axis in radians indicating the direction
void GetAxisVectorFromDirection(Vector direction, Vector& vector)
{
- float x = atan2(direction.Y, GetDistanceBetweenPoints2D(0, 0, direction.X, direction.Z));
+ float x = atan2f(direction.Y, GetDistanceBetweenPoints2D(0, 0, direction.X, direction.Z));
while (x > M_PI*2)
{
- x = x - M_PI*2;
+ x = static_cast(x - M_PI*2);
}
vector.X = x;
vector.Y = GetYAxisFromDirection(direction);
@@ -42,7 +42,7 @@ void GetAxisVectorFromDirection(Vector direction, Vector& vector)
float GetDistanceBetweenPoints2D(float x1, float y1, float x2, float y2)
{
- float dist = pow((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2), 0.5f);
+ float dist = powf((x2 - x1) * powf(x2 - x1, 2) + (y2 - y1) * powf(y2 - y1, 2), 0.5);
if (dist < 0)
dist = 0;
return dist;
@@ -53,8 +53,8 @@ float GetDistanceBetweenPoints3D(float x1, float y1, float z1, float x2, float y
float dx = x2 - x1;
float dy = y2 - y1;
float dz = z2 - z1;
- float dist = sqrt(dx * dx + dy * dy + dz * dz);
+ float dist = sqrtf(dx * dx + dy * dy + dz * dz);
if (dist < 0)
dist = 0;
return dist;
-}
\ No newline at end of file
+}
diff --git a/DPLFusionFix/core/Vector.h b/DPLFusionFix/core/Vector.h
index f2e9134..2316546 100644
--- a/DPLFusionFix/core/Vector.h
+++ b/DPLFusionFix/core/Vector.h
@@ -14,10 +14,10 @@ class Vector
Y = b;
Z = c;
}
- float Heading(void) const { return atan2(-X, Y); }
- float Magnitude(void) const { return sqrt(X * X + Y * Y + Z * Z); }
+ float Heading(void) const { return atan2f(-X, Y); }
+ float Magnitude(void) const { return sqrtf(X * X + Y * Y + Z * Z); }
float MagnitudeSqr(void) const { return X * X + Y * Y + Z * Z; }
- float Magnitude2D(void) const { return sqrt(X * X + Y * Y); }
+ float Magnitude2D(void) const { return sqrtf(X * X + Y * Y); }
float MagnitudeSqr2D(void) const { return X * X + Y * Y; }
void Normalise();
Vector Lerp(const Vector& target, float t) const {
diff --git a/DPLFusionFix/dllmain.cpp b/DPLFusionFix/dllmain.cpp
index 0485fb5..29bb770 100644
--- a/DPLFusionFix/dllmain.cpp
+++ b/DPLFusionFix/dllmain.cpp
@@ -1,5 +1,5 @@
#include "pch.h"
-#include "utils.h"
+#include "utils/MemoryMgr.h"
#include "Settings.h"
#include "GameChangableSettingsClass.h"
#include "HooksClass.h"
@@ -15,21 +15,23 @@
#define HWND_Height 600
#define HWND_Style WS_OVERLAPPEDWINDOW //WS_POPUP | WS_CAPTION | WS_SYSMENU
+using namespace Memory::VP;
+
void OnInitializePlugin()
{
// Patches based on settings
if (SettingsMgr != NULL)
{
// ping in & ping out radius
- *(float*)(0x6414f8) = SettingsMgr->fInstances_Spawn_Radius - INSTANCES_SPAWN_RADIUS_PING_IN_OFFSET;
- *(float*)(0x641420) = SettingsMgr->fInstances_Spawn_Radius;
+ Patch(0x6414f8, SettingsMgr->fInstances_Spawn_Radius - INSTANCES_SPAWN_RADIUS_PING_IN_OFFSET);
+ Patch(0x641420, SettingsMgr->fInstances_Spawn_Radius);
- *(float*)(0x6dd660) = SettingsMgr->fVehicles_HeadLight_DegreesAngle;
+ Patch(0x6dd660, SettingsMgr->fVehicles_HeadLight_DegreesAngle);
// float _11SDrawHelper$m_draw_distance[3]
- *(float*)(0x6cfcb4) = SettingsMgr->fDraw_Distance1;
- *(float*)(0x6cfcb4 + 4) = SettingsMgr->fDraw_Distance2;
- *(float*)(0x6cfcb4 + 8) = SettingsMgr->fDraw_Distance3;
+ Patch(0x6cfcb4, SettingsMgr->fDraw_Distance1);
+ Patch(0x6cfcb4 + 4, SettingsMgr->fDraw_Distance2);
+ Patch(0x6cfcb4 + 8, SettingsMgr->fDraw_Distance3);
// show console if the settings allow
if (SettingsMgr->bShow_Console_Output)
@@ -43,14 +45,14 @@ void OnInitializePlugin()
{
printf("Windowed mode on\n");
Nop(0x575680, 33); // before the hook, to disable the other code stuff
- InjectHook(0x57567C, CreateCustomWindow, PATCH_CALL); // windowed mode / custom window
+ InjectHook(0x57567C, CreateCustomWindow, HookType::Call); // windowed mode / custom window
// windowMode = SW_SHOWNORMAL
- Patch(0x5FE99F + 1, 1);
+ Patch(0x5FE99F + 1, 1);
if (SettingsMgr->bPause_Game_In_Windowed_Mode == false)
{
- WriteAt(0x57168B + 3, "\x00", 1); // all thanks to my ol' helper - Cheat Engine!
+ Patch(0x57168B + 3, 0x00); // all thanks to my ol' helper - Cheat Engine!
}
}
@@ -67,20 +69,20 @@ void OnInitializePlugin()
// Default patches
- WritePointerAt(0x442b4c + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensityBaseNoPingInRadius));
- WritePointerAt(0x442b44 + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensityPingMultiplier));
- WritePointerAt(0x4485f5 + 4, reinterpret_cast(&GameChangableSettings::g_fPedDensitySubtractionNoPingInRadius));
- WritePointerAt(0x448346 + 4, reinterpret_cast(&GameChangableSettings::g_fPedPingOut));
- WritePointerAt(0x448356 + 4, reinterpret_cast(&GameChangableSettings::g_fPedPingIn));
- WritePointerAt(0x404275 + 3, reinterpret_cast(&GameChangableSettings::g_fAICivilianCarGiveUpJourneySquareDistance));
+ Patch(0x442b4c + 4, &GameChangableSettings::g_fPedDensityBaseNoPingInRadius);
+ Patch(0x442b44 + 4, &GameChangableSettings::g_fPedDensityPingMultiplier);
+ Patch(0x4485f5 + 4, &GameChangableSettings::g_fPedDensitySubtractionNoPingInRadius);
+ Patch(0x448346 + 4, &GameChangableSettings::g_fPedPingOut);
+ Patch(0x448356 + 4, &GameChangableSettings::g_fPedPingIn);
+ Patch(0x404275 + 3, &GameChangableSettings::g_fAICivilianCarGiveUpJourneySquareDistance);
if (SettingsMgr->bHighPoly_Civilian_Cars)
{
// civilian cars' rendering priority is set to 0x5 (eVehiclePriorityForeground or eVehicleControlScripted)
- WriteAt(0x40d64c + 1, "\x05", 1); // PARKED CARS - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
- WriteAt(0x4107dd + 1, "\x05", 1); // VIRTUAL PING IN - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
- WriteAt(0x410b0f + 1, "\x05", 1); // ??? - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
- WriteAt(0x412b1e + 1, "\x05", 1); // AIManagerClass step - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
+ Patch(0x40d64c + 1, 0x05); // PARKED CARS - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
+ Patch(0x4107dd + 1, 0x05); // VIRTUAL PING IN - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
+ Patch(0x410b0f + 1, 0x05); // ??? - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
+ Patch(0x412b1e + 1, 0x05); // AIManagerClass step - AIVehicleClass::vehicleSetRenderingPriority(..., eVehiclePriorityForeground);
}
// TODO: maybe fix this... it's for the complete mission debug option
@@ -99,9 +101,9 @@ void OnInitializePlugin()
//WritePointerAt(0x471f54 + 4, reinterpret_cast(&GameChangableSettings::g_fInstances_Ping_In));
//WritePointerAt(0x471f61 + 4, reinterpret_cast(&GameChangableSettings::g_fInstances_Ping_Out));
- *(float*)(0x6778e0) = GameChangableSettings::g_fAICivilianCarTopSpeedForward;
- *(float*)(0x6778dc) = GameChangableSettings::g_fAICivilianCarTopSpeedReverse;
- *(float*)(0x6778d8) = GameChangableSettings::g_fAICivilianCarGainGrad;
+ Memory::Patch(0x6778e0, GameChangableSettings::g_fAICivilianCarTopSpeedForward);
+ Memory::Patch(0x6778dc, GameChangableSettings::g_fAICivilianCarTopSpeedReverse);
+ Memory::Patch(0x6778d8, GameChangableSettings::g_fAICivilianCarGainGrad);
if (SettingsMgr->bPS2_Glow_Effects_Settings)
{
@@ -109,58 +111,58 @@ void OnInitializePlugin()
Nop(0x5ecc3b, 6);
Nop(0x5ed472, 6);
- InjectHook(0x5ecc3b, HooksClass::PS2_Glow_SFX_Settings_Patch, PATCH_JUMP);
+ InjectHook(0x5ecc3b, HooksClass::PS2_Glow_SFX_Settings_Patch, HookType::Jump);
}
// HOOKS
// Potentially causing garage crashes for some people
- //InjectHook(0x465721, HooksClass::Before_OnEnterGarageState, PATCH_JUMP);
+ //InjectHook(0x465721, HooksClass::Before_OnEnterGarageState, HookType::Jump);
//Nop(0x465e30, 7);
- //InjectHook(0x465e30, HooksClass::After_OnEnterGarageState, PATCH_JUMP);
+ //InjectHook(0x465e30, HooksClass::After_OnEnterGarageState, HookType::Jump);
Nop(0x4c4cb9, 9);
- InjectHook(0x4c4cb9, HooksClass::ProcessCommandExtension_Frontend, PATCH_JUMP);
+ InjectHook(0x4c4cb9, HooksClass::ProcessCommandExtension_Frontend, HookType::Jump);
Nop(0x45acc4, 7);
- InjectHook(0x45acc4, &HooksClass::GameSimulationStep, PATCH_JUMP);
+ InjectHook(0x45acc4, &HooksClass::GameSimulationStep, HookType::Jump);
Nop(0x4def78, 6);
- InjectHook(0x4def78, &HooksClass::SimulationDraw, PATCH_JUMP);
+ InjectHook(0x4def78, &HooksClass::SimulationDraw, HookType::Jump);
// this will fix some crashes when going on Era change or back to the menu
if (SettingsMgr->bHeapFree_Validation_Fix)
{
- WriteAt(0x5fc7e6 + 1, "\x09", 1);
+ Patch(0x5fc7e6 + 1, 0x09);
Nop(0x5fc7e3, 3);
Nop(0x5fc7f1, 9);
- InjectHook(0x5fc7f1, HooksClass::HeapFree_Fix_Validation, PATCH_JUMP);
+ InjectHook(0x5fc7f1, HooksClass::HeapFree_Fix_Validation, HookType::Jump);
}
// likely unused by the game
- //InjectHook(0x4a80c9, &CState_Frontend::OnEnterState, PATCH_CALL);
+ //InjectHook(0x4a80c9, &CState_Frontend::OnEnterState, HookType::Call);
if (SettingsMgr->bLoad_Frontend_Dev_Menu)
{
Nop(0x4aa075, 6);
- InjectHook(0x4aa075, &HooksClass::Custom_Load_Dev_Menu, PATCH_JUMP);
+ InjectHook(0x4aa075, &HooksClass::Custom_Load_Dev_Menu, HookType::Jump);
}
if (SettingsMgr->bClassic_BurnOut)
{
Nop(0x5AF86C, 5);
- InjectHook(0x5AF86C, &HooksClass::Classic_BurnOut_Hook, PATCH_JUMP);
+ InjectHook(0x5AF86C, &HooksClass::Classic_BurnOut_Hook, HookType::Jump);
}
if (SettingsMgr->bPlayer_Can_Use_Turn_Signal)
{
Nop(0x49f986, 6);
- InjectHook(0x49f986, &HooksClass::Turn_Signal_Feature, PATCH_JUMP);
+ InjectHook(0x49f986, &HooksClass::Turn_Signal_Feature, HookType::Jump);
}
// HRESULT __fastcall EndScene__i4HRESULT(CViewport *viewport)
//Nop(0x5e455b, 15); // nop all except 'ret' (return)
- //InjectHook(0x5e455b, &HooksClass::D3DDevice_EndScene_Patches, PATCH_JUMP); // re-direct the function to ours, like a thunk function
+ //InjectHook(0x5e455b, &HooksClass::D3DDevice_EndScene_Patches, HookType::Jump); // re-direct the function to ours, like a thunk function
//InjectHook(0x4b7f36, HooksClass::GameOverlays_DrawHooked_Debug);
@@ -169,25 +171,25 @@ void OnInitializePlugin()
if (SettingsMgr->bDev_Menu_On)
{
- WriteAt(0x459f8e + 1, "\x01", 1); // pause_devMenuBTN->SetRenderState(1);
+ Patch(0x459f8e + 1, 0x01); // pause_devMenuBTN->SetRenderState(1);
// NOTE: for your safety you better not access frontend dev menu!
// it will crash the game, so stick to the pause menu dev menu :/
- WriteAt(0x4aa522 + 1, "\x01", 1); // frontend_devMenuBTN->SetRenderState(1);
-
+ Patch(0x4aa522 + 1, 0x01); // frontend_devMenuBTN->SetRenderState(1);
+
//Nop(0x4aa3f2, 9); // disable launch_dev_menu
//Nop(0x459f8c, 14);
}
if (SettingsMgr->bMinimap_Driver3_Goons)
{
- WriteAt(0x4bdf71 + 3, "\x4C", 1); // ambColour.Y = 0;
- //WriteAt(0x4bdf92 + 7, "\x05\x00\x35", 4); // instance.hModel = MinimapIcon_AlertedCop;
+ Patch(0x4bdf71 + 3, 0x4C); // ambColour.Y = 0;
+ //Patch(0x4bdf92 + 7, {0x05, 0x00, 0x35, 0x00}); // instance.hModel = MinimapIcon_AlertedCop;
// Prevent the player icon into becoming one of them
Nop(0x4bdf47, 6);
- InjectHook(0x4bdf47, HooksClass::OnCase_EMapItem_Player_CustomBlock, PATCH_JUMP);
+ InjectHook(0x4bdf47, HooksClass::OnCase_EMapItem_Player_CustomBlock, HookType::Jump);
Nop(0x4bdf92, 11);
- InjectHook(0x4bdf92, HooksClass::DrawMapItem_ModelCheck, PATCH_JUMP);
+ InjectHook(0x4bdf92, HooksClass::DrawMapItem_ModelCheck, HookType::Jump);
}
printf("DPLFusionFix is initialized\n");
diff --git a/DPLFusionFix/dllmain.h b/DPLFusionFix/dllmain.h
index adf8e66..40cec7d 100644
--- a/DPLFusionFix/dllmain.h
+++ b/DPLFusionFix/dllmain.h
@@ -8,6 +8,3 @@ static float g_fPedDensitySubtractionNoPingInRadius;
static float g_fPedDensityDensityMultiplier;
HWND CreateCustomWindow(HINSTANCE hamsterModule, DWORD zero);
-
-void WriteAt(unsigned int address, const char* buffer, size_t size);
-void WriteAt(unsigned int address, int integer);
diff --git a/DPLFusionFix/dpl/Character.cpp b/DPLFusionFix/dpl/Character.cpp
index b00d7af..35451a7 100644
--- a/DPLFusionFix/dpl/Character.cpp
+++ b/DPLFusionFix/dpl/Character.cpp
@@ -275,9 +275,9 @@ CWeapon* CCharacter::GetWeapon()
return (CWeapon*)((int)this + 208);
}
-int CCharacter::GetPointer()
+uintptr_t CCharacter::GetPointer()
{
- return (int)(this);
+ return (uintptr_t)(this);
}
int CCharacter::GetVTableAddress()
@@ -334,8 +334,9 @@ void CCharacter::SetIsSpawned(bool spawned)
bool CCharacter::IsValid()
{
+ // FIXME: What is this trying to do?
try {
- return (this && *(int*)(this->GetPointer())) == 0x64E928;
+ return this->GetPointer() == uintptr_t(0x64E928);
}
catch (std::exception ex) {
return false;
diff --git a/DPLFusionFix/dpl/Character.h b/DPLFusionFix/dpl/Character.h
index 4ab9e60..5827247 100644
--- a/DPLFusionFix/dpl/Character.h
+++ b/DPLFusionFix/dpl/Character.h
@@ -63,7 +63,7 @@ class CCharacter {
void SetAnimType(int type);
int* GetAnimTypePointer();
- int GetPointer();
+ uintptr_t GetPointer();
int GetVTableAddress();
void DrawCrosshair(int Viewport, int unk);
diff --git a/DPLFusionFix/dpl/DebugOptions.cpp b/DPLFusionFix/dpl/DebugOptions.cpp
index 9177fc6..93490d6 100644
--- a/DPLFusionFix/dpl/DebugOptions.cpp
+++ b/DPLFusionFix/dpl/DebugOptions.cpp
@@ -1,5 +1,7 @@
#include "DebugOptions.h"
+using namespace Memory::VP;
+
bool bDebug_ShowVersion = false;
bool bDebug_ShowFPS = false;
bool bDebug_CompleteMission = false;
@@ -22,11 +24,11 @@ void Update_Debug_DisableLoadingScreen()
{
if (bDebug_DisableLoadingScreen)
{
- WriteAt(0x4a76ef, "\xC2\x04\x00", 3);
+ Patch(0x4a76ef, {0xC2, 0x04, 0x00});
}
else
{
- WriteAt(0x4a76ef, "\x56\x8B\xF1", 3);
+ Patch(0x4a76ef, {0x56, 0x8B, 0xF1});
}
}
@@ -35,32 +37,32 @@ void Update_Debug_InvincibleToWater()
if (bDebug_InvincibleToWater)
{
Nop(0x4A268D, 6);
- InjectHook(0x4A268D, 0x4A27A5, PATCH_JUMP);
+ InjectHook(0x4A268D, 0x4A27A5, HookType::Jump);
}
else
{
- WriteAt(0x4A268D, "\x0F\x84\x12\x01\x00\x00", 6);
+ Patch(0x4A268D, {0x0F, 0x84, 0x12, 0x01, 0x00, 0x00});
}
}
void Set_Debug_Cop2006InitWep(char newOne)
{
- WriteAt(0x430046 + 0x1, &newOne, 1);
+ Patch(0x430046 + 0x1, newOne);
}
void Set_Debug_Cop1978InitWep(char newOne)
{
- WriteAt(0x43004a + 0x1, &newOne, 1);
+ Patch(0x43004a + 0x1, newOne);
}
void Update_Debug_NoCollisions()
{
if (bDebug_NoCollisions)
{
- WriteAt(0x5ccd9d, "\xc3", 1);
+ Patch(0x5ccd9d, 0xc3);
}
else
{
- WriteAt(0x5ccd9d, "\x55", 1);
+ Patch(0x5ccd9d, 0x55);
}
-}
\ No newline at end of file
+}
diff --git a/DPLFusionFix/dpl/DebugOptions.h b/DPLFusionFix/dpl/DebugOptions.h
index fa786d8..6e67368 100644
--- a/DPLFusionFix/dpl/DebugOptions.h
+++ b/DPLFusionFix/dpl/DebugOptions.h
@@ -1,5 +1,5 @@
#pragma once
-#include "..\utils.h"
+#include "../utils/MemoryMgr.h"
extern bool bDebug_ShowVersion;
extern bool bDebug_ShowFPS;
diff --git a/DPLFusionFix/dpl/EAnimStates.h b/DPLFusionFix/dpl/EAnimStates.h
index 89f5e8d..282fdbb 100644
--- a/DPLFusionFix/dpl/EAnimStates.h
+++ b/DPLFusionFix/dpl/EAnimStates.h
@@ -14,7 +14,7 @@ enum EnumAnimCondition {
eACond_End = 6
};
-typedef enum eAnimState {
+enum eAnimState {
eAState_Undef = -2,
eAState_Bad = -1,
eAState_Invalid = -1,
diff --git a/DPLFusionFix/dpl/FontManager.cpp b/DPLFusionFix/dpl/FontManager.cpp
index 01a8d0d..4a426bb 100644
--- a/DPLFusionFix/dpl/FontManager.cpp
+++ b/DPLFusionFix/dpl/FontManager.cpp
@@ -80,7 +80,8 @@ void CFontManager::PrintFast(Vector4* dimensions, CPCViewport* piView, FontSpecs
void CFontManager::Print(Vector4* dimensions, AutoPtr piView, FontSpecs *spec, const wchar_t* szFormat, int unk1)
{
- Print(dimensions, piView, spec, (wchar_t*)szFormat, unk1);
+ //Print(dimensions, piView, spec, (wchar_t*)szFormat, unk1);
+ // FIXME: Broken function that infinitely calls itself
}
void CFontManager::Print(Vector4* dimensions, CPCViewport* piView, FontSpecs *spec, const wchar_t* szFormat, int unk1)
diff --git a/DPLFusionFix/dpl/FontManager.h b/DPLFusionFix/dpl/FontManager.h
index 376a0f3..3f42f00 100644
--- a/DPLFusionFix/dpl/FontManager.h
+++ b/DPLFusionFix/dpl/FontManager.h
@@ -13,7 +13,7 @@ enum EJustify {
};
struct FontSpecs {
- struct Vector4 colour { 1, 1, 1, 1 };
+ Vector4 colour { 1, 1, 1, 1 };
int fontType;
int textType;
float x;
diff --git a/DPLFusionFix/dpl/GameOverlayManager.h b/DPLFusionFix/dpl/GameOverlayManager.h
index 44486f1..041d010 100644
--- a/DPLFusionFix/dpl/GameOverlayManager.h
+++ b/DPLFusionFix/dpl/GameOverlayManager.h
@@ -146,7 +146,7 @@ struct CMapMarkers {
};
struct SGameOverlayGraphic {
- struct Vector4 vColour;
+ Vector4 vColour;
float fX;
float fY;
float fW;
diff --git a/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h b/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h
index 5725d17..ed581d7 100644
--- a/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h
+++ b/DPLFusionFix/dpl/HACK_VehicleTypeSelection.h
@@ -10,7 +10,7 @@ struct sNameToEVehicleType
extern int* _22VEHICLE_SELECTION_HACK$currentVehicle;
extern int* _22VEHICLE_SELECTION_HACK$currentVehicleType;
-static class VEHICLE_SELECTION_HACK
+class VEHICLE_SELECTION_HACK
{
public:
static sNameToEVehicleType* GetVehicleTypeMatchTable();
@@ -20,4 +20,4 @@ static class VEHICLE_SELECTION_HACK
static int GetNumVehicles();
static char* GetCurrentVehicleName();
-};
\ No newline at end of file
+};
diff --git a/DPLFusionFix/dpl/LevelList.h b/DPLFusionFix/dpl/LevelList.h
index 01031fb..4b81506 100644
--- a/DPLFusionFix/dpl/LevelList.h
+++ b/DPLFusionFix/dpl/LevelList.h
@@ -4,8 +4,8 @@
class CLevelList
{
public:
- unsigned int m_uCurrentLevel;
- unsigned int m_uLevels;
+ int m_uCurrentLevel;
+ int m_uLevels;
char* buffer;
char* GetLevelName(int nLevel);
diff --git a/DPLFusionFix/dpl/LifeProgression.h b/DPLFusionFix/dpl/LifeProgression.h
index d772b08..e3e1a65 100644
--- a/DPLFusionFix/dpl/LifeProgression.h
+++ b/DPLFusionFix/dpl/LifeProgression.h
@@ -15,8 +15,8 @@ struct CLifeEventList {
uint8_t field7_0xd;
uint8_t field8_0xe;
uint8_t field9_0xf;
- struct Matrix m_restartPosition;
- struct Vector4 v4Position;
+ Matrix m_restartPosition;
+ Vector4 v4Position;
unsigned int eventType;
char *filename;
struct LocalisedString *m_eventName;
diff --git a/DPLFusionFix/dpl/State_Frontend.cpp b/DPLFusionFix/dpl/State_Frontend.cpp
index 93ef2c4..0157769 100644
--- a/DPLFusionFix/dpl/State_Frontend.cpp
+++ b/DPLFusionFix/dpl/State_Frontend.cpp
@@ -1010,7 +1010,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame
GetGameMenuLink()->SetValue(currentChar);
}
- uint32_t num_options = 0;
+ int num_options = 0;
if (m_eDebugOptionsType == eDebugOptions_Game)
{
num_options = sizeof(m_pszGameDebugOptions) / 4;
@@ -1052,7 +1052,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame
int option_idx = GetDebugOptionIndex(szCommand);
if (option_idx != -1)
{
- uint32_t option_num = (m_debugOffset + option_idx);
+ int option_num = (m_debugOffset + option_idx);
char* optName = NULL;
SDebugOption* ogopt = NULL;
@@ -1101,7 +1101,7 @@ void CState_Frontend::ProcessCommand_Development(char *szCommand, char *szParame
// Make the debug options be changed
if (m_debugOption >= 0 && m_debugOption < total_num_options)
{
- uint32_t option_num = (m_debugOption + m_debugOffset);
+ int option_num = (m_debugOption + m_debugOffset);
char* optName = NULL;
SDebugOption* ogopt = NULL;
diff --git a/DPLFusionFix/dpl/State_VEdit.cpp b/DPLFusionFix/dpl/State_VEdit.cpp
index bab9768..22e2efc 100644
--- a/DPLFusionFix/dpl/State_VEdit.cpp
+++ b/DPLFusionFix/dpl/State_VEdit.cpp
@@ -60,7 +60,7 @@ void CState_VEdit::Step_GarageCamera()
// if input down or input up is not pressed within the dead-zone
if (inputback < camerainput_deadzone && inputforward < camerainput_deadzone)
{
- static float cord_elevationStep = 0.1f * 0.014959967;
+ static float cord_elevationStep = 0.1f * 0.014959967f;
if (*m_DisplayElevate < -cord_elevationStep)
*m_DisplayElevate += cord_elevationStep; // push camera up
@@ -69,17 +69,17 @@ void CState_VEdit::Step_GarageCamera()
}
if (inputleft > camerainput_deadzone) {
- *m_DisplayRotate = *m_DisplayRotate + (inputleft * 0.014959967);
+ *m_DisplayRotate = *m_DisplayRotate + (inputleft * 0.014959967f);
}
else if (inputright > camerainput_deadzone) {
- *m_DisplayRotate = *m_DisplayRotate - (inputright * 0.014959967);
+ *m_DisplayRotate = *m_DisplayRotate - (inputright * 0.014959967f);
}
if (inputback > camerainput_deadzone) {
- *m_DisplayElevate = *m_DisplayElevate - (inputback * 0.014959967);
+ *m_DisplayElevate = *m_DisplayElevate - (inputback * 0.014959967f);
}
else if (inputforward > camerainput_deadzone) {
- *m_DisplayElevate = *m_DisplayElevate + (inputforward * 0.014959967);
+ *m_DisplayElevate = *m_DisplayElevate + (inputforward * 0.014959967f);
}
// if rotation is greater than 360 degrees then reset the angle (no effect)
@@ -90,7 +90,7 @@ void CState_VEdit::Step_GarageCamera()
// if rotation is less than 0 then set the angle to 360 degrees (no effect)
if (*m_DisplayRotate < 0)
{
- *m_DisplayRotate = M_PI * 2;
+ *m_DisplayRotate = static_cast(M_PI * 2);
}
// clamp elevation (approx -5.6 degrees to +22.5 degrees in radians)
diff --git a/DPLFusionFix/dpl/Vector4.cpp b/DPLFusionFix/dpl/Vector4.cpp
index 05e935a..0024945 100644
--- a/DPLFusionFix/dpl/Vector4.cpp
+++ b/DPLFusionFix/dpl/Vector4.cpp
@@ -89,7 +89,7 @@ float GetDistanceBetweenPoints3D(Vector4 v1, Vector4 v2)
float x2 = v2.X;
float y2 = v2.Y;
float z2 = v2.Z;
- float dist = pow((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2) + (z2 - z1) * (z2 - z1), 0.5f);
+ float dist = static_cast(((x2 - x1) * pow(x2 - x1, 2) + (y2 - y1) * pow(y2 - y1, 2) + (z2 - z1) * (z2 - z1), 0.5f));
if (dist < 0)
dist = 0;
return dist;
diff --git a/DPLFusionFix/dpl/common.cpp b/DPLFusionFix/dpl/common.cpp
index 2e1e781..f88f7aa 100644
--- a/DPLFusionFix/dpl/common.cpp
+++ b/DPLFusionFix/dpl/common.cpp
@@ -111,8 +111,8 @@ void OnGameStep()
if (SettingsMgr->bWindowed_Mode)
{
HWND hamsterWnd = GetHamsterHWND();
- int width = GetSystemMetrics(SM_CXSCREEN);
- int height = GetSystemMetrics(SM_CYSCREEN);
+ float width = static_cast(GetSystemMetrics(SM_CXSCREEN));
+ float height = static_cast(GetSystemMetrics(SM_CYSCREEN));
if (width != 0 && height != 0)
{
diff --git a/DPLFusionFix/utils.cpp b/DPLFusionFix/utils.cpp
deleted file mode 100644
index 5832a47..0000000
--- a/DPLFusionFix/utils.cpp
+++ /dev/null
@@ -1,25 +0,0 @@
-#include "utils.h"
-
-void WriteAt(unsigned int address, const char* buffer, size_t size)
-{
- DWORD dwProtect;
- VirtualProtect((void*)address, size, PAGE_EXECUTE_READWRITE, &dwProtect);
- memcpy((void*)address, buffer, size);
- VirtualProtect((void*)address, size, dwProtect, &dwProtect);
-}
-
-void WriteAt(unsigned int address, int integer)
-{
- DWORD dwProtect;
- VirtualProtect((void*)address, sizeof(int), PAGE_EXECUTE_READWRITE, &dwProtect);
- memcpy((void*)address, (void*)integer, sizeof(int));
- VirtualProtect((void*)address, sizeof(int), dwProtect, &dwProtect);
-}
-
-void WritePointerAt(unsigned int address, intptr_t ptr)
-{
- DWORD dwProtect;
- VirtualProtect((void*)address, sizeof(ptr), PAGE_EXECUTE_READWRITE, &dwProtect);
- memcpy((void*)address, &ptr, sizeof(ptr));
- VirtualProtect((void*)address, sizeof(ptr), dwProtect, &dwProtect);
-}
\ No newline at end of file
diff --git a/DPLFusionFix/utils.h b/DPLFusionFix/utils.h
deleted file mode 100644
index 1591410..0000000
--- a/DPLFusionFix/utils.h
+++ /dev/null
@@ -1,9 +0,0 @@
-#pragma once
-#include "utils/MemoryMgr.h"
-
-using namespace Memory::VP;
-
-void WriteAt(unsigned int address, const char* buffer, size_t size);
-void WriteAt(unsigned int address, int integer);
-
-void WritePointerAt(unsigned int address, intptr_t ptr);
\ No newline at end of file
diff --git a/DPLFusionFix/utils/MemoryMgr.h b/DPLFusionFix/utils/MemoryMgr.h
index b53cf48..178f1b5 100644
--- a/DPLFusionFix/utils/MemoryMgr.h
+++ b/DPLFusionFix/utils/MemoryMgr.h
@@ -1,91 +1,135 @@
-#ifndef __MEMORYMGR
-#define __MEMORYMGR
+#pragma once
// Switches:
-// _MEMORY_NO_CRT - don't include anything "complex" like ScopedUnprotect or memset
// _MEMORY_DECLS_ONLY - don't include anything but macroes
#define WRAPPER __declspec(naked)
#define DEPRECATED __declspec(deprecated)
+
+#ifdef _MSC_VER
#define EAXJMP(a) { _asm mov eax, a _asm jmp eax }
#define VARJMP(a) { _asm jmp a }
#define WRAPARG(a) ((int)a)
+#else
+#define EAXJMP(a) __asm__ volatile("mov eax, %0\n" "jmp eax" :: "i" (a));
+#define VARJMP(a) __asm__ volatile("jmp %0" :: "m" (a));
+#define WRAPARG(a)
+#endif
+#ifdef _MSC_VER
#define NOVMT __declspec(novtable)
+#else
+#define NOVMT
+#endif
+
#define SETVMT(a) *((uintptr_t*)this) = (uintptr_t)a
#ifndef _MEMORY_DECLS_ONLY
#define WIN32_LEAN_AND_MEAN
-#include
+#include
#include
#include
-#ifndef _MEMORY_NO_CRT
+#include
#include
-#include
-#endif
+#include
-enum
+namespace Memory
{
- PATCH_CALL,
- PATCH_JUMP
-};
+ enum class HookType
+ {
+ Call,
+ Jump,
+ };
-template
-inline AT DynBaseAddress(AT address)
-{
-#ifdef _WIN64
- return (ptrdiff_t)GetModuleHandle(nullptr) - 0x140000000 + address;
-#else
- return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address;
-#endif
-}
+ template
+ inline AT DynBaseAddress(AT address)
+ {
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
+ #ifdef _WIN64
+ return (ptrdiff_t)GetModuleHandle(nullptr) - 0x140000000 + address;
+ #else
+ return (ptrdiff_t)GetModuleHandle(nullptr) - 0x400000 + address;
+ #endif
+ }
-namespace Memory
-{
template
inline void Patch(AT address, T value)
- {*(T*)address = value; }
+ {
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
+ *(T*)address = value;
+ }
-#ifndef _MEMORY_NO_CRT
template
inline void Patch(AT address, std::initializer_list list )
{
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
uint8_t* addr = reinterpret_cast(address);
- std::copy( list.begin(), list.end(), stdext::make_checked_array_iterator(addr, list.size()) );
+ std::copy( list.begin(), list.end(), addr );
+ }
+
+ template
+ inline void Read(AT address, Var& var)
+ {
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
+ var = *(Var*)address;
}
-#endif
template
inline void Nop(AT address, size_t count)
-#ifndef _MEMORY_NO_CRT
- { memset((void*)address, 0x90, count); }
-#else
- { do {
- *(uint8_t*)address++ = 0x90;
- } while ( --count != 0 ); }
-#endif
+ {
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
+ memset((void*)address, 0x90, count);
+ }
- template
- inline void WriteOffsetValue(AT address, Var var)
+ template
+ inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
{
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
intptr_t dstAddr = (intptr_t)address;
intptr_t srcAddr;
memcpy( &srcAddr, std::addressof(var), sizeof(srcAddr) );
- *(int32_t*)dstAddr = static_cast(srcAddr - dstAddr - (4 + extraBytesAfterOffset));
+ *(int32_t*)dstAddr = static_cast(srcAddr - dstAddr - (4 + bytesAfterDisplacement));
}
- template
- inline void ReadOffsetValue(AT address, Var& var)
+ template
+ inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
{
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
intptr_t srcAddr = (intptr_t)address;
- intptr_t dstAddr = srcAddr + (4 + extraBytesAfterOffset) + *(int32_t*)srcAddr;
+ intptr_t dstAddr = srcAddr + (4 + bytesAfterDisplacement) + *(int32_t*)srcAddr;
var = {};
memcpy( std::addressof(var), &dstAddr, sizeof(dstAddr) );
}
+ template
+ inline void WriteMemDisplacement(AT address, Var var, [[maybe_unused]] ptrdiff_t bytesAfterDisplacement = 0)
+ {
+#ifdef _WIN64
+ WriteOffsetValue(address, var, bytesAfterDisplacement);
+#else
+ Patch(address, var);
+#endif
+ }
+
+ template
+ inline void ReadMemDisplacement(AT address, Var& var, [[maybe_unused]] ptrdiff_t bytesAfterDisplacement = 0)
+ {
+#ifdef _WIN64
+ ReadOffsetValue(address, var, bytesAfterDisplacement);
+#else
+ Read(address, var);
+#endif
+ }
+
+ inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ ReadMemDisplacement(address, orig, bytesAfterDisplacement);
+ WriteMemDisplacement(address, std::addressof(var), bytesAfterDisplacement);
+ };
+
template
inline void InjectHook(AT address, Func hook)
{
@@ -93,9 +137,9 @@ namespace Memory
}
template
- inline void InjectHook(AT address, Func hook, unsigned int nType)
+ inline void InjectHook(AT address, Func hook, HookType type)
{
- *(uint8_t*)address = nType == PATCH_JUMP ? 0xE9 : 0xE8;
+ *(uint8_t*)address = type == HookType::Jump ? 0xE9 : 0xE8;
InjectHook(address, hook);
}
@@ -113,36 +157,53 @@ namespace Memory
return reinterpret_cast( addr + offset );
}
-#ifndef _MEMORY_NO_CRT
+ inline auto InterceptCall = [](auto address, auto& func, auto&& hook)
+ {
+ ReadCall(address, func);
+ InjectHook(address, hook);
+ };
+
inline bool MemEquals(uintptr_t address, std::initializer_list val)
{
const uint8_t* mem = reinterpret_cast(address);
- return std::equal( val.begin(), val.end(), stdext::make_checked_array_iterator(mem, val.size()) );
+ return std::equal( val.begin(), val.end(), mem );
}
-#endif
template
inline AT Verify(AT address, uintptr_t expected)
{
+ static_assert(sizeof(AT) == sizeof(uintptr_t), "AT must be pointer sized");
assert( uintptr_t(address) == expected );
return address;
}
namespace DynBase
{
+ enum class HookType
+ {
+ Call,
+ Jump,
+ };
+
+ using Memory::DynBaseAddress;
+
template
inline void Patch(AT address, T value)
{
Memory::Patch(DynBaseAddress(address), value);
}
-#ifndef _MEMORY_NO_CRT
template
inline void Patch(AT address, std::initializer_list list )
{
Memory::Patch(DynBaseAddress(address), std::move(list));
}
-#endif
+
+ template
+ inline void Read(AT address, Var& var)
+ {
+ Memory::Read(DynBaseAddress(address), var);
+ }
template
inline void Nop(AT address, size_t count)
@@ -150,28 +211,45 @@ namespace Memory
Memory::Nop(DynBaseAddress(address), count);
}
- template
- inline void WriteOffsetValue(AT address, Var var)
+ template
+ inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
{
- Memory::WriteOffsetValue(DynBaseAddress(address), var);
+ Memory::WriteOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement);
}
- template
- inline void ReadOffsetValue(AT address, Var& var)
+ template< typename Var, typename AT>
+ inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
{
- Memory::ReadOffsetValue(DynBaseAddress(address), var);
+ Memory::ReadOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement);
}
- template
- inline void InjectHook(AT address, HT hook)
+ template
+ inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ Memory::WriteMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement);
+ }
+
+ template
+ inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ Memory::ReadMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement);
+ }
+
+ inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ Memory::InterceptMemDisplacement(DynBaseAddress(address), orig, var, bytesAfterDisplacement);
+ };
+
+ template
+ inline void InjectHook(AT address, Func hook)
{
Memory::InjectHook(DynBaseAddress(address), hook);
}
- template
- inline void InjectHook(AT address, HT hook, unsigned int nType)
+ template
+ inline void InjectHook(AT address, Func hook, HookType type)
{
- Memory::InjectHook(DynBaseAddress(address), hook, nType);
+ Memory::InjectHook(DynBaseAddress(address), hook, static_cast(type));
}
template
@@ -186,7 +264,11 @@ namespace Memory
return Memory::ReadCallFrom(DynBaseAddress(address), offset);
}
-#ifndef _MEMORY_NO_CRT
+ constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook)
+ {
+ Memory::InterceptCall(DynBaseAddress(address), func, hook);
+ };
+
inline bool MemEquals(uintptr_t address, std::initializer_list val)
{
return Memory::MemEquals(DynBaseAddress(address), std::move(val));
@@ -197,11 +279,18 @@ namespace Memory
{
return Memory::Verify(address, DynBaseAddress(expected));
}
-#endif
};
namespace VP
{
+ enum class HookType
+ {
+ Call,
+ Jump,
+ };
+
+ using Memory::DynBaseAddress;
+
template
inline void Patch(AT address, T value)
{
@@ -211,7 +300,6 @@ namespace Memory
VirtualProtect((void*)address, sizeof(T), dwProtect, &dwProtect);
}
-#ifndef _MEMORY_NO_CRT
template
inline void Patch(AT address, std::initializer_list list )
{
@@ -220,7 +308,12 @@ namespace Memory
Memory::Patch(address, std::move(list));
VirtualProtect((void*)address, list.size(), dwProtect, &dwProtect);
}
-#endif
+
+ template
+ inline void Read(AT address, Var& var)
+ {
+ Memory::Read(address, var);
+ }
template
inline void Nop(AT address, size_t count)
@@ -231,24 +324,49 @@ namespace Memory
VirtualProtect((void*)address, count, dwProtect, &dwProtect);
}
- template
- inline void WriteOffsetValue(AT address, Var var)
+ template
+ inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
{
DWORD dwProtect;
VirtualProtect((void*)address, 4, PAGE_EXECUTE_READWRITE, &dwProtect);
- Memory::WriteOffsetValue(address, var);
+ Memory::WriteOffsetValue(address, var, bytesAfterDisplacement);
VirtualProtect((void*)address, 4, dwProtect, &dwProtect);
}
- template
- inline void ReadOffsetValue(AT address, Var& var)
+ template
+ inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
{
- Memory::ReadOffsetValue(address, var);
+ Memory::ReadOffsetValue(address, var, bytesAfterDisplacement);
}
- template
- inline void InjectHook(AT address, HT hook)
+ template
+ inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ DWORD dwProtect;
+
+ VirtualProtect((void*)address, 4, PAGE_EXECUTE_READWRITE, &dwProtect);
+ Memory::WriteMemDisplacement(address, var, bytesAfterDisplacement);
+ VirtualProtect((void*)address, 4, dwProtect, &dwProtect);
+ }
+
+ template
+ inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ Memory::ReadMemDisplacement(address, var, bytesAfterDisplacement);
+ }
+
+ inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ DWORD dwProtect;
+
+ VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect);
+ Memory::InterceptMemDisplacement(address, orig, var, bytesAfterDisplacement);
+ VirtualProtect((void*)address, 5, dwProtect, &dwProtect);
+ };
+
+ template
+ inline void InjectHook(AT address, Func hook)
{
DWORD dwProtect;
@@ -257,13 +375,13 @@ namespace Memory
VirtualProtect((void*)((DWORD_PTR)address + 1), 4, dwProtect, &dwProtect);
}
- template
- inline void InjectHook(AT address, HT hook, unsigned int nType)
+ template
+ inline void InjectHook(AT address, Func hook, HookType type)
{
DWORD dwProtect;
VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect);
- Memory::InjectHook( address, hook, nType );
+ Memory::InjectHook( address, hook, static_cast(type) );
VirtualProtect((void*)address, 5, dwProtect, &dwProtect);
}
@@ -279,12 +397,19 @@ namespace Memory
return Memory::ReadCallFrom(address, offset);
}
-#ifndef _MEMORY_NO_CRT
+ constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook)
+ {
+ DWORD dwProtect;
+
+ VirtualProtect((void*)address, 5, PAGE_EXECUTE_READWRITE, &dwProtect);
+ Memory::InterceptCall(address, func, hook);
+ VirtualProtect((void*)address, 5, dwProtect, &dwProtect);
+ };
+
inline bool MemEquals(uintptr_t address, std::initializer_list val)
{
return Memory::MemEquals(address, std::move(val));
}
-#endif
template
inline AT Verify(AT address, uintptr_t expected)
@@ -294,19 +419,31 @@ namespace Memory
namespace DynBase
{
+ enum class HookType
+ {
+ Call,
+ Jump,
+ };
+
+ using Memory::DynBaseAddress;
+
template
inline void Patch(AT address, T value)
{
VP::Patch(DynBaseAddress(address), value);
}
-#ifndef _MEMORY_NO_CRT
template
inline void Patch(AT address, std::initializer_list list )
{
VP::Patch(DynBaseAddress(address), std::move(list));
}
-#endif
+
+ template
+ inline void Read(AT address, Var& var)
+ {
+ VP::Read(DynBaseAddress(address), var);
+ }
template
inline void Nop(AT address, size_t count)
@@ -314,28 +451,45 @@ namespace Memory
VP::Nop(DynBaseAddress(address), count);
}
- template
- inline void WriteOffsetValue(AT address, Var var)
+ template
+ inline void WriteOffsetValue(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ VP::WriteOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement);
+ }
+
+ template
+ inline void ReadOffsetValue(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
{
- VP::WriteOffsetValue(DynBaseAddress(address), var);
+ VP::ReadOffsetValue(DynBaseAddress(address), var, bytesAfterDisplacement);
}
- template
- inline void ReadOffsetValue(AT address, Var& var)
+ template
+ inline void WriteMemDisplacement(AT address, Var var, ptrdiff_t bytesAfterDisplacement = 0)
{
- VP::ReadOffsetValue(DynBaseAddress(address), var);
+ VP::WriteMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement);
}
- template
- inline void InjectHook(AT address, HT hook)
+ template
+ inline void ReadMemDisplacement(AT address, Var& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ VP::ReadMemDisplacement(DynBaseAddress(address), var, bytesAfterDisplacement);
+ }
+
+ inline auto InterceptMemDisplacement = [](auto address, auto& orig, auto& var, ptrdiff_t bytesAfterDisplacement = 0)
+ {
+ VP::InterceptMemDisplacement(DynBaseAddress(address), orig, var, bytesAfterDisplacement);
+ };
+
+ template
+ inline void InjectHook(AT address, Func hook)
{
VP::InjectHook(DynBaseAddress(address), hook);
}
- template
- inline void InjectHook(AT address, HT hook, unsigned int nType)
+ template
+ inline void InjectHook(AT address, Func hook, HookType type)
{
- VP::InjectHook(DynBaseAddress(address), hook, nType);
+ VP::InjectHook(DynBaseAddress(address), hook, static_cast(type));
}
template
@@ -347,15 +501,18 @@ namespace Memory
template
inline void* ReadCallFrom(AT address, ptrdiff_t offset = 0)
{
- Memory::ReadCallFrom(DynBaseAddress(address), offset);
+ return Memory::ReadCallFrom(DynBaseAddress(address), offset);
}
-#ifndef _MEMORY_NO_CRT
+ constexpr auto InterceptCall = [](auto address, auto& func, auto&& hook)
+ {
+ VP::InterceptCall(DynBaseAddress(address), func, hook);
+ };
+
inline bool MemEquals(uintptr_t address, std::initializer_list val)
{
return Memory::MemEquals(DynBaseAddress(address), std::move(val));
}
-#endif
template
inline AT Verify(AT address, uintptr_t expected)
@@ -367,104 +524,4 @@ namespace Memory
};
};
-#ifndef _MEMORY_NO_CRT
-
-#include
-#include
-#include
-
-namespace ScopedUnprotect
-{
- class Unprotect
- {
- public:
- ~Unprotect()
- {
- for ( auto& it : m_queriedProtects )
- {
- DWORD dwOldProtect;
- VirtualProtect( std::get<0>(it), std::get<1>(it), std::get<2>(it), &dwOldProtect );
- }
- }
-
- protected:
- Unprotect() = default;
-
- void UnprotectRange( DWORD_PTR BaseAddress, SIZE_T Size )
- {
- SIZE_T QueriedSize = 0;
- while ( QueriedSize < Size )
- {
- MEMORY_BASIC_INFORMATION MemoryInf;
- DWORD dwOldProtect;
-
- VirtualQuery( (LPCVOID)(BaseAddress + QueriedSize), &MemoryInf, sizeof(MemoryInf) );
- if ( MemoryInf.State == MEM_COMMIT && (MemoryInf.Type & MEM_IMAGE) != 0 &&
- (MemoryInf.Protect & (PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY|PAGE_READWRITE|PAGE_WRITECOPY)) == 0 )
- {
- const bool wasExecutable = (MemoryInf.Protect & (PAGE_EXECUTE|PAGE_EXECUTE_READ)) != 0;
- VirtualProtect( MemoryInf.BaseAddress, MemoryInf.RegionSize, wasExecutable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &dwOldProtect );
- m_queriedProtects.emplace_front( MemoryInf.BaseAddress, MemoryInf.RegionSize, MemoryInf.Protect );
- }
- QueriedSize += MemoryInf.RegionSize;
- }
- }
-
- private:
- std::forward_list< std::tuple< LPVOID, SIZE_T, DWORD > > m_queriedProtects;
- };
-
- class Section : public Unprotect
- {
- public:
- Section( HINSTANCE hInstance, const char* name )
- {
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
- PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(ntHeader);
-
- for ( SIZE_T i = 0, j = ntHeader->FileHeader.NumberOfSections; i < j; ++i, ++pSection )
- {
- if ( strncmp( (const char*)pSection->Name, name, IMAGE_SIZEOF_SHORT_NAME ) == 0 )
- {
- const DWORD_PTR VirtualAddress = (DWORD_PTR)hInstance + pSection->VirtualAddress;
- const SIZE_T VirtualSize = pSection->Misc.VirtualSize;
- UnprotectRange( VirtualAddress, VirtualSize );
-
- m_locatedSection = true;
- break;
- }
- }
- };
-
- bool SectionLocated() const { return m_locatedSection; }
-
- private:
- bool m_locatedSection = false;
- };
-
- class FullModule : public Unprotect
- {
- public:
- FullModule( HINSTANCE hInstance )
- {
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)hInstance + ((PIMAGE_DOS_HEADER)hInstance)->e_lfanew);
- UnprotectRange( (DWORD_PTR)hInstance, ntHeader->OptionalHeader.SizeOfImage );
- }
- };
-
- inline std::unique_ptr UnprotectSectionOrFullModule( HINSTANCE hInstance, const char* name )
- {
- std::unique_ptr section = std::make_unique( hInstance, name );
- if ( !section->SectionLocated() )
- {
- return std::make_unique( hInstance );
- }
- return section;
- }
-};
-
#endif
-
-#endif
-
-#endif
\ No newline at end of file