Patch r_preloadShaders crash
This commit is contained in:
parent
5d87fdbfa9
commit
58c5571884
@ -132,6 +132,21 @@ namespace renderer
|
|||||||
a.jmp(0x1C4136_b);
|
a.jmp(0x1C4136_b);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void r_preload_shaders_stub(utils::hook::assembler& a)
|
||||||
|
{
|
||||||
|
const auto is_zero = a.newLabel();
|
||||||
|
|
||||||
|
a.mov(rax, qword_ptr(SELECT_VALUE(0x123FFF30_b, 0x111DC230_b)));
|
||||||
|
a.test(rax, rax);
|
||||||
|
a.jz(is_zero);
|
||||||
|
|
||||||
|
a.mov(rcx, qword_ptr(rax, 0x540C68));
|
||||||
|
a.jmp(SELECT_VALUE(0x5CF1FF_b, 0x6E76FF_b));
|
||||||
|
|
||||||
|
a.bind(is_zero);
|
||||||
|
a.jmp(SELECT_VALUE(0x5CF20A_b, 0x6E7722_b));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface
|
||||||
@ -166,6 +181,10 @@ namespace renderer
|
|||||||
r_use_custom_red_dot_brightness = dvars::register_bool("r_useCustomRedDotBrightness",
|
r_use_custom_red_dot_brightness = dvars::register_bool("r_useCustomRedDotBrightness",
|
||||||
true, game::DVAR_FLAG_SAVED, "Use custom red-dot brightness values");
|
true, game::DVAR_FLAG_SAVED, "Use custom red-dot brightness values");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// patch r_preloadShaders crash at init
|
||||||
|
utils::hook::jump(SELECT_VALUE(0x5CF1F1_b, 0x6E76F1_b), utils::hook::assemble(r_preload_shaders_stub), true);
|
||||||
|
dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_SAVED);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,13 @@
|
|||||||
|
|
||||||
#include <MinHook.h>
|
#include <MinHook.h>
|
||||||
|
|
||||||
|
Mem seg_ptr(const SReg& segment, const uint64_t off)
|
||||||
|
{
|
||||||
|
auto mem = ptr_abs(off);
|
||||||
|
mem.setSegment(segment);
|
||||||
|
return mem;
|
||||||
|
}
|
||||||
|
|
||||||
namespace utils::hook
|
namespace utils::hook
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "signature.hpp"
|
#include "signature.hpp"
|
||||||
|
#include "memory.hpp"
|
||||||
|
|
||||||
#include <asmjit/core/jitruntime.h>
|
#include <asmjit/core/jitruntime.h>
|
||||||
#include <asmjit/x86/x86assembler.h>
|
#include <asmjit/x86/x86assembler.h>
|
||||||
|
|
||||||
using namespace asmjit::x86;
|
using namespace asmjit::x86;
|
||||||
|
|
||||||
|
Mem seg_ptr(const SReg& segment, const uint64_t off);
|
||||||
|
|
||||||
namespace utils::hook
|
namespace utils::hook
|
||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
@ -204,4 +207,59 @@ namespace utils::hook
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* allocate_somewhere_near(const void* base_address, const size_t size);
|
uint8_t* allocate_somewhere_near(const void* base_address, const size_t size);
|
||||||
|
|
||||||
|
template <size_t Base>
|
||||||
|
void* allocate_far_jump()
|
||||||
|
{
|
||||||
|
constexpr auto alloc_size = 0x1000;
|
||||||
|
constexpr auto far_jmp_size = 0xC;
|
||||||
|
|
||||||
|
const auto alloc_jump_table = []
|
||||||
|
{
|
||||||
|
return reinterpret_cast<char*>(
|
||||||
|
memory::allocate_near(Base, alloc_size, PAGE_EXECUTE_READWRITE));
|
||||||
|
};
|
||||||
|
|
||||||
|
static auto jump_table = alloc_jump_table();
|
||||||
|
static auto current_pos = jump_table;
|
||||||
|
|
||||||
|
if (current_pos + far_jmp_size >= jump_table + alloc_size)
|
||||||
|
{
|
||||||
|
jump_table = alloc_jump_table();
|
||||||
|
current_pos = jump_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto ptr = current_pos;
|
||||||
|
current_pos += far_jmp_size;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t Base, typename T>
|
||||||
|
void* create_far_jump(const T dest)
|
||||||
|
{
|
||||||
|
static std::unordered_map<void*, void*> allocated_jumps;
|
||||||
|
if (const auto iter = allocated_jumps.find(reinterpret_cast<void*>(dest)); iter != allocated_jumps.end())
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto pos = allocate_far_jump<Base>();
|
||||||
|
jump(pos, dest, true);
|
||||||
|
allocated_jumps.insert(std::make_pair(dest, pos));
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t Base, typename T>
|
||||||
|
void far_jump(const size_t address, const T dest)
|
||||||
|
{
|
||||||
|
const auto pos = create_far_jump<Base>(dest);
|
||||||
|
jump(address, pos, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t Base, typename T>
|
||||||
|
void far_call(const size_t address, const T dest)
|
||||||
|
{
|
||||||
|
const auto pos = create_far_jump<Base>(dest);
|
||||||
|
call(address, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -166,6 +166,33 @@ namespace utils
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* memory::allocate_near(const size_t address, const size_t size, const std::uint32_t protect)
|
||||||
|
{
|
||||||
|
SYSTEM_INFO system_info{};
|
||||||
|
GetSystemInfo(&system_info);
|
||||||
|
|
||||||
|
const auto page_size = system_info.dwPageSize;
|
||||||
|
const auto aligned_size = size + (~size & (page_size - 1));
|
||||||
|
auto current_address = address;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
current_address -= page_size;
|
||||||
|
|
||||||
|
if (current_address <= reinterpret_cast<size_t>(system_info.lpMinimumApplicationAddress))
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto result = VirtualAlloc(reinterpret_cast<void*>(current_address), aligned_size, MEM_RESERVE | MEM_COMMIT, protect);
|
||||||
|
if (result != nullptr)
|
||||||
|
{
|
||||||
|
std::memset(result, 0, aligned_size);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memory::allocator* memory::get_allocator()
|
memory::allocator* memory::get_allocator()
|
||||||
{
|
{
|
||||||
return &memory::mem_allocator_;
|
return &memory::mem_allocator_;
|
||||||
|
@ -69,6 +69,8 @@ namespace utils
|
|||||||
static bool is_bad_code_ptr(const void* ptr);
|
static bool is_bad_code_ptr(const void* ptr);
|
||||||
static bool is_rdata_ptr(void* ptr);
|
static bool is_rdata_ptr(void* ptr);
|
||||||
|
|
||||||
|
static void* allocate_near(const size_t address, const size_t size, const std::uint32_t protect);
|
||||||
|
|
||||||
static allocator* get_allocator();
|
static allocator* get_allocator();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user