Skip to content

Commit

Permalink
feat!: miscX (#286)
Browse files Browse the repository at this point in the history
- the fast and furious series has a lot of sequels
  • Loading branch information
qudix authored Oct 8, 2024
1 parent f4666a5 commit 8401f3e
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 13 deletions.
48 changes: 37 additions & 11 deletions include/RE/C/ConsoleLog.h
Original file line number Diff line number Diff line change
@@ -1,40 +1,66 @@
#pragma once

#include "RE/B/BSTEvent.h"
#include "RE/B/BSTSingleton.h"
#include "RE/B/BSStringT.h"

namespace RE
{
class ConsoleLog
struct ConsoleLogAddEvent;

class __declspec(novtable) ConsoleLog :
public BSTSingletonSDM<ConsoleLog>,
public BSTEventSource<ConsoleLogAddEvent>
{
public:
SF_RTTI_VTABLE(ConsoleLog);

// BSTSDM
virtual ~ConsoleLog(); // 00

[[nodiscard]] static ConsoleLog* GetSingleton()
{
static REL::Relocation<ConsoleLog**> singleton{ ID::ConsoleLog::singleton };
static REL::Relocation<ConsoleLog**> singleton{ ID::ConsoleLog::Singleton };
return *singleton;
}

void VPrint(const char* a_fmt, std::va_list a_args)
void AddString(const char* a_str)
{
using func_t = decltype(&ConsoleLog::AddString);
static REL::Relocation<func_t> func{ ID::ConsoleLog::AddString };
func(this, a_str);
}

void Print(const char* a_fmt, std::va_list a_args)
{
using func_t = decltype(&ConsoleLog::VPrint);
static REL::Relocation<func_t> func{ ID::ConsoleLog::VPrint };
using func_t = decltype(&ConsoleLog::Print);
static REL::Relocation<func_t> func{ ID::ConsoleLog::Print };
func(this, a_fmt, a_args);
}

// printf format rules, no compile time checking
void Print(const char* a_fmt, ...)
// std::printf rules, no compile time checking
void PrintLine(const char* a_fmt, ...)
{
std::va_list args;
va_start(args, a_fmt);
VPrint(a_fmt, args);
Print(a_fmt, args);
va_end(args);
}

// std::format rules, compile time checking
// std::format rules, has compile time checking
template <class... Args>
void Log(const std::format_string<Args...> a_fmt, Args&&... a_args)
{
Print(std::vformat(a_fmt.get(), std::make_format_args(a_args...)).c_str());
AddString(std::vformat(a_fmt.get(), std::make_format_args(a_args...)).c_str());
}

void SetUseConsoleOverlay(bool a_value)
{
useConsoleOverlay = a_value;
}

// members
BSStringT<char> buffer; // 38
bool useConsoleOverlay; // 48
};
static_assert(sizeof(ConsoleLog) == 0x48);
}
5 changes: 3 additions & 2 deletions include/RE/IDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ namespace RE::ID

namespace ConsoleLog
{
inline constexpr REL::ID singleton{ 879277 };
inline constexpr REL::ID VPrint{ 166358 };
inline constexpr REL::ID Singleton{ 879277 };
inline constexpr REL::ID AddString{ 166357 };
inline constexpr REL::ID Print{ 166358 };
}

namespace ExtraDataList
Expand Down
15 changes: 15 additions & 0 deletions include/REL/Relocation.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,21 @@ namespace REL
inline constexpr std::uint8_t RET = 0xC3;
inline constexpr std::uint8_t INT3 = 0xCC;

template <class T, class U>
[[nodiscard]] auto AdjustPointer(U* a_ptr, const std::ptrdiff_t a_adjust) noexcept
{
auto addr = a_ptr ? reinterpret_cast<std::uintptr_t>(a_ptr) + a_adjust : 0;
if constexpr (std::is_const_v<U> && std::is_volatile_v<U>) {
return reinterpret_cast<std::add_cv_t<T>*>(addr);
} else if constexpr (std::is_const_v<U>) {
return reinterpret_cast<std::add_const_t<T>*>(addr);
} else if constexpr (std::is_volatile_v<U>) {
return reinterpret_cast<std::add_volatile_t<T>*>(addr);
} else {
return reinterpret_cast<T*>(addr);
}
}

template <class F, class... Args>
constexpr std::invoke_result_t<F, Args...> invoke(F&& a_func, Args&&... a_args) //
noexcept(std::is_nothrow_invocable_v<F, Args...>)
Expand Down
1 change: 1 addition & 0 deletions include/REX/W32.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "REX/W32/DXGI_5.h"
#include "REX/W32/DXGI_6.h"
#include "REX/W32/KERNEL32.h"
#include "REX/W32/NT.h"
#include "REX/W32/OLE32.h"
#include "REX/W32/USER32.h"
#include "REX/W32/VERSION.h"
Expand Down
10 changes: 10 additions & 0 deletions include/REX/W32/BASE.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ namespace REX::W32
};
std::int64_t value;
};
static_assert(sizeof(LARGE_INTEGER) == 0x8);

