Skip to content

Commit

Permalink
refactor: make NativeClosure safer
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Mar 20, 2024
1 parent cf02a42 commit 5fcfe6c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
23 changes: 13 additions & 10 deletions src/ll/api/memory/Closure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,27 @@ using T = NativeClosure<void*>;
void initNativeClosure(void* t, void* impl, size_t offset, size_t size) {
impl = unwrapFuncPtrJmp(impl);
auto self = (T*)t;
NativeClosurePrologue asmc = {

self->closure = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

memcpy(self->closure, impl, offset);

new ((char*)(self->closure) + offset) NativeClosurePrologue{
.data = (uintptr_t)&self->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}
};

self->closure = std::make_unique_for_overwrite<uchar[]>(size);

VirtualProtect(self->closure.get(), size, PAGE_EXECUTE_READWRITE, &self->oldProtectFlags);

memcpy(self->closure.get(), impl, offset);
memcpy(self->closure.get() + offset, &asmc, sizeof(asmc));
ulong _;
VirtualProtect(self->closure, size, PAGE_EXECUTE_READ, &_);
}
void releaseNativeClosure(void* t, size_t size) {
auto self = (T*)t;
ulong _;
VirtualProtect(self->closure.get(), size, self->oldProtectFlags, &_);
auto self = (T*)t;
if (self->closure != nullptr) {
VirtualFree(self->closure, 0, MEM_RELEASE);
self->closure = nullptr;
}
}
} // namespace ll::memory::detail
6 changes: 3 additions & 3 deletions src/ll/api/memory/Closure.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,14 @@ class NativeClosure {
origin_fn* func;
uintptr_t data;
} stored;
ulong oldProtectFlags{};
std::unique_ptr<uchar[]> closure;

void* closure;

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

closure_fn* get() const { return (closure_fn*)closure.get(); }
closure_fn* get() const { return (closure_fn*)closure; }

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

Expand Down

0 comments on commit 5fcfe6c

Please sign in to comment.