TLS patch changes
This commit is contained in:
parent
14b9552a7b
commit
31d4abb84a
@ -9,14 +9,10 @@
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
|
||||
#pragma section("code_buf", read, execute)
|
||||
|
||||
namespace tls
|
||||
{
|
||||
namespace
|
||||
{
|
||||
__declspec(allocate("code_buf")) char code_buffer[0x100]{};
|
||||
|
||||
DWORD get_tls_index()
|
||||
{
|
||||
const auto game = game_module::get_game_module();
|
||||
@ -40,9 +36,8 @@ namespace tls
|
||||
void post_unpack() override
|
||||
{
|
||||
// Add tls_index * 8 offset to tls access where it's missing (it was optimized away in the bnet code)
|
||||
utils::hook::jump(code_buffer, utils::hook::assemble(get_tls_stub), true);
|
||||
|
||||
static std::vector<std::size_t> address_list =
|
||||
std::vector<std::size_t> address_list =
|
||||
{
|
||||
0x14004614C,
|
||||
0x140047A85,
|
||||
@ -114,10 +109,12 @@ namespace tls
|
||||
0x14020C5A3,
|
||||
};
|
||||
|
||||
const auto tls_stub_ptr = utils::hook::assemble(get_tls_stub);
|
||||
|
||||
for (const auto& address : address_list)
|
||||
{
|
||||
utils::hook::nop(address, 0x9);
|
||||
utils::hook::call(address, code_buffer);
|
||||
utils::hook::far_call<BASE_ADDRESS>(address, tls_stub_ptr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -24,7 +24,15 @@ FARPROC WINAPI get_proc_address(const HMODULE hModule, const LPCSTR lpProcName)
|
||||
{
|
||||
if (lpProcName == "InitializeCriticalSectionEx"s)
|
||||
{
|
||||
component_loader::post_unpack();
|
||||
try
|
||||
{
|
||||
component_loader::post_unpack();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
MessageBoxA(nullptr, e.what(), "ERROR", MB_ICONERROR);
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return GetProcAddress(hModule, lpProcName);
|
||||
|
@ -220,6 +220,11 @@ namespace utils::hook
|
||||
set<int32_t>(patch_pointer + 1, int32_t(size_t(data) - (size_t(pointer) + 5)));
|
||||
}
|
||||
|
||||
void call(void* pointer, const size_t data)
|
||||
{
|
||||
return call(pointer, reinterpret_cast<void*>(data));
|
||||
}
|
||||
|
||||
void call(const size_t pointer, void* data)
|
||||
{
|
||||
return call(reinterpret_cast<void*>(pointer), data);
|
||||
@ -255,6 +260,11 @@ namespace utils::hook
|
||||
}
|
||||
}
|
||||
|
||||
void jump(void* pointer, const size_t data, const bool use_far)
|
||||
{
|
||||
return jump(pointer, reinterpret_cast<void*>(data), use_far);
|
||||
}
|
||||
|
||||
void jump(const size_t pointer, void* data, const bool use_far)
|
||||
{
|
||||
return jump(reinterpret_cast<void*>(pointer), data, use_far);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include "signature.hpp"
|
||||
#include "memory.hpp"
|
||||
|
||||
#include <asmjit/core/jitruntime.h>
|
||||
#include <asmjit/x86/x86assembler.h>
|
||||
@ -151,10 +152,12 @@ namespace utils::hook
|
||||
bool is_relatively_far(const void* pointer, const void* data, int offset = 5);
|
||||
|
||||
void call(void* pointer, void* data);
|
||||
void call(void* pointer, size_t data);
|
||||
void call(size_t pointer, void* data);
|
||||
void call(size_t pointer, size_t data);
|
||||
|
||||
void jump(void* pointer, void* data, bool use_far = false);
|
||||
void jump(void* pointer, size_t data, bool use_far = false);
|
||||
void jump(size_t pointer, void* data, bool use_far = false);
|
||||
void jump(size_t pointer, size_t data, bool use_far = false);
|
||||
|
||||
@ -202,4 +205,59 @@ namespace utils::hook
|
||||
{
|
||||
return static_cast<T(*)(Args ...)>(func)(args...);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -158,6 +158,33 @@ namespace utils
|
||||
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()
|
||||
{
|
||||
return &memory::mem_allocator_;
|
||||
|
@ -67,6 +67,8 @@ namespace utils
|
||||
static bool is_bad_code_ptr(const 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();
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user