union ULARGE_INTEGER
{
Expand All @@ -172,6 +173,15 @@ namespace REX::W32
};
std::uint64_t value;
};
static_assert(sizeof(ULARGE_INTEGER) == 0x8);

struct UNICODE_STRING
{
std::uint16_t length;
std::uint16_t maxLength;
wchar_t* buffer;
};
static_assert(sizeof(UNICODE_STRING) == 0x10);
}

namespace REX::W32
Expand Down
92 changes: 92 additions & 0 deletions include/REX/W32/NT.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#pragma once

#include "REX/W32/BASE.h"

namespace REX::W32
{
struct EXCEPTION_REGISTRATION_RECORD;
struct PEB_LDR_DATA;
struct RTL_USER_PROCESS_PARAMETERS;
struct UNICODE_STRING;

using PS_POST_PROCESS_INIT_ROUTINE = void(*)();

struct LIST_ENTRY
{
struct LIST_ENTRY* fLink;
struct LIST_ENTRY* bLink;
};

struct NT_TIB
{
EXCEPTION_REGISTRATION_RECORD* exceptionList;
void* stackBase;
void* stackLimit;
void* subSystemTib;
union
{
void* fiberData;
std::uint32_t version;
};
void* arbitraryUserPointer;
struct NT_TIB* self;
};

struct PEB
{
std::byte reserved1[2];
std::byte beingDebugged;
std::byte reserved2[1];
void* reserved3[2];
PEB_LDR_DATA* ldr;
RTL_USER_PROCESS_PARAMETERS* processParameters;
void* reserved4[3];
void* atlThunkSListPtr;
void* reserved5;
std::uint32_t reserved6;
void* reserved7;
std::uint32_t reserved8;
std::uint32_t atlThunkSListPtr32;
void* reserved9[45];
std::byte reserved10[96];
PS_POST_PROCESS_INIT_ROUTINE postProcessInitRoutine;
std::byte reserved11[128];
void* reserved12[1];
std::uint32_t sessionID;
};

struct PEB_LDR_DATA
{
std::byte reserved1[8];
void* reserved2[3];
LIST_ENTRY inMemoryOrderModuleList;
};

struct RTL_USER_PROCESS_PARAMETERS
{
std::byte reserved1[16];
void* reserved2[10];
UNICODE_STRING imagePathName;
UNICODE_STRING commandLine;
};

struct TEB
{
void* reserved1[11];
void* threadLocalStoragePointer;
PEB* processEnvironmentBlock;
void* reserved2[399];
std::byte reserved3[1952];
void* tlsSlots[64];
std::byte reserved4[8];
void* reserved5[26];
void* reservedForOle;
void* reserved6[4];
void* tlsExpansionSlots;
};
}

namespace REX::W32
{
TEB* NtCurrentTeb() noexcept;
}
11 changes: 11 additions & 0 deletions src/REX/W32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#include "REX/W32/DBGHELP.h"
#include "REX/W32/DXGI.h"
#include "REX/W32/KERNEL32.h"
#include "REX/W32/NT.h"
#include "REX/W32/OLE32.h"
#include "REX/W32/SHELL32.h"
#include "REX/W32/USER32.h"
#include "REX/W32/VERSION.h"
#include "REX/W32/WS2_32.h"

// ADVAPI32

Expand Down Expand Up @@ -644,6 +646,15 @@ namespace REX::W32
}
}

// NT
namespace REX::W32
{
TEB* NtCurrentTeb() noexcept
{
return reinterpret_cast<TEB*>(__readgsqword(offsetof(NT_TIB, self)));
}
}

// OLE32

REX_W32_IMPORT(void, CoTaskMemFree, void*);
Expand Down

0 comments on commit 8401f3e

Please sign in to comment.