Skip to content

Commit

Permalink
feat: use dual mapping replace virtual protect
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Oct 19, 2024
1 parent 8c5de90 commit 0cea1f1
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 80 deletions.
5 changes: 2 additions & 3 deletions src/ll/api/memory/Closure.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,12 @@ class NativeClosure<Ret(Args...)> {
uintptr_t data;
} stored;

VirtualMemory closure{};
DualMapping closure{};

NativeClosure(origin_fn* func, uintptr_t data) : stored({func, data}) {
detail::initNativeClosure(this, (void*)closureImpl, implOffset);
}

closure_fn* get() const { return closure.get<closure_fn>(); }
closure_fn* get() const { return reinterpret_cast<closure_fn*>(closure.executable()); }

~NativeClosure() { detail::releaseNativeClosure(this); }

Expand Down
15 changes: 15 additions & 0 deletions src/ll/api/memory/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "mc/deps/core/memory/IMemoryAllocator.h"

#include "pl/MemoryResource.h"

namespace ll::memory {

LLAPI FuncPtr resolveSymbol(char const* symbol) { // for link
Expand All @@ -31,4 +33,17 @@ size_t getUsableSize(void* ptr) { return getDefaultAllocator().getUsableSize(ptr
throw std::bad_alloc();
}
}
void DualMapping::alloc(size_t size) {
free();
memSize = size;
pointer = pl::DualMappingMemoryResource::getInstance().allocate(size);
}
void DualMapping::free() {
if (!pointer) return;
pl::DualMappingMemoryResource::getInstance().deallocate(std::exchange(pointer, nullptr), std::exchange(memSize, 0));
}
void* DualMapping::executable() const {
if (!pointer) return nullptr;
return pl::DualMappingMemoryResource::getInstance().executable(pointer, memSize);
}
} // namespace ll::memory
34 changes: 7 additions & 27 deletions src/ll/api/memory/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,43 +150,23 @@ template <template <class> class P, class T>
}
#endif

enum class AccessMode {
Read = 1 << 0,
Write = 1 << 1,
Execute = 1 << 2,
};

[[nodiscard]] constexpr AccessMode operator|(const AccessMode l, const AccessMode r) noexcept {
return static_cast<AccessMode>(
static_cast<std::underlying_type_t<AccessMode>>(l) | static_cast<std::underlying_type_t<AccessMode>>(r)
);
}
[[nodiscard]] constexpr AccessMode operator&(const AccessMode l, const AccessMode r) noexcept {
return static_cast<AccessMode>(
static_cast<std::underlying_type_t<AccessMode>>(l) & static_cast<std::underlying_type_t<AccessMode>>(r)
);
}
class VirtualMemory {
class DualMapping {
void* pointer{};
size_t memSize{};

public:
LLAPI void alloc(size_t size, AccessMode mode);
LLAPI void alloc(size_t size);
LLAPI void free();

VirtualMemory() = default;
DualMapping() = default;

VirtualMemory(size_t size, AccessMode mode) { alloc(size, mode); }
DualMapping(size_t size) { alloc(size); }

~VirtualMemory() { free(); }
~DualMapping() { free(); }

size_t size() const { return memSize; }

void* get() const { return pointer; }

template <class T>
T* get() const {
return reinterpret_cast<T*>(pointer);
}
void* writable() const { return pointer; }
LLAPI void* executable() const;
};
} // namespace ll::memory
15 changes: 0 additions & 15 deletions src/ll/api/memory/linux/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,4 @@ void modify(void* ptr, size_t len, std::function<void()> const& callback) {
callback();
mprotect(ptr, len, oldProtect);
}
void VirtualMemory::alloc(size_t size, AccessMode mode) {
free();
memSize = size;
int fProtect{};
if ((bool)(mode & AccessMode::Read)) fProtect |= PROT_READ;
if ((bool)(mode & AccessMode::Write)) fProtect |= PROT_WRITE;
if ((bool)(mode & AccessMode::Execute)) fProtect |= PROT_EXEC;

pointer = mmap(nullptr, memSize, fProtect, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
void VirtualMemory::free() {
if (!pointer) return;
munmap(pointer, memSize);
pointer = nullptr;
}
} // namespace ll::memory
21 changes: 0 additions & 21 deletions src/ll/api/memory/win/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,4 @@ void modify(void* ptr, size_t len, std::function<void()> const& callback) {
callback();
VirtualProtect(ptr, len, oldProtect, &oldProtect);
}
void VirtualMemory::alloc(size_t size, AccessMode mode) {
free();
memSize = size;
DWORD fProtect{PAGE_NOACCESS};
if ((bool)(mode & AccessMode::Read) && (bool)(mode & AccessMode::Write)) {
fProtect = PAGE_READWRITE;
} else if ((bool)(mode & AccessMode::Read)) {
fProtect = PAGE_READONLY;
} else if ((bool)(mode & AccessMode::Write)) {
fProtect = PAGE_WRITECOPY;
}
if ((bool)(mode & AccessMode::Execute)) fProtect *= PAGE_EXECUTE;

pointer = VirtualAlloc(nullptr, memSize, MEM_COMMIT | MEM_RESERVE, fProtect);
}
void VirtualMemory::free() {
if (!pointer) return;
VirtualFree(pointer, 0, MEM_RELEASE);
pointer = nullptr;
}

} // namespace ll::memory
24 changes: 11 additions & 13 deletions src/ll/api/memory/x64/Closure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,17 @@ void initNativeClosure(void* self, void* impl, size_t offset) {
impl = unwrapFuncAddress(impl);
auto tSelf = (T*)self;

tSelf->closure.alloc(size, AccessMode::Execute | AccessMode::Read);

modify(tSelf->closure.get(), size, [&]() {
memcpy(tSelf->closure.get(), impl, offset);

new ((char*)(tSelf->closure.get()) + offset) NativeClosurePrologue{
.data = (uintptr_t)&tSelf->stored,
.push_rax = 0x50,
.mov_rax = {0x48, 0xB8},
.addr = (uintptr_t)impl + offset + sizeof(uintptr_t) - 1, // -1 for 0x58 in magic
.jmp_rax = {0xFF, 0xE0}
};
});
tSelf->closure.alloc(size);

memcpy(tSelf->closure.writable(), impl, offset);

new ((char*)(tSelf->closure.writable()) + offset) NativeClosurePrologue{
.data = (uintptr_t)&tSelf->stored,
.push_rax = 0x50,
.mov_rax = {0x48, 0xB8},
.addr = (uintptr_t)impl + offset + sizeof(uintptr_t) - 1, // -1 for 0x58 in magic
.jmp_rax = {0xFF, 0xE0}
};
}
void releaseNativeClosure(void* /*self*/) {}

Expand Down
2 changes: 1 addition & 1 deletion xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ add_requires("pcg_cpp v1.0.0")
add_requires("pfr 2.1.1")
add_requires("demangler v17.0.7")
add_requires("levibuildscript 0.2.0")
add_requires("preloader v1.9.0")
add_requires("preloader v1.12.0")
add_requires("symbolprovider v1.2.0")

if is_windows then
Expand Down

0 comments on commit 0cea1f1

Please sign in to comment.