Skip to content

Commit

Permalink
Add source file for Relocation.hpp
Browse files Browse the repository at this point in the history
  • Loading branch information
wopss committed Feb 8, 2024
1 parent 861ccc2 commit d50fb22
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 56 deletions.
67 changes: 67 additions & 0 deletions include/RED4ext/Relocation-inl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once

#ifdef RED4EXT_STATIC_LIB
#include <RED4ext/Relocation.hpp>
#endif

#include <mutex>
#include <sstream>

#include <Windows.h>

#include <RED4ext/Common.hpp>

RED4EXT_INLINE uintptr_t RED4ext::RelocBase::GetImageBase()
{
static const auto base = reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr));
return base;
}

RED4EXT_INLINE
uintptr_t RED4ext::UniversalRelocBase::Resolve(UniversalRelocSegment aSegment, uint64_t aHash)
{
using functionType = uintptr_t (*)(UniversalRelocSegment, uint64_t);
static functionType resolveFunc = nullptr;

static std::once_flag flag;
std::call_once(flag,
[]()
{
constexpr auto dllName = "RED4ext.dll";
constexpr auto functionName = "RED4ext_ResolveAddress";

auto handle = LoadLibraryA(dllName);
if (!handle)
{
std::stringstream stream;
stream << "Failed to get '" << dllName
<< "' handle.\nProcess will now close.\n\nLast error: " << GetLastError();

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}

resolveFunc = reinterpret_cast<functionType>(GetProcAddress(handle, functionName));
if (resolveFunc == nullptr)
{
std::stringstream stream;
stream << "Failed to get '" << functionName
<< "' address.\nProcess will now close.\n\nLast error: " << GetLastError();

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}
});

auto address = resolveFunc(aSegment, aHash);
if (address == 0)
{
std::stringstream stream;
stream << "Failed to resolve address for hash " << std::hex << aHash << ".\nProcess will now close.";

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}

return address;
}
62 changes: 6 additions & 56 deletions include/RED4ext/Relocation.hpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
#pragma once

#include <cstdint>
#include <mutex>
#include <sstream>

#include <Windows.h>

namespace RED4ext
{
class RelocBase
{
public:
inline static uintptr_t GetImageBase()
{
static const auto base = reinterpret_cast<uintptr_t>(GetModuleHandle(nullptr));
return base;
}
static uintptr_t GetImageBase();
};

/**
Expand Down Expand Up @@ -98,53 +90,7 @@ enum class UniversalRelocSegment : uint32_t
class UniversalRelocBase
{
public:
static uintptr_t Resolve(UniversalRelocSegment aSegment, uint64_t aHash)
{
using functionType = uintptr_t (*)(UniversalRelocSegment, uint64_t);
static functionType resolveFunc = nullptr;

static std::once_flag flag;
std::call_once(flag,
[]()
{
constexpr auto dllName = "RED4ext.dll";
constexpr auto functionName = "RED4ext_ResolveAddress";

auto handle = LoadLibraryA(dllName);
if (!handle)
{
std::stringstream stream;
stream << "Failed to get '" << dllName
<< "' handle.\nProcess will now close.\n\nLast error: " << GetLastError();

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}

resolveFunc = reinterpret_cast<functionType>(GetProcAddress(handle, functionName));
if (resolveFunc == nullptr)
{
std::stringstream stream;
stream << "Failed to get '" << functionName
<< "' address.\nProcess will now close.\n\nLast error: " << GetLastError();

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}
});

auto address = resolveFunc(aSegment, aHash);
if (address == 0)
{
std::stringstream stream;
stream << "Failed to resolve address for hash " << std::hex << aHash << ".\nProcess will now close.";

MessageBoxA(nullptr, stream.str().c_str(), "RED4ext.SDK", MB_ICONERROR | MB_OK);
TerminateProcess(GetCurrentProcess(), 1);
}

return address;
}
static uintptr_t Resolve(UniversalRelocSegment aSegment, uint64_t aHash);
};

/**
Expand Down Expand Up @@ -218,3 +164,7 @@ class UniversalRelocVtbl : private UniversalRelocBase
};

} // namespace RED4ext

#ifdef RED4EXT_HEADER_ONLY
#include <RED4ext/Relocation-inl.hpp>
#endif
6 changes: 6 additions & 0 deletions src/Relocation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef RED4EXT_STATIC_LIB
#error Please define 'RED4EXT_STATIC_LIB' to compile this file.
#endif

#include <RED4ext/Relocation-inl.hpp>

0 comments on commit d50fb22

Please sign in to comment.