Skip to content

Commit

Permalink
refactor: prepare for remove direct symbol resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
OEOTYAN committed Sep 13, 2024
1 parent 90892c0 commit f884773
Show file tree
Hide file tree
Showing 18 changed files with 227 additions and 145 deletions.
9 changes: 9 additions & 0 deletions src-server/ll/core/plugin-abi/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,13 @@ LLNDAPI FuncPtr resolveSignature(std::string_view signature, std::span<std::byte
LLNDAPI FuncPtr resolveSignature(std::string_view signature) {
return resolveSignature(signature, sys_utils::getImageRange());
}
LLAPI FuncPtr resolveSymbol(std::string_view symbol, bool disableErrorOutput) {
auto sym = SymbolView{symbol};
auto res = sym.resolve(true);
if (!disableErrorOutput && res == nullptr) {
getLogger().fatal("Couldn't find: {}", sym.toString());
getLogger().fatal("In module: {}", sys_utils::getCallerModuleFileName());
}
return res;
}
} // namespace ll::memory
5 changes: 3 additions & 2 deletions src-test/server/Packet_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ struct magic_enum::customize::enum_range<MinecraftPacketIds> {
};

std::string getVTableName(void* vtable) {
auto res = ll::memory::lookupSymbol(*((void**)vtable));
auto res = ll::memory::Symbol::fromAddress(*((void**)vtable));

if (res.size() == 1) {
return res[0].substr(4, res[0].size() - 9);
auto str = res[0].view().raw();
return std::string{str.substr(4, str.size() - 9)};
} else {
throw std::runtime_error("cannot get symbol");
}
Expand Down
4 changes: 2 additions & 2 deletions src-test/server/TestNbt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,6 @@ LL_AUTO_TYPE_INSTANCE_HOOK(NbtTest, HookPriority::Normal, ServerInstance, &Serve
->toSnbt(SnbtFormat::PrettyConsolePrint)
);

ll::getLogger().debug("signature {}", "48 8D 05 ? ? ? ? E8"_sig.toString(false, false));
ll::getLogger().debug("resolve {}", "48 8D 05 ? ? ? ? E8"_sig.resolve());
ll::getLogger().debug("signature {}", "48 8D 05 ? ? ? ? E8"_sigv.toString(false, false));
ll::getLogger().debug("resolve {}", "48 8D 05 ? ? ? ? E8"_sigv.resolve());
}
11 changes: 5 additions & 6 deletions src/ll/api/base/FixedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@ template <size_t N>
struct FixedString {
char buf[N + 1]{};
consteval FixedString() = default;
// NOLINTBEGIN(google-explicit-constructor)
consteval FixedString(std::string_view s) { std::copy_n(s.data(), s.size(), buf); }
consteval FixedString(char const* s) { std::copy_n(s, N, buf); }
consteval operator char const*() const { return buf; }
consteval operator std::string_view() const { return buf; }
constexpr operator std::string() const { return buf; }
// NOLINTEND(google-explicit-constructor)

[[nodiscard]] constexpr char const& operator[](size_t idx) const { return buf[idx]; }
[[nodiscard]] constexpr char& operator[](size_t idx) { return buf[idx]; }

template <size_t Ny>
consteval auto operator+(const FixedString<Ny>& other) {
Expand All @@ -29,13 +30,11 @@ struct FixedString {
struct StringView {
char const* data;
size_t size;
consteval StringView(std::string_view v) { // NOLINT
consteval StringView(std::string_view v) {
data = v.data();
size = v.size();
}
consteval operator std::string_view() const { // NOLINT
return std::string_view{data, size};
}
consteval operator std::string_view() const { return std::string_view{data, size}; }
};

template <StringView s>
Expand Down
11 changes: 5 additions & 6 deletions src/ll/api/command/Optional.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,13 @@ class Optional {
[[nodiscard]] constexpr T const* operator->() const { return &get(); }
[[nodiscard]] constexpr T* operator->() { return &get(); }

// NOLINTNEXTLINE(google-explicit-constructor)
[[nodiscard]] constexpr operator T const&&() const&& { return std::move(get()); }
[[nodiscard]] constexpr operator T&&() && { return std::move(get()); } // NOLINT(google-explicit-constructor)
[[nodiscard]] constexpr operator T const&() const& { return get(); } // NOLINT(google-explicit-constructor)
[[nodiscard]] constexpr operator T&() & { return get(); } // NOLINT(google-explicit-constructor)
[[nodiscard]] constexpr operator T&&() && { return std::move(get()); }
[[nodiscard]] constexpr operator T const&() const& { return get(); }
[[nodiscard]] constexpr operator T&() & { return get(); }

[[nodiscard]] constexpr operator T const*() const { return &get(); } // NOLINT(google-explicit-constructor)
[[nodiscard]] constexpr operator T*() { return &get(); } // NOLINT(google-explicit-constructor)
[[nodiscard]] constexpr operator T const*() const { return &get(); }
[[nodiscard]] constexpr operator T*() { return &get(); }

template <class U>
[[nodiscard]] constexpr T value_or(U&& right) const& {
Expand Down
6 changes: 2 additions & 4 deletions src/ll/api/data/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ namespace ll::data {
namespace detail {

struct from_chars_result : std::from_chars_result {
[[nodiscard]] constexpr operator bool() const noexcept { // NOLINT(google-explicit-constructor)
return ec == std::errc{};
}
constexpr void value() const {
[[nodiscard]] constexpr operator bool() const noexcept { return ec == std::errc{}; }
constexpr void value() const {
if (ec != std::errc{}) {
throw std::system_error{std::make_error_code(ec)};
}
Expand Down
9 changes: 7 additions & 2 deletions src/ll/api/memory/Hook.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,19 @@ constexpr FuncPtr resolveIdentifier(T identifier) {
// TODO: remove in release
template <class T>
constexpr FuncPtr resolveIdentifier(std::string_view identifier) {
return resolveSymbol(identifier, false);
return SymbolView{identifier}.resolve();
}

template <class T>
constexpr FuncPtr resolveIdentifier(SignatureView identifier) {
return identifier.resolve();
}

template <class T>
constexpr FuncPtr resolveIdentifier(SymbolView identifier) {
return identifier.resolve();
}

template <class T>
constexpr FuncPtr resolveIdentifier(uintptr_t address) {
return toFuncPtr(address);
Expand Down Expand Up @@ -176,7 +181,7 @@ struct LL_EBO Hook {};
\
static int hook(bool suspendThreads = true) { \
detector<_OriginFuncType>(); \
_HookTarget = ::ll::memory::resolveIdentifier<_OriginFuncType>(IDENTIFIER); \
if (!_HookTarget) _HookTarget = ::ll::memory::resolveIdentifier<_OriginFuncType>(IDENTIFIER); \
return ::ll::memory::hook( \
_HookTarget, \
::ll::memory::toFuncPtr(&DEF_TYPE::detour), \
Expand Down
55 changes: 6 additions & 49 deletions src/ll/api/memory/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,24 @@
#include <optional>
#include <vector>

#include "pl/SymbolProvider.h"

#include "ll/api/io/Logger.h"
#include "ll/api/service/GamingStatus.h"
#include "ll/api/thread/GlobalThreadPauser.h"
#include "ll/api/utils/StringUtils.h"
#include "ll/api/utils/SystemUtils.h"
#include "ll/core/LeviLamina.h"

#include "mc/deps/core/common/bedrock/IMemoryAllocator.h"

#include "demangler/Demangle.h"

namespace ll::memory {

std::string demangleSymbol(std::string_view symbol) {
std::string res;
if (demangler::nonMicrosoftDemangle(symbol, res)) return res;
else if (symbol.starts_with("_")) { // some platform's external symbol style...
demangler::nonMicrosoftDemangle(symbol.substr(1), res);
} else {
if (char* demangled = demangler::microsoftDemangle(
symbol,
nullptr,
nullptr,
(demangler::MSDemangleFlags)(demangler::MSDF_NoAccessSpecifier | demangler::MSDF_NoCallingConvention)
)) {
res = demangled;
std::free(demangled);
} else {
res = symbol;
}
}
return res;
}
FuncPtr resolveSymbol(char const* symbol) {
auto res = pl::symbol_provider::pl_resolve_symbol_silent(symbol);
LLAPI FuncPtr resolveSymbol(char const* symbol) { // for link
auto sym = SymbolView{
{symbol, strlen(symbol)}
};
auto res = sym.resolve(true);
if (res == nullptr) {
getLogger().fatal("Couldn't find: {}", demangleSymbol(symbol));
getLogger().fatal("Couldn't find: {}", sym.toString());
getLogger().fatal("In module: {}", sys_utils::getCallerModuleFileName());
}
return res;
}
FuncPtr resolveSymbol(std::string_view symbol, bool disableErrorOutput) {
auto res = pl::symbol_provider::pl_resolve_symbol_silent_n(symbol.data(), symbol.size());
if (!disableErrorOutput && res == nullptr) {
getLogger().fatal("Couldn't find: {}", demangleSymbol(symbol));
getLogger().fatal("In module: {}", sys_utils::getCallerModuleFileName());
}
return res;
}
std::vector<std::string> lookupSymbol(FuncPtr func) {
std::vector<std::string> symbols;
size_t length;
auto result = pl::symbol_provider::pl_lookup_symbol(func, &length);
for (size_t i = 0; i < length; i++) {
symbols.emplace_back(result[i]);
}
if (result) pl::symbol_provider::pl_free_lookup_result(result);
return symbols;
}
size_t getUsableSize(void* ptr) { return getDefaultAllocator().getUsableSize(ptr); }

[[noreturn]] void throwMemoryException(size_t size) {
Expand Down
41 changes: 6 additions & 35 deletions src/ll/api/memory/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "ll/api/base/FixedString.h"
#include "ll/api/base/Macro.h"
#include "ll/api/memory/Signature.h"
#include "ll/api/memory/Symbol.h"

namespace Bedrock::Memory {
class IMemoryAllocator;
Expand Down Expand Up @@ -53,24 +54,6 @@ template <class T>
inline void memcpy_t(void* dst, void const* src) {
memcpy(dst, src, sizeof(T));
}

/**
* @brief resolve symbol to function pointer
* @param symbol Symbol
* @return function pointer
*/
LLNDAPI FuncPtr resolveSymbol(char const* symbol);

LLNDAPI FuncPtr resolveSymbol(std::string_view symbol, bool disableErrorOutput);

LLNDAPI std::string demangleSymbol(std::string_view symbol);
/**
* @brief lookup symbol name of a function address
* @param func Function address
* @return symbols
*/
LLNDAPI std::vector<std::string> lookupSymbol(FuncPtr func);

/**
* @brief make a region of memory writable and executable, then call the
* callback, and finally restore the region.
Expand All @@ -85,6 +68,11 @@ inline void modify(T& ref, std::function<void(std::remove_cv_t<T>&)> const& f) {
modify((void*)std::addressof(ref), sizeof(T), [&] { f((std::remove_cv_t<T>&)(ref)); });
}

template <class RTN = void, class... Args>
constexpr auto addressCall(void const* address, auto&&... args) -> RTN {
return ((RTN(*)(Args...))address)(std::forward<decltype((args))>(args)...);
}

template <class RTN = void, class... Args>
constexpr auto virtualCall(void const* self, ptrdiff_t vIndex, auto&&... args) -> RTN {
return (*(RTN(**)(void const*, Args...))(*(uintptr_t**)self + vIndex))(
Expand Down Expand Up @@ -201,21 +189,4 @@ class VirtualMemory {
return reinterpret_cast<T*>(pointer);
}
};

template <FixedString symbol>
inline FuncPtr symbolCache = resolveSymbol(symbol, false);

template <FixedString signature>
inline FuncPtr signatureResultCache = signatureCache.view().resolve();

} // namespace ll::memory

#define LL_RESOLVE_SYMBOL(symbol) (ll::memory::symbolCache<symbol>)

#define LL_RESOLVE_SIGNATURE(signature) (ll::memory::signatureCache<signature>)

#define LL_SYMBOL_CALL(symbol, Ret, ...) ((Ret(*)(__VA_ARGS__))(ll::memory::symbolCache<symbol>))

#define LL_ADDRESS_CALL(address, Ret, ...) ((Ret(*)(__VA_ARGS__))(address))

#define LL_SIGNATURE_CALL(signature, Ret, ...) ((Ret(*)(__VA_ARGS__))(ll::memory::signatureCache<signature>))
35 changes: 24 additions & 11 deletions src/ll/api/memory/Signature.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,16 @@ class SignatureElement {
};

class SignatureView {
std::span<SignatureElement const> const elements;
std::span<SignatureElement const> elements;

public:
[[nodiscard]] constexpr SignatureView() = default;

[[nodiscard]] constexpr SignatureView(SignatureView&&) noexcept = default;
LL_MAY_CONSTEXPR SignatureView& operator=(SignatureView&&) noexcept = default;
[[nodiscard]] constexpr SignatureView(SignatureView const&) noexcept = default;
LL_MAY_CONSTEXPR SignatureView& operator=(SignatureView const&) noexcept = default;

[[nodiscard]] constexpr SignatureView(std::span<SignatureElement const> span) : elements(span) {}

[[nodiscard]] constexpr SignatureView(Signature const& signature);
Expand All @@ -66,7 +72,7 @@ class SignatureView {
};

class Signature {
std::vector<SignatureElement> const elements;
std::vector<SignatureElement> elements;

[[nodiscard]] constexpr Signature(std::vector<SignatureElement> vec) : elements(std::move(vec)) {}

Expand Down Expand Up @@ -123,7 +129,11 @@ class FixedSignature {
[[nodiscard]] constexpr SignatureView view() const { return {std::span{elements}}; }
};

template <FixedString str>
template <size_t N>
[[nodiscard]] constexpr SignatureView::SignatureView(FixedSignature<N> const& signature)
: SignatureView(signature.view()) {}

template <FixedString signature>
constexpr auto signatureCache = []() {
constexpr size_t N = []() {
size_t i = 0;
Expand All @@ -132,24 +142,27 @@ constexpr auto signatureCache = []() {
i++;
return true;
},
str,
signature,
" "
);
return i;
}();
FixedSignature<N> res{Signature::parse(str)};
FixedSignature<N> res{Signature::parse(signature)};
return res;
}();

template <size_t N>
[[nodiscard]] constexpr SignatureView::SignatureView(FixedSignature<N> const& signature)
: SignatureView(signature.view()) {}
template <FixedString signature>
inline void* signatureAddressCache = signatureCache<signature>.view().resolve();

} // namespace ll::memory

namespace ll::inline literals::inline memory_literals {
template <FixedString str>
consteval memory::SignatureView operator""_sig() noexcept {
return memory::signatureCache<str>.view();
template <FixedString signature>
consteval memory::SignatureView operator""_sigv() noexcept {
return memory::signatureCache<signature>.view();
}
template <FixedString signature>
constexpr void* operator""_sig() noexcept {
return memory::signatureAddressCache<signature>;
}
} // namespace ll::inline literals::inline memory_literals
48 changes: 48 additions & 0 deletions src/ll/api/memory/Symbol.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "ll/api/memory/Symbol.h"

#include "ll/api/utils/SystemUtils.h"
#include "ll/core/LeviLamina.h"

#include "demangler/Demangle.h"
#include "pl/SymbolProvider.h"

namespace ll::memory {
void* SymbolView::resolve(bool disableErrorOutput) const {
auto res = pl::symbol_provider::pl_resolve_symbol_silent_n(sym.data(), sym.size());
if (!disableErrorOutput && res == nullptr) {
getLogger().fatal("Couldn't find: {}", toString());
getLogger().fatal("In module: {}", sys_utils::getCallerModuleFileName());
}
return res;
}
std::string SymbolView::toString() const {
std::string res;
if (demangler::nonMicrosoftDemangle(sym, res)) return res;
else if (sym.starts_with("_")) { // some platform's external sym style...
demangler::nonMicrosoftDemangle(sym.substr(1), res);
} else {
if (char* demangled = demangler::microsoftDemangle(
sym,
nullptr,
nullptr,
(demangler::MSDemangleFlags)(demangler::MSDF_NoAccessSpecifier | demangler::MSDF_NoCallingConvention)
)) {
res = demangled;
std::free(demangled);
} else {
res = sym;
}
}
return res;
}
std::vector<Symbol> Symbol::fromAddress(void* func) {
std::vector<Symbol> result;
size_t length{};
auto symbols = pl::symbol_provider::pl_lookup_symbol(func, &length);
for (size_t i = 0; i < length; i++) {
result.emplace_back(symbols[i]);
}
if (symbols) pl::symbol_provider::pl_free_lookup_result(symbols);
return result;
}
} // namespace ll::memory
Loading

0 comments on commit f884773

Please sign in to comment.