Add experimental TLS loader
This commit is contained in:
parent
e1333db8a2
commit
2d5a4e43b3
99
src/loader/tls_loader.cpp
Normal file
99
src/loader/tls_loader.cpp
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "tls_loader.hpp"
|
||||||
|
#include "utils/nt.hpp"
|
||||||
|
|
||||||
|
std::mutex tls_loader::mutex_;
|
||||||
|
std::vector<std::unique_ptr<tls_loader::tls_entry>> tls_loader::tls_entries_;
|
||||||
|
|
||||||
|
//static thread_local tls_loader::tls_executer $;
|
||||||
|
|
||||||
|
void tls_loader::handle(IMAGE_TLS_DIRECTORY* tls_directory)
|
||||||
|
{
|
||||||
|
std::lock_guard _(mutex_);
|
||||||
|
tls_entries_.push_back(std::make_unique<tls_entry>(tls_directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
void tls_loader::execute(const bool is_attaching)
|
||||||
|
{
|
||||||
|
std::lock_guard _(mutex_);
|
||||||
|
|
||||||
|
for (auto& entry : tls_entries_)
|
||||||
|
{
|
||||||
|
entry->execute(is_attaching);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_loader::tls_entry::tls_entry(IMAGE_TLS_DIRECTORY* tls_directory) : tls_directory_(tls_directory)
|
||||||
|
{
|
||||||
|
this->tls_index_ = 18;//TlsAlloc();
|
||||||
|
*reinterpret_cast<DWORD*>(this->tls_directory_->AddressOfIndex) = this->tls_index_;
|
||||||
|
|
||||||
|
this->execute(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_loader::tls_entry::~tls_entry()
|
||||||
|
{
|
||||||
|
//TlsFree(this->tls_index_);
|
||||||
|
this->allocator_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tls_loader::tls_entry::execute(const bool is_attaching)
|
||||||
|
{
|
||||||
|
if (is_attaching) this->attach();
|
||||||
|
else this->detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void tls_loader::tls_entry::attach()
|
||||||
|
{
|
||||||
|
const size_t data_size = this->tls_directory_->EndAddressOfRawData - this->tls_directory_->StartAddressOfRawData;
|
||||||
|
const size_t size = data_size + this->tls_directory_->SizeOfZeroFill;
|
||||||
|
const auto data = this->allocator_.allocate(size);
|
||||||
|
|
||||||
|
std::memcpy(data, PVOID(this->tls_directory_->StartAddressOfRawData), data_size);
|
||||||
|
|
||||||
|
const auto tls_indices = reinterpret_cast<LPVOID*>(__readfsdword(0x2C));
|
||||||
|
tls_indices[this->tls_index_] = data;
|
||||||
|
|
||||||
|
auto callbacks = reinterpret_cast<PIMAGE_TLS_CALLBACK*>(this->tls_directory_->AddressOfCallBacks);
|
||||||
|
if (callbacks)
|
||||||
|
{
|
||||||
|
utils::nt::module self;
|
||||||
|
|
||||||
|
while (*callbacks)
|
||||||
|
{
|
||||||
|
(*callbacks)(self.get_ptr(), DLL_THREAD_ATTACH, nullptr);
|
||||||
|
++callbacks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tls_loader::tls_entry::detach()
|
||||||
|
{
|
||||||
|
auto callbacks = reinterpret_cast<PIMAGE_TLS_CALLBACK*>(this->tls_directory_->AddressOfCallBacks);
|
||||||
|
if (callbacks)
|
||||||
|
{
|
||||||
|
utils::nt::module self;
|
||||||
|
|
||||||
|
while (*callbacks)
|
||||||
|
{
|
||||||
|
(*callbacks)(self.get_ptr(), DLL_THREAD_DETACH, nullptr);
|
||||||
|
++callbacks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto tls_indices = reinterpret_cast<LPVOID*>(__readfsdword(0x2C));
|
||||||
|
const auto data = tls_indices[this->tls_index_];
|
||||||
|
|
||||||
|
//const auto data = TlsGetValue(this->tls_index_);
|
||||||
|
//this->allocator_.free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_loader::tls_executer::tls_executer()
|
||||||
|
{
|
||||||
|
execute(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_loader::tls_executer::~tls_executer()
|
||||||
|
{
|
||||||
|
execute(false);
|
||||||
|
}
|
38
src/loader/tls_loader.hpp
Normal file
38
src/loader/tls_loader.hpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "utils/memory.hpp"
|
||||||
|
|
||||||
|
class tls_loader final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
class tls_executer final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tls_executer();
|
||||||
|
~tls_executer();
|
||||||
|
};
|
||||||
|
|
||||||
|
static void handle(IMAGE_TLS_DIRECTORY* tls_directory);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class tls_entry final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
tls_entry(IMAGE_TLS_DIRECTORY* tls_directory);
|
||||||
|
~tls_entry();
|
||||||
|
|
||||||
|
void execute(bool is_attaching);
|
||||||
|
|
||||||
|
private:
|
||||||
|
utils::memory::allocator allocator_;
|
||||||
|
IMAGE_TLS_DIRECTORY* tls_directory_;
|
||||||
|
DWORD tls_index_;
|
||||||
|
|
||||||
|
void attach();
|
||||||
|
void detach();
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::mutex mutex_;
|
||||||
|
static std::vector<std::unique_ptr<tls_entry>> tls_entries_;
|
||||||
|
|
||||||
|
static void execute(bool is_attaching);
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user