Steam proxy
This commit is contained in:
parent
2ea490382b
commit
245cd533d1
2
deps/fmt
vendored
2
deps/fmt
vendored
@ -1 +1 @@
|
||||
Subproject commit 4133e501f3277aeef530b75de2e7bfceca93e5d2
|
||||
Subproject commit 0d5ef5c2a66026409b0cfbafa1d2f46cdc5aa4d0
|
2
deps/mongoose
vendored
2
deps/mongoose
vendored
@ -1 +1 @@
|
||||
Subproject commit 6f7f774080f0c2ec291bfa0a908bc31a923051a1
|
||||
Subproject commit 36a1927915f966f20486a80070f0428f2606a53a
|
2
deps/protobuf
vendored
2
deps/protobuf
vendored
@ -1 +1 @@
|
||||
Subproject commit 790e6afb72ed4ad952d9c74e73ae53a01443fe97
|
||||
Subproject commit 70c1ac756d3cd8fa04725f82f0ad1a30404c3bb3
|
@ -1,254 +1,254 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Dvar::Var Colors::NewColors;
|
||||
std::vector<DWORD> Colors::ColorTable;
|
||||
|
||||
DWORD Colors::HsvToRgb(Colors::HsvColor hsv)
|
||||
{
|
||||
DWORD rgb;
|
||||
unsigned char region, p, q, t;
|
||||
unsigned int h, s, v, remainder;
|
||||
|
||||
if (hsv.s == 0)
|
||||
{
|
||||
rgb = RGB(hsv.v, hsv.v, hsv.v);
|
||||
return rgb;
|
||||
}
|
||||
|
||||
// converting to 16 bit to prevent overflow
|
||||
h = hsv.h;
|
||||
s = hsv.s;
|
||||
v = hsv.v;
|
||||
|
||||
region = static_cast<uint8_t>(h / 43);
|
||||
remainder = (h - (region * 43)) * 6;
|
||||
|
||||
p = static_cast<uint8_t>((v * (255 - s)) >> 8);
|
||||
q = static_cast<uint8_t>((v * (255 - ((s * remainder) >> 8))) >> 8);
|
||||
t = static_cast<uint8_t>((v * (255 - ((s * (255 - remainder)) >> 8))) >> 8);
|
||||
|
||||
switch (region)
|
||||
{
|
||||
case 0:
|
||||
rgb = RGB(v, t, p);
|
||||
break;
|
||||
case 1:
|
||||
rgb = RGB(q, v, p);
|
||||
break;
|
||||
case 2:
|
||||
rgb = RGB(p, v, t);
|
||||
break;
|
||||
case 3:
|
||||
rgb = RGB(p, q, v);
|
||||
break;
|
||||
case 4:
|
||||
rgb = RGB(t, p, v);
|
||||
break;
|
||||
default:
|
||||
rgb = RGB(v, p, q);
|
||||
break;
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void Colors::Strip(const char* in, char* out, int max)
|
||||
{
|
||||
if (!in || !out) return;
|
||||
|
||||
max--;
|
||||
int current = 0;
|
||||
while (*in != 0 && current < max)
|
||||
{
|
||||
char index = *(in + 1);
|
||||
if (*in == '^' && (Colors::ColorIndex(index) != 7 || index == '7'))
|
||||
{
|
||||
++in;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = *in;
|
||||
++out;
|
||||
++current;
|
||||
}
|
||||
|
||||
++in;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
std::string Colors::Strip(std::string in)
|
||||
{
|
||||
char buffer[1000] = { 0 }; // Should be more than enough
|
||||
Colors::Strip(in.data(), buffer, sizeof(buffer));
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
void __declspec(naked) Colors::ClientUserinfoChanged()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h] // length
|
||||
sub eax, 1
|
||||
push eax
|
||||
|
||||
push ecx // name
|
||||
push edx // buffer
|
||||
|
||||
call strncpy
|
||||
|
||||
add esp, 0Ch
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
char* Colors::GetClientName(int localClientNum, int index, char *buf, size_t size)
|
||||
{
|
||||
Game::CL_GetClientName(localClientNum, index, buf, size);
|
||||
|
||||
// Remove the colors
|
||||
strncpy(buf, Colors::Strip(buf).data(), size);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Colors::PatchColorLimit(char limit)
|
||||
{
|
||||
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
||||
Utils::Hook::Set<char>(0x4C1BE4, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x505721, limit); // R_TextWidth
|
||||
Utils::Hook::Set<char>(0x505801, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x50597F, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x5815DB, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x592ED0, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x5A2E2E, limit); // No idea :P
|
||||
|
||||
Utils::Hook::Set<char>(0x5A2733, limit - '0'); // No idea :P
|
||||
}
|
||||
|
||||
char Colors::Add(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
char index = '0' + static_cast<char>(Colors::ColorTable.size());
|
||||
Colors::ColorTable.push_back(RGB(r, g, b));
|
||||
Colors::PatchColorLimit(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
unsigned int Colors::ColorIndex(unsigned char index)
|
||||
{
|
||||
unsigned int result = index - '0';
|
||||
if (result >= Colors::ColorTable.size() || result < 0) result = 7;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Colors::LookupColor(DWORD* color, char index)
|
||||
{
|
||||
*color = RGB(255, 255, 255);
|
||||
|
||||
if (index == '8') // Color 8
|
||||
{
|
||||
*color = *reinterpret_cast<DWORD*>(0x66E5F70);
|
||||
}
|
||||
else if (index == '9') // Color 9
|
||||
{
|
||||
*color = *reinterpret_cast<DWORD*>(0x66E5F74);
|
||||
}
|
||||
else if (index == ':')
|
||||
{
|
||||
*color = Colors::HsvToRgb({ static_cast<uint8_t>((Game::Sys_Milliseconds() / 200) % 256), 255,255 });
|
||||
}
|
||||
else if (index == ';')
|
||||
{
|
||||
float fltColor[4];
|
||||
Game::Dvar_GetUnpackedColorByName("sv_customTextColor", fltColor);
|
||||
*color = RGB(fltColor[0] * 255, fltColor[1] * 255, fltColor[2] * 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
int clrIndex = Colors::ColorIndex(index);
|
||||
|
||||
// Use native colors
|
||||
if (clrIndex <= 7 && !Colors::NewColors.Get<bool>())
|
||||
{
|
||||
*color = reinterpret_cast<DWORD*>(0x78DC70)[index - 48];
|
||||
}
|
||||
else
|
||||
{
|
||||
*color = Colors::ColorTable[clrIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* Colors::CleanStrStub(char* string)
|
||||
{
|
||||
Colors::Strip(string, string, strlen(string) + 1);
|
||||
return string;
|
||||
}
|
||||
|
||||
void __declspec(naked) Colors::LookupColorStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
push [esp + 8h] // Index
|
||||
push esi // Color ref
|
||||
call Colors::LookupColor
|
||||
add esp, 8h
|
||||
pop ebx
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
Colors::Colors()
|
||||
{
|
||||
// Disable SV_UpdateUserinfo_f, to block changing the name ingame
|
||||
Utils::Hook::Set<BYTE>(0x6258D0, 0xC3);
|
||||
|
||||
// Allow colored names ingame
|
||||
Utils::Hook(0x5D8B40, Colors::ClientUserinfoChanged, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Though, don't apply that to overhead names.
|
||||
Utils::Hook(0x581932, Colors::GetClientName, HOOK_CALL).Install()->Quick();
|
||||
|
||||
// Patch RB_LookupColor
|
||||
Utils::Hook(0x534CD0, Colors::LookupColorStub, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Patch ColorIndex
|
||||
Utils::Hook(0x417770, Colors::ColorIndex, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Patch I_CleanStr
|
||||
Utils::Hook(0x4AD470, Colors::CleanStrStub, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Register dvar
|
||||
Colors::NewColors = Dvar::Register<bool>("cg_newColors", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Use Warfare² color code style.");
|
||||
Game::Dvar_RegisterColor("sv_customTextColor", 1, 0.7f, 0, 1, Game::dvar_flag::DVAR_FLAG_REPLICATED, "Color for the extended color code.");
|
||||
|
||||
// Add our colors
|
||||
Colors::Add(0, 0, 0); // 0 - Black
|
||||
Colors::Add(255, 49, 49); // 1 - Red
|
||||
Colors::Add(134, 192, 0); // 2 - Green
|
||||
Colors::Add(255, 173, 34); // 3 - Yellow
|
||||
Colors::Add(0, 135, 193); // 4 - Blue
|
||||
Colors::Add(32, 197, 255); // 5 - Light Blue
|
||||
Colors::Add(151, 80, 221); // 6 - Pink
|
||||
|
||||
Colors::Add(255, 255, 255); // 7 - White
|
||||
|
||||
Colors::Add(0, 0, 0); // 8 - Team color (axis?)
|
||||
Colors::Add(0, 0, 0); // 9 - Team color (allies?)
|
||||
|
||||
// Custom colors
|
||||
Colors::Add(0, 0, 0); // 10 - Rainbow (:)
|
||||
Colors::Add(0, 0, 0); // 11 - Server color (;) - using that color in infostrings (e.g. your name) fails, ';' is an illegal character!
|
||||
}
|
||||
|
||||
Colors::~Colors()
|
||||
{
|
||||
Colors::ColorTable.clear();
|
||||
}
|
||||
}
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
Dvar::Var Colors::NewColors;
|
||||
std::vector<DWORD> Colors::ColorTable;
|
||||
|
||||
DWORD Colors::HsvToRgb(Colors::HsvColor hsv)
|
||||
{
|
||||
DWORD rgb;
|
||||
unsigned char region, p, q, t;
|
||||
unsigned int h, s, v, remainder;
|
||||
|
||||
if (hsv.s == 0)
|
||||
{
|
||||
rgb = RGB(hsv.v, hsv.v, hsv.v);
|
||||
return rgb;
|
||||
}
|
||||
|
||||
// converting to 16 bit to prevent overflow
|
||||
h = hsv.h;
|
||||
s = hsv.s;
|
||||
v = hsv.v;
|
||||
|
||||
region = static_cast<uint8_t>(h / 43);
|
||||
remainder = (h - (region * 43)) * 6;
|
||||
|
||||
p = static_cast<uint8_t>((v * (255 - s)) >> 8);
|
||||
q = static_cast<uint8_t>((v * (255 - ((s * remainder) >> 8))) >> 8);
|
||||
t = static_cast<uint8_t>((v * (255 - ((s * (255 - remainder)) >> 8))) >> 8);
|
||||
|
||||
switch (region)
|
||||
{
|
||||
case 0:
|
||||
rgb = RGB(v, t, p);
|
||||
break;
|
||||
case 1:
|
||||
rgb = RGB(q, v, p);
|
||||
break;
|
||||
case 2:
|
||||
rgb = RGB(p, v, t);
|
||||
break;
|
||||
case 3:
|
||||
rgb = RGB(p, q, v);
|
||||
break;
|
||||
case 4:
|
||||
rgb = RGB(t, p, v);
|
||||
break;
|
||||
default:
|
||||
rgb = RGB(v, p, q);
|
||||
break;
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
void Colors::Strip(const char* in, char* out, int max)
|
||||
{
|
||||
if (!in || !out) return;
|
||||
|
||||
max--;
|
||||
int current = 0;
|
||||
while (*in != 0 && current < max)
|
||||
{
|
||||
char index = *(in + 1);
|
||||
if (*in == '^' && (Colors::ColorIndex(index) != 7 || index == '7'))
|
||||
{
|
||||
++in;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out = *in;
|
||||
++out;
|
||||
++current;
|
||||
}
|
||||
|
||||
++in;
|
||||
}
|
||||
*out = '\0';
|
||||
}
|
||||
|
||||
std::string Colors::Strip(std::string in)
|
||||
{
|
||||
char buffer[1000] = { 0 }; // Should be more than enough
|
||||
Colors::Strip(in.data(), buffer, sizeof(buffer));
|
||||
return std::string(buffer);
|
||||
}
|
||||
|
||||
void __declspec(naked) Colors::ClientUserinfoChanged()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, [esp + 4h] // length
|
||||
sub eax, 1
|
||||
push eax
|
||||
|
||||
push ecx // name
|
||||
push edx // buffer
|
||||
|
||||
call strncpy
|
||||
|
||||
add esp, 0Ch
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
char* Colors::GetClientName(int localClientNum, int index, char *buf, size_t size)
|
||||
{
|
||||
Game::CL_GetClientName(localClientNum, index, buf, size);
|
||||
|
||||
// Remove the colors
|
||||
strncpy_s(buf, size, Colors::Strip(buf).data(), size);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void Colors::PatchColorLimit(char limit)
|
||||
{
|
||||
Utils::Hook::Set<char>(0x535629, limit); // DrawText2d
|
||||
Utils::Hook::Set<char>(0x4C1BE4, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x4863DD, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x486429, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x49A5A8, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x505721, limit); // R_TextWidth
|
||||
Utils::Hook::Set<char>(0x505801, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x50597F, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x5815DB, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x592ED0, limit); // No idea :P
|
||||
Utils::Hook::Set<char>(0x5A2E2E, limit); // No idea :P
|
||||
|
||||
Utils::Hook::Set<char>(0x5A2733, limit - '0'); // No idea :P
|
||||
}
|
||||
|
||||
char Colors::Add(uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
char index = '0' + static_cast<char>(Colors::ColorTable.size());
|
||||
Colors::ColorTable.push_back(RGB(r, g, b));
|
||||
Colors::PatchColorLimit(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
unsigned int Colors::ColorIndex(unsigned char index)
|
||||
{
|
||||
unsigned int result = index - '0';
|
||||
if (result >= Colors::ColorTable.size() || result < 0) result = 7;
|
||||
return result;
|
||||
}
|
||||
|
||||
void Colors::LookupColor(DWORD* color, char index)
|
||||
{
|
||||
*color = RGB(255, 255, 255);
|
||||
|
||||
if (index == '8') // Color 8
|
||||
{
|
||||
*color = *reinterpret_cast<DWORD*>(0x66E5F70);
|
||||
}
|
||||
else if (index == '9') // Color 9
|
||||
{
|
||||
*color = *reinterpret_cast<DWORD*>(0x66E5F74);
|
||||
}
|
||||
else if (index == ':')
|
||||
{
|
||||
*color = Colors::HsvToRgb({ static_cast<uint8_t>((Game::Sys_Milliseconds() / 200) % 256), 255,255 });
|
||||
}
|
||||
else if (index == ';')
|
||||
{
|
||||
float fltColor[4];
|
||||
Game::Dvar_GetUnpackedColorByName("sv_customTextColor", fltColor);
|
||||
*color = RGB(fltColor[0] * 255, fltColor[1] * 255, fltColor[2] * 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
int clrIndex = Colors::ColorIndex(index);
|
||||
|
||||
// Use native colors
|
||||
if (clrIndex <= 7 && !Colors::NewColors.Get<bool>())
|
||||
{
|
||||
*color = reinterpret_cast<DWORD*>(0x78DC70)[index - 48];
|
||||
}
|
||||
else
|
||||
{
|
||||
*color = Colors::ColorTable[clrIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* Colors::CleanStrStub(char* string)
|
||||
{
|
||||
Colors::Strip(string, string, strlen(string) + 1);
|
||||
return string;
|
||||
}
|
||||
|
||||
void __declspec(naked) Colors::LookupColorStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
push ebx
|
||||
push [esp + 8h] // Index
|
||||
push esi // Color ref
|
||||
call Colors::LookupColor
|
||||
add esp, 8h
|
||||
pop ebx
|
||||
retn
|
||||
}
|
||||
}
|
||||
|
||||
Colors::Colors()
|
||||
{
|
||||
// Disable SV_UpdateUserinfo_f, to block changing the name ingame
|
||||
Utils::Hook::Set<BYTE>(0x6258D0, 0xC3);
|
||||
|
||||
// Allow colored names ingame
|
||||
Utils::Hook(0x5D8B40, Colors::ClientUserinfoChanged, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Though, don't apply that to overhead names.
|
||||
Utils::Hook(0x581932, Colors::GetClientName, HOOK_CALL).Install()->Quick();
|
||||
|
||||
// Patch RB_LookupColor
|
||||
Utils::Hook(0x534CD0, Colors::LookupColorStub, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Patch ColorIndex
|
||||
Utils::Hook(0x417770, Colors::ColorIndex, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Patch I_CleanStr
|
||||
Utils::Hook(0x4AD470, Colors::CleanStrStub, HOOK_JUMP).Install()->Quick();
|
||||
|
||||
// Register dvar
|
||||
Colors::NewColors = Dvar::Register<bool>("cg_newColors", true, Game::dvar_flag::DVAR_FLAG_SAVED, "Use Warfare² color code style.");
|
||||
Game::Dvar_RegisterColor("sv_customTextColor", 1, 0.7f, 0, 1, Game::dvar_flag::DVAR_FLAG_REPLICATED, "Color for the extended color code.");
|
||||
|
||||
// Add our colors
|
||||
Colors::Add(0, 0, 0); // 0 - Black
|
||||
Colors::Add(255, 49, 49); // 1 - Red
|
||||
Colors::Add(134, 192, 0); // 2 - Green
|
||||
Colors::Add(255, 173, 34); // 3 - Yellow
|
||||
Colors::Add(0, 135, 193); // 4 - Blue
|
||||
Colors::Add(32, 197, 255); // 5 - Light Blue
|
||||
Colors::Add(151, 80, 221); // 6 - Pink
|
||||
|
||||
Colors::Add(255, 255, 255); // 7 - White
|
||||
|
||||
Colors::Add(0, 0, 0); // 8 - Team color (axis?)
|
||||
Colors::Add(0, 0, 0); // 9 - Team color (allies?)
|
||||
|
||||
// Custom colors
|
||||
Colors::Add(0, 0, 0); // 10 - Rainbow (:)
|
||||
Colors::Add(0, 0, 0); // 11 - Server color (;) - using that color in infostrings (e.g. your name) fails, ';' is an illegal character!
|
||||
}
|
||||
|
||||
Colors::~Colors()
|
||||
{
|
||||
Colors::ColorTable.clear();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -13,11 +13,11 @@ namespace Components
|
||||
{
|
||||
char filename[MAX_PATH];
|
||||
__time64_t time;
|
||||
tm* ltime;
|
||||
tm ltime;
|
||||
|
||||
_time64(&time);
|
||||
ltime = _localtime64(&time);
|
||||
strftime(filename, sizeof(filename) - 1, "iw4x-" VERSION_STR "-%Y%m%d%H%M%S.dmp", ltime);
|
||||
_localtime64_s(<ime, &time);
|
||||
strftime(filename, sizeof(filename) - 1, "iw4x-" VERSION_STR "-%Y%m%d%H%M%S.dmp", <ime);
|
||||
|
||||
HANDLE hFile = CreateFileA(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
|
@ -1,155 +1,155 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::mutex Logger::MessageMutex;
|
||||
std::vector<std::string> Logger::MessageQueue;
|
||||
void(*Logger::PipeCallback)(std::string) = nullptr;
|
||||
|
||||
bool Logger::IsConsoleReady()
|
||||
{
|
||||
return (IsWindow(*reinterpret_cast<HWND*>(0x64A3288)) != FALSE || (Dedicated::IsDedicated() && !Flags::HasFlag("console")));
|
||||
}
|
||||
|
||||
void Logger::Print(const char* message, ...)
|
||||
{
|
||||
return Logger::MessagePrint(0, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::Print(int channel, const char* message, ...)
|
||||
{
|
||||
return Logger::MessagePrint(channel, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::MessagePrint(int channel, std::string message)
|
||||
{
|
||||
if (Flags::HasFlag("stdout") || Loader::PerformingUnitTests())
|
||||
{
|
||||
printf("%s", message.data());
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Logger::IsConsoleReady())
|
||||
{
|
||||
OutputDebugStringA(message.data());
|
||||
}
|
||||
|
||||
if (!Game::Sys_IsMainThread())
|
||||
{
|
||||
Logger::EnqueueMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::Com_PrintMessage(0, message.data(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::ErrorPrint(int error, std::string message)
|
||||
{
|
||||
return Game::Com_Error(error, "%s", message.data());
|
||||
}
|
||||
|
||||
void Logger::Error(int error, const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(error, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::Error(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(0, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::SoftError(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(2, Logger::Format(&message));
|
||||
}
|
||||
|
||||
std::string Logger::Format(const char** message)
|
||||
{
|
||||
char buffer[0x1000] = { 0 };
|
||||
|
||||
va_list ap = reinterpret_cast<char*>(const_cast<char**>(&message[1]));
|
||||
//va_start(ap, *message);
|
||||
_vsnprintf(buffer, sizeof(buffer), *message, ap);
|
||||
va_end(ap);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Logger::Frame()
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
|
||||
for (unsigned int i = 0; i < Logger::MessageQueue.size(); ++i)
|
||||
{
|
||||
Game::Com_PrintMessage(0, Logger::MessageQueue[i].data(), 0);
|
||||
|
||||
if (!Logger::IsConsoleReady())
|
||||
{
|
||||
OutputDebugStringA(Logger::MessageQueue[i].data());
|
||||
}
|
||||
}
|
||||
|
||||
Logger::MessageQueue.clear();
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
|
||||
void Logger::PipeOutput(void(*callback)(std::string))
|
||||
{
|
||||
Logger::PipeCallback = callback;
|
||||
}
|
||||
|
||||
void Logger::PrintMessagePipe(const char* data)
|
||||
{
|
||||
if (Logger::PipeCallback)
|
||||
{
|
||||
Logger::PipeCallback(data);
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Logger::PrintMessageStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, Logger::PipeCallback
|
||||
test eax, eax
|
||||
jz returnPrint
|
||||
|
||||
push [esp + 8h]
|
||||
call Logger::PrintMessagePipe
|
||||
add esp, 4h
|
||||
retn
|
||||
|
||||
returnPrint:
|
||||
push esi
|
||||
mov esi, [esp + 0Ch]
|
||||
|
||||
mov eax, 4AA835h
|
||||
jmp eax
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::EnqueueMessage(std::string message)
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
Logger::MessageQueue.push_back(message);
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
Logger::PipeOutput(nullptr);
|
||||
|
||||
QuickPatch::OnFrame(Logger::Frame);
|
||||
|
||||
Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).Install()->Quick();
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
Logger::MessageQueue.clear();
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
}
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Components
|
||||
{
|
||||
std::mutex Logger::MessageMutex;
|
||||
std::vector<std::string> Logger::MessageQueue;
|
||||
void(*Logger::PipeCallback)(std::string) = nullptr;
|
||||
|
||||
bool Logger::IsConsoleReady()
|
||||
{
|
||||
return (IsWindow(*reinterpret_cast<HWND*>(0x64A3288)) != FALSE || (Dedicated::IsDedicated() && !Flags::HasFlag("console")));
|
||||
}
|
||||
|
||||
void Logger::Print(const char* message, ...)
|
||||
{
|
||||
return Logger::MessagePrint(0, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::Print(int channel, const char* message, ...)
|
||||
{
|
||||
return Logger::MessagePrint(channel, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::MessagePrint(int channel, std::string message)
|
||||
{
|
||||
if (Flags::HasFlag("stdout") || Loader::PerformingUnitTests())
|
||||
{
|
||||
printf("%s", message.data());
|
||||
fflush(stdout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Logger::IsConsoleReady())
|
||||
{
|
||||
OutputDebugStringA(message.data());
|
||||
}
|
||||
|
||||
if (!Game::Sys_IsMainThread())
|
||||
{
|
||||
Logger::EnqueueMessage(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
Game::Com_PrintMessage(0, message.data(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::ErrorPrint(int error, std::string message)
|
||||
{
|
||||
return Game::Com_Error(error, "%s", message.data());
|
||||
}
|
||||
|
||||
void Logger::Error(int error, const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(error, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::Error(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(0, Logger::Format(&message));
|
||||
}
|
||||
|
||||
void Logger::SoftError(const char* message, ...)
|
||||
{
|
||||
return Logger::ErrorPrint(2, Logger::Format(&message));
|
||||
}
|
||||
|
||||
std::string Logger::Format(const char** message)
|
||||
{
|
||||
char buffer[0x1000] = { 0 };
|
||||
|
||||
va_list ap = reinterpret_cast<char*>(const_cast<char**>(&message[1]));
|
||||
//va_start(ap, *message);
|
||||
_vsnprintf_s(buffer, sizeof(buffer), *message, ap);
|
||||
va_end(ap);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void Logger::Frame()
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
|
||||
for (unsigned int i = 0; i < Logger::MessageQueue.size(); ++i)
|
||||
{
|
||||
Game::Com_PrintMessage(0, Logger::MessageQueue[i].data(), 0);
|
||||
|
||||
if (!Logger::IsConsoleReady())
|
||||
{
|
||||
OutputDebugStringA(Logger::MessageQueue[i].data());
|
||||
}
|
||||
}
|
||||
|
||||
Logger::MessageQueue.clear();
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
|
||||
void Logger::PipeOutput(void(*callback)(std::string))
|
||||
{
|
||||
Logger::PipeCallback = callback;
|
||||
}
|
||||
|
||||
void Logger::PrintMessagePipe(const char* data)
|
||||
{
|
||||
if (Logger::PipeCallback)
|
||||
{
|
||||
Logger::PipeCallback(data);
|
||||
}
|
||||
}
|
||||
|
||||
void __declspec(naked) Logger::PrintMessageStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov eax, Logger::PipeCallback
|
||||
test eax, eax
|
||||
jz returnPrint
|
||||
|
||||
push [esp + 8h]
|
||||
call Logger::PrintMessagePipe
|
||||
add esp, 4h
|
||||
retn
|
||||
|
||||
returnPrint:
|
||||
push esi
|
||||
mov esi, [esp + 0Ch]
|
||||
|
||||
mov eax, 4AA835h
|
||||
jmp eax
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::EnqueueMessage(std::string message)
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
Logger::MessageQueue.push_back(message);
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
{
|
||||
Logger::PipeOutput(nullptr);
|
||||
|
||||
QuickPatch::OnFrame(Logger::Frame);
|
||||
|
||||
Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).Install()->Quick();
|
||||
}
|
||||
|
||||
Logger::~Logger()
|
||||
{
|
||||
Logger::MessageMutex.lock();
|
||||
Logger::MessageQueue.clear();
|
||||
Logger::MessageMutex.unlock();
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ namespace Components
|
||||
|
||||
AntiCheat::EmptyHash();
|
||||
|
||||
_snprintf(buffer, size, format, mapname);
|
||||
_snprintf_s(buffer, size, size, format, mapname);
|
||||
}
|
||||
|
||||
void Maps::AddDependency(std::string expression, std::string zone)
|
||||
|
@ -45,7 +45,7 @@ namespace Components
|
||||
Game::Script_SetupTokens(script, reinterpret_cast<char*>(0x797F80));
|
||||
script->punctuations = reinterpret_cast<Game::punctuation_t*>(0x797F80);
|
||||
|
||||
strcpy(script->buffer, buffer.data());
|
||||
memcpy(script->buffer, buffer.data(), script->length + 1);
|
||||
|
||||
script->length = Game::Script_CleanString(script->buffer);
|
||||
|
||||
@ -75,7 +75,7 @@ namespace Components
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(source->filename, "string", 64);
|
||||
strncpy_s(source->filename, 64, "string", 64);
|
||||
source->scriptstack = script;
|
||||
source->tokens = NULL;
|
||||
source->defines = NULL;
|
||||
|
@ -305,6 +305,7 @@ namespace Components
|
||||
Utils::Hook::Nop(0x6830B1, 20);
|
||||
Utils::Hook(0x682EBF, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick();
|
||||
Utils::Hook(0x6830B1, QuickPatch::GetStatsID, HOOK_CALL).Install()->Quick();
|
||||
//Utils::Hook::Set<BYTE>(0x68323A, 0xEB);
|
||||
|
||||
// Exploit fixes
|
||||
Utils::Hook(0x414D92, QuickPatch::MsgReadBitsCompressCheckSV, HOOK_CALL).Install()->Quick();
|
||||
|
@ -144,7 +144,7 @@ namespace Components
|
||||
char msgbuf[1024] = { 0 };
|
||||
va_list v;
|
||||
va_start(v, message);
|
||||
_vsnprintf(msgbuf, sizeof(msgbuf), message, v);
|
||||
_vsnprintf_s(msgbuf, sizeof(msgbuf), message, v);
|
||||
va_end(v);
|
||||
|
||||
Game::Scr_ShutdownAllocNode();
|
||||
|
@ -271,12 +271,17 @@ namespace Components
|
||||
Theatre::DemoContainer.CurrentSelection = index;
|
||||
Theatre::Container::DemoInfo info = Theatre::DemoContainer.Demos[index];
|
||||
|
||||
tm time;
|
||||
char buffer[1000] = { 0 };
|
||||
localtime_s(&time, &info.TimeStamp);
|
||||
asctime_s(buffer, sizeof buffer, &time);
|
||||
|
||||
Dvar::Var("ui_demo_mapname").Set(info.Mapname);
|
||||
Dvar::Var("ui_demo_mapname_localized").Set(Game::UI_LocalizeMapName(info.Mapname.data()));
|
||||
Dvar::Var("ui_demo_gametype").Set(Game::UI_LocalizeGameType(info.Gametype.data()));
|
||||
Dvar::Var("ui_demo_length").Set(Utils::String::FormatTimeSpan(info.Length));
|
||||
Dvar::Var("ui_demo_author").Set(info.Author);
|
||||
Dvar::Var("ui_demo_date").Set(std::asctime(std::localtime(&info.TimeStamp)));
|
||||
Dvar::Var("ui_demo_date").Set(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
// Disable irrelevant warnings
|
||||
#pragma warning(disable: 4100) // Unreferenced parameter (steam has to have them and other stubs as well, due to their calling convention)
|
||||
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#define VC_EXTRALEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <windows.h>
|
||||
|
@ -1,105 +1,97 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
unsigned int Utils::GetSecondsSinceAppActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetSecondsSinceComputerActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Utils::GetConnectedUniverse()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetServerRealTime()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Utils::GetIPCountry()
|
||||
{
|
||||
return "US";
|
||||
}
|
||||
|
||||
bool Utils::GetImageSize(int iImage, unsigned int *pnWidth, unsigned int *pnHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetImageRGBA(int iImage, unsigned char *pubDest, int nDestBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetCSERIPPort(unsigned int *unIP, unsigned short *usPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char Utils::GetCurrentBatteryPower()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetAppID()
|
||||
{
|
||||
return 10190;
|
||||
}
|
||||
|
||||
void Utils::SetOverlayNotificationPosition(int eNotificationPosition)
|
||||
{
|
||||
if (Steam::Overlay)
|
||||
{
|
||||
FARPROC setPosition = GetProcAddress(Steam::Overlay, "SetNotificationPosition");
|
||||
|
||||
if (setPosition)
|
||||
{
|
||||
::Utils::Hook::Call<void(int)>(setPosition)(eNotificationPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Utils::IsAPICallCompleted(unsigned __int64 hSteamAPICall, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Utils::GetAPICallFailureReason(unsigned __int64 hSteamAPICall)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Utils::GetAPICallResult(unsigned __int64 hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Utils::RunFrame()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int Utils::GetIPCCallCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Utils::SetWarningMessageHook(void(*pFunction)(int hpipe, const char *message))
|
||||
{
|
||||
}
|
||||
|
||||
bool Utils::IsOverlayEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::BOverlayNeedsPresent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
unsigned int Utils::GetSecondsSinceAppActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetSecondsSinceComputerActive()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Utils::GetConnectedUniverse()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetServerRealTime()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* Utils::GetIPCountry()
|
||||
{
|
||||
return "US";
|
||||
}
|
||||
|
||||
bool Utils::GetImageSize(int iImage, unsigned int *pnWidth, unsigned int *pnHeight)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetImageRGBA(int iImage, unsigned char *pubDest, int nDestBufferSize)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::GetCSERIPPort(unsigned int *unIP, unsigned short *usPort)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char Utils::GetCurrentBatteryPower()
|
||||
{
|
||||
return 255;
|
||||
}
|
||||
|
||||
unsigned int Utils::GetAppID()
|
||||
{
|
||||
return 10190;
|
||||
}
|
||||
|
||||
void Utils::SetOverlayNotificationPosition(int eNotificationPosition)
|
||||
{
|
||||
Proxy::SetOverlayNotificationPosition(eNotificationPosition);
|
||||
}
|
||||
|
||||
bool Utils::IsAPICallCompleted(unsigned __int64 hSteamAPICall, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int Utils::GetAPICallFailureReason(unsigned __int64 hSteamAPICall)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool Utils::GetAPICallResult(unsigned __int64 hSteamAPICall, void *pCallback, int cubCallback, int iCallbackExpected, bool *pbFailed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void Utils::RunFrame()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned int Utils::GetIPCCallCount()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Utils::SetWarningMessageHook(void(*pFunction)(int hpipe, const char *message))
|
||||
{
|
||||
}
|
||||
|
||||
bool Utils::IsOverlayEnabled()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Utils::BOverlayNeedsPresent()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
88
src/Steam/Proxy.cpp
Normal file
88
src/Steam/Proxy.cpp
Normal file
@ -0,0 +1,88 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
HMODULE Proxy::Client = nullptr;
|
||||
HMODULE Proxy::Overlay = nullptr;
|
||||
|
||||
bool Proxy::Inititalize()
|
||||
{
|
||||
std::string directoy = Proxy::GetSteamDirectory();
|
||||
if (directoy.empty()) return false;
|
||||
|
||||
SetDllDirectoryA(Proxy::GetSteamDirectory().data());
|
||||
|
||||
Proxy::Client = LoadLibraryA(STEAMCLIENT_LIB);
|
||||
Proxy::Overlay = LoadLibraryA(GAMEOVERLAY_LIB);
|
||||
|
||||
return (Proxy::Client && Proxy::Overlay);
|
||||
}
|
||||
|
||||
void Proxy::Uninititalize()
|
||||
{
|
||||
if (Proxy::Client) FreeLibrary(Proxy::Client);
|
||||
Proxy::Client = nullptr;
|
||||
|
||||
if (Proxy::Overlay) FreeLibrary(Proxy::Overlay);
|
||||
Proxy::Overlay = nullptr;
|
||||
}
|
||||
|
||||
std::string Proxy::GetSteamDirectory()
|
||||
{
|
||||
HKEY hRegKey;
|
||||
char SteamPath[MAX_PATH];
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, STEAM_REGISTRY_PATH, 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS)
|
||||
{
|
||||
DWORD dwLength = sizeof(SteamPath);
|
||||
RegQueryValueExA(hRegKey, "InstallPath", NULL, NULL, reinterpret_cast<BYTE*>(SteamPath), &dwLength);
|
||||
RegCloseKey(hRegKey);
|
||||
|
||||
return SteamPath;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void Proxy::SetOverlayNotificationPosition(uint32_t eNotificationPosition)
|
||||
{
|
||||
if (Proxy::Overlay)
|
||||
{
|
||||
FARPROC SetNotificationPositionFn = GetProcAddress(Proxy::Overlay, "SetNotificationPosition");
|
||||
|
||||
if (SetNotificationPositionFn)
|
||||
{
|
||||
::Utils::Hook::Call<void(uint32_t)>(SetNotificationPositionFn)(eNotificationPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Proxy::IsOverlayEnabled()
|
||||
{
|
||||
if (Proxy::Overlay)
|
||||
{
|
||||
FARPROC IsOverlayEnabledFn = GetProcAddress(Proxy::Overlay, "IsOverlayEnabled");
|
||||
|
||||
if (IsOverlayEnabledFn)
|
||||
{
|
||||
return ::Utils::Hook::Call<bool()>(IsOverlayEnabledFn)();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Proxy::BOverlayNeedsPresent()
|
||||
{
|
||||
if (Proxy::Overlay)
|
||||
{
|
||||
FARPROC BOverlayNeedsPresentFn = GetProcAddress(Proxy::Overlay, "BOverlayNeedsPresent");
|
||||
|
||||
if (BOverlayNeedsPresentFn)
|
||||
{
|
||||
return ::Utils::Hook::Call<bool()>(BOverlayNeedsPresentFn)();
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
30
src/Steam/Proxy.hpp
Normal file
30
src/Steam/Proxy.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifdef _WIN64
|
||||
#define GAMEOVERLAY_LIB "gameoverlayrenderer64.dll"
|
||||
#define STEAMCLIENT_LIB "steamclient64.dll"
|
||||
#define STEAM_REGISTRY_PATH "Software\\Wow6432Node\\Valve\\Steam"
|
||||
#else
|
||||
#define GAMEOVERLAY_LIB "gameoverlayrenderer.dll"
|
||||
#define STEAMCLIENT_LIB "steamclient.dll"
|
||||
#define STEAM_REGISTRY_PATH "Software\\Valve\\Steam"
|
||||
#endif
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
class Proxy
|
||||
{
|
||||
public:
|
||||
static bool Inititalize();
|
||||
static void Uninititalize();
|
||||
|
||||
//Overlay related proxies
|
||||
static void SetOverlayNotificationPosition(uint32_t eNotificationPosition);
|
||||
static bool IsOverlayEnabled();
|
||||
static bool BOverlayNeedsPresent();
|
||||
|
||||
private:
|
||||
static HMODULE Client;
|
||||
static HMODULE Overlay;
|
||||
|
||||
static std::string GetSteamDirectory();
|
||||
};
|
||||
}
|
@ -2,8 +2,6 @@
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
HMODULE Overlay = 0;
|
||||
|
||||
uint64_t Callbacks::CallID = 0;
|
||||
std::map<uint64_t, bool> Callbacks::Calls;
|
||||
std::map<uint64_t, Callbacks::Base*> Callbacks::ResultHandlers;
|
||||
@ -71,22 +69,9 @@ namespace Steam
|
||||
{
|
||||
bool SteamAPI_Init()
|
||||
{
|
||||
Overlay = GetModuleHandleA("gameoverlayrenderer.dll");
|
||||
|
||||
if (!Overlay)
|
||||
if (!Proxy::Inititalize())
|
||||
{
|
||||
HKEY hRegKey;
|
||||
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Valve\\Steam", 0, KEY_QUERY_VALUE, &hRegKey) == ERROR_SUCCESS)
|
||||
{
|
||||
char steamPath[MAX_PATH] = { 0 };
|
||||
DWORD dwLength = sizeof(steamPath);
|
||||
RegQueryValueExA(hRegKey, "InstallPath", NULL, NULL, reinterpret_cast<BYTE*>(steamPath), &dwLength);
|
||||
RegCloseKey(hRegKey);
|
||||
|
||||
SetDllDirectoryA(steamPath);
|
||||
|
||||
Overlay = LoadLibraryA(::Utils::String::VA("%s\\%s", steamPath, "gameoverlayrenderer.dll"));
|
||||
}
|
||||
OutputDebugStringA("Steamproxy not initialized properly");
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -109,6 +94,7 @@ namespace Steam
|
||||
|
||||
void SteamAPI_Shutdown()
|
||||
{
|
||||
Proxy::Uninititalize();
|
||||
}
|
||||
|
||||
void SteamAPI_UnregisterCallResult()
|
||||
|
@ -1,93 +1,93 @@
|
||||
#pragma once
|
||||
|
||||
#define STEAM_EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int AccountID : 32;
|
||||
unsigned int AccountInstance : 20;
|
||||
unsigned int AccountType : 4;
|
||||
int Universe : 8;
|
||||
};
|
||||
|
||||
unsigned long long Bits;
|
||||
} SteamID;
|
||||
|
||||
#include "Interfaces\SteamUser.hpp"
|
||||
#include "Interfaces\SteamUtils.hpp"
|
||||
#include "Interfaces\SteamFriends.hpp"
|
||||
#include "Interfaces\SteamGameServer.hpp"
|
||||
#include "Interfaces\SteamNetworking.hpp"
|
||||
#include "Interfaces\SteamMatchmaking.hpp"
|
||||
#include "Interfaces\SteamRemoteStorage.hpp"
|
||||
#include "Interfaces\SteamMasterServerUpdater.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
class Callbacks
|
||||
{
|
||||
public:
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base() : Flags(0), Callback(0) {};
|
||||
|
||||
virtual void Run(void *pvParam) = 0;
|
||||
virtual void Run(void *pvParam, bool bIOFailure, uint64_t hSteamAPICall) = 0;
|
||||
virtual int GetCallbackSizeBytes() = 0;
|
||||
|
||||
int GetICallback() { return Callback; }
|
||||
void SetICallback(int iCallback) { Callback = iCallback; }
|
||||
|
||||
protected:
|
||||
unsigned char Flags;
|
||||
int Callback;
|
||||
};
|
||||
|
||||
struct Result
|
||||
{
|
||||
void* data;
|
||||
int size;
|
||||
int type;
|
||||
uint64_t call;
|
||||
};
|
||||
|
||||
static uint64_t RegisterCall();
|
||||
static void RegisterCallback(Base* handler, int callback);
|
||||
static void RegisterCallResult(uint64_t call, Base* result);
|
||||
static void ReturnCall(void* data, int size, int type, uint64_t call);
|
||||
static void RunCallbacks();
|
||||
|
||||
private:
|
||||
static uint64_t CallID;
|
||||
static std::map<uint64_t, bool> Calls;
|
||||
static std::map<uint64_t, Base*> ResultHandlers;
|
||||
static std::vector<Result> Results;
|
||||
static std::vector<Base*> CallbackList;
|
||||
};
|
||||
|
||||
STEAM_EXPORT bool SteamAPI_Init();
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallResult(Callbacks::Base* result, uint64_t call);
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallback(Callbacks::Base* handler, int callback);
|
||||
STEAM_EXPORT void SteamAPI_RunCallbacks();
|
||||
STEAM_EXPORT void SteamAPI_Shutdown();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallResult();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallback();
|
||||
|
||||
STEAM_EXPORT bool SteamGameServer_Init();
|
||||
STEAM_EXPORT void SteamGameServer_RunCallbacks();
|
||||
STEAM_EXPORT void SteamGameServer_Shutdown();
|
||||
|
||||
STEAM_EXPORT Steam::Friends* SteamFriends();
|
||||
STEAM_EXPORT Steam::Matchmaking* SteamMatchmaking();
|
||||
STEAM_EXPORT Steam::GameServer* SteamGameServer();
|
||||
STEAM_EXPORT Steam::MasterServerUpdater* SteamMasterServerUpdater();
|
||||
STEAM_EXPORT Steam::Networking* SteamNetworking();
|
||||
STEAM_EXPORT Steam::RemoteStorage* SteamRemoteStorage();
|
||||
STEAM_EXPORT Steam::User* SteamUser();
|
||||
STEAM_EXPORT Steam::Utils* SteamUtils();
|
||||
|
||||
extern HMODULE Overlay;
|
||||
}
|
||||
#pragma once
|
||||
|
||||
#define STEAM_EXPORT extern "C" __declspec(dllexport)
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned int AccountID : 32;
|
||||
unsigned int AccountInstance : 20;
|
||||
unsigned int AccountType : 4;
|
||||
int Universe : 8;
|
||||
};
|
||||
|
||||
unsigned long long Bits;
|
||||
} SteamID;
|
||||
|
||||
#include "Interfaces\SteamUser.hpp"
|
||||
#include "Interfaces\SteamUtils.hpp"
|
||||
#include "Interfaces\SteamFriends.hpp"
|
||||
#include "Interfaces\SteamGameServer.hpp"
|
||||
#include "Interfaces\SteamNetworking.hpp"
|
||||
#include "Interfaces\SteamMatchmaking.hpp"
|
||||
#include "Interfaces\SteamRemoteStorage.hpp"
|
||||
#include "Interfaces\SteamMasterServerUpdater.hpp"
|
||||
|
||||
#include "Proxy.hpp"
|
||||
|
||||
namespace Steam
|
||||
{
|
||||
class Callbacks
|
||||
{
|
||||
public:
|
||||
class Base
|
||||
{
|
||||
public:
|
||||
Base() : Flags(0), Callback(0) {};
|
||||
|
||||
virtual void Run(void *pvParam) = 0;
|
||||
virtual void Run(void *pvParam, bool bIOFailure, uint64_t hSteamAPICall) = 0;
|
||||
virtual int GetCallbackSizeBytes() = 0;
|
||||
|
||||
int GetICallback() { return Callback; }
|
||||
void SetICallback(int iCallback) { Callback = iCallback; }
|
||||
|
||||
protected:
|
||||
unsigned char Flags;
|
||||
int Callback;
|
||||
};
|
||||
|
||||
struct Result
|
||||
{
|
||||
void* data;
|
||||
int size;
|
||||
int type;
|
||||
uint64_t call;
|
||||
};
|
||||
|
||||
static uint64_t RegisterCall();
|
||||
static void RegisterCallback(Base* handler, int callback);
|
||||
static void RegisterCallResult(uint64_t call, Base* result);
|
||||
static void ReturnCall(void* data, int size, int type, uint64_t call);
|
||||
static void RunCallbacks();
|
||||
|
||||
private:
|
||||
static uint64_t CallID;
|
||||
static std::map<uint64_t, bool> Calls;
|
||||
static std::map<uint64_t, Base*> ResultHandlers;
|
||||
static std::vector<Result> Results;
|
||||
static std::vector<Base*> CallbackList;
|
||||
};
|
||||
|
||||
STEAM_EXPORT bool SteamAPI_Init();
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallResult(Callbacks::Base* result, uint64_t call);
|
||||
STEAM_EXPORT void SteamAPI_RegisterCallback(Callbacks::Base* handler, int callback);
|
||||
STEAM_EXPORT void SteamAPI_RunCallbacks();
|
||||
STEAM_EXPORT void SteamAPI_Shutdown();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallResult();
|
||||
STEAM_EXPORT void SteamAPI_UnregisterCallback();
|
||||
|
||||
STEAM_EXPORT bool SteamGameServer_Init();
|
||||
STEAM_EXPORT void SteamGameServer_RunCallbacks();
|
||||
STEAM_EXPORT void SteamGameServer_Shutdown();
|
||||
|
||||
STEAM_EXPORT Steam::Friends* SteamFriends();
|
||||
STEAM_EXPORT Steam::Matchmaking* SteamMatchmaking();
|
||||
STEAM_EXPORT Steam::GameServer* SteamGameServer();
|
||||
STEAM_EXPORT Steam::MasterServerUpdater* SteamMasterServerUpdater();
|
||||
STEAM_EXPORT Steam::Networking* SteamNetworking();
|
||||
STEAM_EXPORT Steam::RemoteStorage* SteamRemoteStorage();
|
||||
STEAM_EXPORT Steam::User* SteamUser();
|
||||
STEAM_EXPORT Steam::Utils* SteamUtils();
|
||||
}
|
||||
|
@ -1,257 +1,257 @@
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
std::map<void*, void*> Hook::Interceptor::IReturn;
|
||||
std::map<void*, void(*)()> Hook::Interceptor::ICallbacks;
|
||||
|
||||
void Hook::Signature::Process()
|
||||
{
|
||||
if (Hook::Signature::Signatures.empty()) return;
|
||||
|
||||
char* start = reinterpret_cast<char*>(Hook::Signature::Start);
|
||||
|
||||
unsigned int sigCount = Hook::Signature::Signatures.size();
|
||||
Hook::Signature::Container* containers = Hook::Signature::Signatures.data();
|
||||
|
||||
for (size_t i = 0; i < Hook::Signature::Length; ++i)
|
||||
{
|
||||
char* address = start + i;
|
||||
|
||||
for (unsigned int k = 0; k < sigCount; ++k)
|
||||
{
|
||||
Hook::Signature::Container* container = &containers[k];
|
||||
|
||||
unsigned int j = 0;
|
||||
for (j = 0; j < strlen(container->Mask); ++j)
|
||||
{
|
||||
if (container->Mask[j] != '?' &&container->Signature[j] != address[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == strlen(container->Mask))
|
||||
{
|
||||
container->Callback(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hook::Signature::Add(Hook::Signature::Container& container)
|
||||
{
|
||||
Hook::Signature::Signatures.push_back(container);
|
||||
}
|
||||
|
||||
void Hook::Interceptor::Install(void* place, void(*stub)())
|
||||
{
|
||||
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
||||
}
|
||||
|
||||
void Hook::Interceptor::Install(void** place, void(*stub)())
|
||||
{
|
||||
Hook::Interceptor::IReturn[place] = *place;
|
||||
Hook::Interceptor::ICallbacks[place] = stub;
|
||||
*place = Hook::Interceptor::InterceptionStub;
|
||||
}
|
||||
|
||||
void __declspec(naked) Hook::Interceptor::InterceptionStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
sub esp, 4h // Reserve space on the stack for the return address
|
||||
pushad // Store registers
|
||||
|
||||
lea eax, [esp + 20h] // Load initial stack pointer
|
||||
push eax // Push it onto the stack
|
||||
|
||||
call RunCallback // Run the callback based on the given stack pointer
|
||||
call PopReturn // Get the initial return address according to the stack pointer
|
||||
|
||||
add esp, 4h // Clear the stack
|
||||
|
||||
mov [esp + 20h], eax // Store the return address at the reserved space
|
||||
popad // Restore the registers
|
||||
|
||||
retn // Return (jump to our return address)
|
||||
}
|
||||
}
|
||||
|
||||
void Hook::Interceptor::RunCallback(void* place)
|
||||
{
|
||||
auto iCallback = Hook::Interceptor::ICallbacks.find(place);
|
||||
if (iCallback != Hook::Interceptor::ICallbacks.end())
|
||||
{
|
||||
iCallback->second();
|
||||
Hook::Interceptor::ICallbacks.erase(iCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void* Hook::Interceptor::PopReturn(void* place)
|
||||
{
|
||||
void* retVal = nullptr;
|
||||
|
||||
auto iReturn = Hook::Interceptor::IReturn.find(place);
|
||||
if (iReturn != Hook::Interceptor::IReturn.end())
|
||||
{
|
||||
retVal = iReturn->second;
|
||||
Hook::Interceptor::IReturn.erase(iReturn);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Hook::~Hook()
|
||||
{
|
||||
if (Hook::Initialized)
|
||||
{
|
||||
Hook::Uninstall();
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(DWORD place, void(*stub)(), bool useJump)
|
||||
{
|
||||
return Hook::Initialize(place, reinterpret_cast<void*>(stub), useJump);
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(DWORD place, void* stub, bool useJump)
|
||||
{
|
||||
return Hook::Initialize(reinterpret_cast<void*>(place), stub, useJump);
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(void* place, void* stub, bool useJump)
|
||||
{
|
||||
if (Hook::Initialized) return this;
|
||||
Hook::Initialized = true;
|
||||
|
||||
Hook::UseJump = useJump;
|
||||
Hook::Place = place;
|
||||
Hook::Stub = stub;
|
||||
|
||||
Hook::Original = static_cast<char*>(Hook::Place) + 5 + *reinterpret_cast<DWORD*>((static_cast<char*>(Hook::Place) + 1));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook* Hook::Install(bool unprotect, bool keepUnportected)
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = true;
|
||||
|
||||
if (unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &this->Protection);
|
||||
std::memcpy(Hook::Buffer, Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
char* code = static_cast<char*>(Hook::Place);
|
||||
|
||||
*code = static_cast<char>(Hook::UseJump ? 0xE9 : 0xE8);
|
||||
|
||||
*reinterpret_cast<size_t*>(code + 1) = reinterpret_cast<size_t>(Hook::Stub) - (reinterpret_cast<size_t>(Hook::Place) + 5);
|
||||
|
||||
if (unprotect && !keepUnportected) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), Hook::Protection, &this->Protection);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Hook::Quick()
|
||||
{
|
||||
if (Hook::Installed)
|
||||
{
|
||||
Hook::Installed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Uninstall(bool unprotect)
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || !Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = false;
|
||||
|
||||
if(unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &this->Protection);
|
||||
|
||||
std::memcpy(Hook::Place, Hook::Buffer, sizeof(Hook::Buffer));
|
||||
|
||||
if (unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), Hook::Protection, &this->Protection);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void* Hook::GetAddress()
|
||||
{
|
||||
return Hook::Place;
|
||||
}
|
||||
|
||||
void Hook::Nop(void* place, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
memset(place, 0x90, length);
|
||||
|
||||
VirtualProtect(place, length, oldProtect, &oldProtect);
|
||||
FlushInstructionCache(GetCurrentProcess(), place, length);
|
||||
}
|
||||
|
||||
void Hook::Nop(DWORD place, size_t length)
|
||||
{
|
||||
Nop(reinterpret_cast<void*>(place), length);
|
||||
}
|
||||
|
||||
void Hook::SetString(void* place, const char* string, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(place, length + 1, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
strncpy(static_cast<char*>(place), string, length);
|
||||
|
||||
VirtualProtect(place, length + 1, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
void Hook::SetString(DWORD place, const char* string, size_t length)
|
||||
{
|
||||
Hook::SetString(reinterpret_cast<void*>(place), string, length);
|
||||
}
|
||||
|
||||
void Hook::SetString(void* place, const char* string)
|
||||
{
|
||||
Hook::SetString(place, string, strlen(static_cast<char*>(place)));
|
||||
}
|
||||
|
||||
void Hook::SetString(DWORD place, const char* string)
|
||||
{
|
||||
Hook::SetString(reinterpret_cast<void*>(place), string);
|
||||
}
|
||||
|
||||
void Hook::RedirectJump(void* place, void* stub)
|
||||
{
|
||||
char* operandPtr = static_cast<char*>(place) + 2;
|
||||
int newOperand = reinterpret_cast<int>(stub) - (reinterpret_cast<int>(place) + 6);
|
||||
Utils::Hook::Set<int>(operandPtr, newOperand);
|
||||
}
|
||||
|
||||
void Hook::RedirectJump(DWORD place, void* stub)
|
||||
{
|
||||
Hook::RedirectJump(reinterpret_cast<void*>(place), stub);
|
||||
}
|
||||
}
|
||||
#include "STDInclude.hpp"
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
std::map<void*, void*> Hook::Interceptor::IReturn;
|
||||
std::map<void*, void(*)()> Hook::Interceptor::ICallbacks;
|
||||
|
||||
void Hook::Signature::Process()
|
||||
{
|
||||
if (Hook::Signature::Signatures.empty()) return;
|
||||
|
||||
char* start = reinterpret_cast<char*>(Hook::Signature::Start);
|
||||
|
||||
unsigned int sigCount = Hook::Signature::Signatures.size();
|
||||
Hook::Signature::Container* containers = Hook::Signature::Signatures.data();
|
||||
|
||||
for (size_t i = 0; i < Hook::Signature::Length; ++i)
|
||||
{
|
||||
char* address = start + i;
|
||||
|
||||
for (unsigned int k = 0; k < sigCount; ++k)
|
||||
{
|
||||
Hook::Signature::Container* container = &containers[k];
|
||||
|
||||
unsigned int j = 0;
|
||||
for (j = 0; j < strlen(container->Mask); ++j)
|
||||
{
|
||||
if (container->Mask[j] != '?' &&container->Signature[j] != address[j])
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (j == strlen(container->Mask))
|
||||
{
|
||||
container->Callback(address);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Hook::Signature::Add(Hook::Signature::Container& container)
|
||||
{
|
||||
Hook::Signature::Signatures.push_back(container);
|
||||
}
|
||||
|
||||
void Hook::Interceptor::Install(void* place, void(*stub)())
|
||||
{
|
||||
return Hook::Interceptor::Install(reinterpret_cast<void**>(place), stub);
|
||||
}
|
||||
|
||||
void Hook::Interceptor::Install(void** place, void(*stub)())
|
||||
{
|
||||
Hook::Interceptor::IReturn[place] = *place;
|
||||
Hook::Interceptor::ICallbacks[place] = stub;
|
||||
*place = Hook::Interceptor::InterceptionStub;
|
||||
}
|
||||
|
||||
void __declspec(naked) Hook::Interceptor::InterceptionStub()
|
||||
{
|
||||
__asm
|
||||
{
|
||||
sub esp, 4h // Reserve space on the stack for the return address
|
||||
pushad // Store registers
|
||||
|
||||
lea eax, [esp + 20h] // Load initial stack pointer
|
||||
push eax // Push it onto the stack
|
||||
|
||||
call RunCallback // Run the callback based on the given stack pointer
|
||||
call PopReturn // Get the initial return address according to the stack pointer
|
||||
|
||||
add esp, 4h // Clear the stack
|
||||
|
||||
mov [esp + 20h], eax // Store the return address at the reserved space
|
||||
popad // Restore the registers
|
||||
|
||||
retn // Return (jump to our return address)
|
||||
}
|
||||
}
|
||||
|
||||
void Hook::Interceptor::RunCallback(void* place)
|
||||
{
|
||||
auto iCallback = Hook::Interceptor::ICallbacks.find(place);
|
||||
if (iCallback != Hook::Interceptor::ICallbacks.end())
|
||||
{
|
||||
iCallback->second();
|
||||
Hook::Interceptor::ICallbacks.erase(iCallback);
|
||||
}
|
||||
}
|
||||
|
||||
void* Hook::Interceptor::PopReturn(void* place)
|
||||
{
|
||||
void* retVal = nullptr;
|
||||
|
||||
auto iReturn = Hook::Interceptor::IReturn.find(place);
|
||||
if (iReturn != Hook::Interceptor::IReturn.end())
|
||||
{
|
||||
retVal = iReturn->second;
|
||||
Hook::Interceptor::IReturn.erase(iReturn);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
Hook::~Hook()
|
||||
{
|
||||
if (Hook::Initialized)
|
||||
{
|
||||
Hook::Uninstall();
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(DWORD place, void(*stub)(), bool useJump)
|
||||
{
|
||||
return Hook::Initialize(place, reinterpret_cast<void*>(stub), useJump);
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(DWORD place, void* stub, bool useJump)
|
||||
{
|
||||
return Hook::Initialize(reinterpret_cast<void*>(place), stub, useJump);
|
||||
}
|
||||
|
||||
Hook* Hook::Initialize(void* place, void* stub, bool useJump)
|
||||
{
|
||||
if (Hook::Initialized) return this;
|
||||
Hook::Initialized = true;
|
||||
|
||||
Hook::UseJump = useJump;
|
||||
Hook::Place = place;
|
||||
Hook::Stub = stub;
|
||||
|
||||
Hook::Original = static_cast<char*>(Hook::Place) + 5 + *reinterpret_cast<DWORD*>((static_cast<char*>(Hook::Place) + 1));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook* Hook::Install(bool unprotect, bool keepUnportected)
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = true;
|
||||
|
||||
if (unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &this->Protection);
|
||||
std::memcpy(Hook::Buffer, Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
char* code = static_cast<char*>(Hook::Place);
|
||||
|
||||
*code = static_cast<char>(Hook::UseJump ? 0xE9 : 0xE8);
|
||||
|
||||
*reinterpret_cast<size_t*>(code + 1) = reinterpret_cast<size_t>(Hook::Stub) - (reinterpret_cast<size_t>(Hook::Place) + 5);
|
||||
|
||||
if (unprotect && !keepUnportected) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), Hook::Protection, &this->Protection);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void Hook::Quick()
|
||||
{
|
||||
if (Hook::Installed)
|
||||
{
|
||||
Hook::Installed = false;
|
||||
}
|
||||
}
|
||||
|
||||
Hook* Hook::Uninstall(bool unprotect)
|
||||
{
|
||||
Hook::StateMutex.lock();
|
||||
|
||||
if (!Hook::Initialized || !Hook::Installed)
|
||||
{
|
||||
Hook::StateMutex.unlock();
|
||||
return this;
|
||||
}
|
||||
|
||||
Hook::Installed = false;
|
||||
|
||||
if(unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), PAGE_EXECUTE_READWRITE, &this->Protection);
|
||||
|
||||
std::memcpy(Hook::Place, Hook::Buffer, sizeof(Hook::Buffer));
|
||||
|
||||
if (unprotect) VirtualProtect(Hook::Place, sizeof(Hook::Buffer), Hook::Protection, &this->Protection);
|
||||
|
||||
FlushInstructionCache(GetCurrentProcess(), Hook::Place, sizeof(Hook::Buffer));
|
||||
|
||||
Hook::StateMutex.unlock();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
void* Hook::GetAddress()
|
||||
{
|
||||
return Hook::Place;
|
||||
}
|
||||
|
||||
void Hook::Nop(void* place, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(place, length, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
memset(place, 0x90, length);
|
||||
|
||||
VirtualProtect(place, length, oldProtect, &oldProtect);
|
||||
FlushInstructionCache(GetCurrentProcess(), place, length);
|
||||
}
|
||||
|
||||
void Hook::Nop(DWORD place, size_t length)
|
||||
{
|
||||
Nop(reinterpret_cast<void*>(place), length);
|
||||
}
|
||||
|
||||
void Hook::SetString(void* place, const char* string, size_t length)
|
||||
{
|
||||
DWORD oldProtect;
|
||||
VirtualProtect(place, length + 1, PAGE_EXECUTE_READWRITE, &oldProtect);
|
||||
|
||||
strncpy_s(static_cast<char*>(place), length, string, length);
|
||||
|
||||
VirtualProtect(place, length + 1, oldProtect, &oldProtect);
|
||||
}
|
||||
|
||||
void Hook::SetString(DWORD place, const char* string, size_t length)
|
||||
{
|
||||
Hook::SetString(reinterpret_cast<void*>(place), string, length);
|
||||
}
|
||||
|
||||
void Hook::SetString(void* place, const char* string)
|
||||
{
|
||||
Hook::SetString(place, string, strlen(static_cast<char*>(place)));
|
||||
}
|
||||
|
||||
void Hook::SetString(DWORD place, const char* string)
|
||||
{
|
||||
Hook::SetString(reinterpret_cast<void*>(place), string);
|
||||
}
|
||||
|
||||
void Hook::RedirectJump(void* place, void* stub)
|
||||
{
|
||||
char* operandPtr = static_cast<char*>(place) + 2;
|
||||
int newOperand = reinterpret_cast<int>(stub) - (reinterpret_cast<int>(place) + 6);
|
||||
Utils::Hook::Set<int>(operandPtr, newOperand);
|
||||
}
|
||||
|
||||
void Hook::RedirectJump(DWORD place, void* stub)
|
||||
{
|
||||
Hook::RedirectJump(reinterpret_cast<void*>(place), stub);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user