From ffc97a564275bad0832d35a5db8bd2a66a969976 Mon Sep 17 00:00:00 2001 From: altalk23 <45172705+altalk23@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:50:31 +0300 Subject: [PATCH] i am eating my thumbs (arm reference) --- src/Handler.cpp | 87 ++++++++------------------------ src/Handler.hpp | 2 + src/generator/ArmV7Generator.cpp | 19 +++---- src/target/PosixArmV7Target.cpp | 11 ++++ src/target/PosixArmV7Target.hpp | 3 ++ src/target/Target.cpp | 8 +++ src/target/Target.hpp | 4 ++ 7 files changed, 54 insertions(+), 80 deletions(-) diff --git a/src/Handler.cpp b/src/Handler.cpp index 6cd32d7..f9c837b 100644 --- a/src/Handler.cpp +++ b/src/Handler.cpp @@ -53,19 +53,24 @@ Result<> Handler::init() { auto target = m_modifiedBytes.size(); - auto address = reinterpret_cast(m_address); + auto address = reinterpret_cast(Target::get().getRealPtr(m_address)); m_originalBytes.insert(m_originalBytes.begin(), address, address + target); TULIP_HOOK_UNWRAP_INTO(auto trampolineOffset, generator->relocateOriginal(target)); TULIP_HOOK_UNWRAP(generator->generateTrampoline(trampolineOffset)); - auto metadata = HookMetadata(); - metadata.m_priority = INT32_MAX; - static_cast(this->createHook(m_wrapped, metadata)); + this->addOriginal(); return Ok(); } +void Handler::addOriginal() { + auto metadata = HookMetadata{ + .m_priority = INT32_MAX, + }; + static_cast(this->createHook(Target::get().getRealPtrAs(m_wrapped, m_address), metadata)); +} + HookHandle Handler::createHook(void* address, HookMetadata m_metadata) { static size_t s_nextHookHandle = 0; auto hook = HookHandle(++s_nextHookHandle); @@ -96,10 +101,7 @@ void Handler::clearHooks() { m_handles.clear(); m_content->m_functions.clear(); - auto metadata = HookMetadata{ - .m_priority = INT32_MAX, - }; - static_cast(this->createHook(m_wrapped, metadata)); + this->addOriginal(); } void Handler::updateHookMetadata(HookHandle const& hook, HookMetadata const& metadata) { @@ -115,68 +117,19 @@ void Handler::reorderFunctions() { } Result<> Handler::interveneFunction() { - return Target::get().writeMemory(m_address, static_cast(m_modifiedBytes.data()), m_modifiedBytes.size()); + return Target::get().writeMemory( + Target::get().getRealPtr(m_address), + static_cast(m_modifiedBytes.data()), + m_modifiedBytes.size() + ); } Result<> Handler::restoreFunction() { - return Target::get().writeMemory(m_address, static_cast(m_originalBytes.data()), m_originalBytes.size()); -} - -// TODO: fully remove the symbol resolver because i dont like it -bool TULIP_HOOK_DEFAULT_CONV Handler::symbolResolver(char const* csymbol, uint64_t* value) { - std::string symbol = csymbol; - - if (symbol.find("_address") != std::string::npos) { - auto in = std::istringstream(symbol.substr(8)); - - std::string input; - std::getline(in, input, '_'); - HandlerHandle handler = std::stoll(input, nullptr, 16); - std::getline(in, input, '_'); - size_t offset = std::stoll(input, nullptr, 10); - - *value = reinterpret_cast(Pool::get().getHandler(handler).m_address) + offset; - return true; - } - - if (symbol.find("_handler") != std::string::npos) { - auto in = std::istringstream(symbol.substr(8)); - - std::string input; - std::getline(in, input, '_'); - HandlerHandle handler = std::stoll(input, nullptr, 16); - - *value = reinterpret_cast(Pool::get().getHandler(handler).m_handler); - return true; - } - - if (symbol.find("_content") != std::string::npos) { - auto in = std::istringstream(symbol.substr(8)); - - std::string input; - std::getline(in, input, '_'); - HandlerHandle handler = std::stoll(input, nullptr, 16); - - *value = reinterpret_cast(Pool::get().getHandler(handler).m_content); - return true; - } - - if (symbol.find("_incrementIndex") != std::string::npos) { - *value = reinterpret_cast(&Handler::incrementIndex); - return true; - } - - if (symbol.find("_decrementIndex") != std::string::npos) { - *value = reinterpret_cast(&Handler::decrementIndex); - return true; - } - - if (symbol.find("_getNextFunction") != std::string::npos) { - *value = reinterpret_cast(&Handler::getNextFunction); - return true; - } - - return false; + return Target::get().writeMemory( + Target::get().getRealPtr(m_address), + static_cast(m_originalBytes.data()), + m_originalBytes.size() + ); } static thread_local std::stack s_indexStack; diff --git a/src/Handler.hpp b/src/Handler.hpp index 7b22668..304e160 100644 --- a/src/Handler.hpp +++ b/src/Handler.hpp @@ -49,6 +49,8 @@ namespace tulip::hook { void clearHooks(); + void addOriginal(); + void reorderFunctions(); void updateHookMetadata(HookHandle const& hook, HookMetadata const& metadata); diff --git a/src/generator/ArmV7Generator.cpp b/src/generator/ArmV7Generator.cpp index 0f20022..87739d5 100644 --- a/src/generator/ArmV7Generator.cpp +++ b/src/generator/ArmV7Generator.cpp @@ -30,8 +30,8 @@ Result ArmV7HandlerGenerator::relocateOri auto origin = new CodeMemBlock((uint64_t)m_address, target); auto relocated = new CodeMemBlock(); // idk about arm thumb stuff help me - auto originBuffer = (void*)((uint64_t)m_address + 1); - auto relocatedBuffer = (void*)m_trampoline; + auto originBuffer = m_address; + auto relocatedBuffer = m_trampoline; GenRelocateCodeAndBranch(originBuffer, relocatedBuffer, origin, relocated); @@ -109,7 +109,8 @@ std::vector ArmV7HandlerGenerator::intervenerBytes(uint64_t address) { a.ldrw(PC, "handler"); a.label("handler"); - a.write32(reinterpret_cast(m_handler)); + // my thumbs will eat me + a.write32(reinterpret_cast(m_handler) + 1); a.updateLabels(); @@ -117,16 +118,8 @@ std::vector ArmV7HandlerGenerator::intervenerBytes(uint64_t address) { } std::vector ArmV7HandlerGenerator::trampolineBytes(uint64_t address, size_t offset) { - ArmV7Assembler a(address); - using enum ArmV7Register; - - a.ldrw(PC, "original"); - a.label("original"); - a.write32(reinterpret_cast(m_address) + offset); - - a.updateLabels(); - - return std::move(a.m_buffer); + // Dobby handles the creation of the trampoline + return {}; } Result<> ArmV7HandlerGenerator::generateTrampoline(RelocateReturn offsets) { diff --git a/src/target/PosixArmV7Target.cpp b/src/target/PosixArmV7Target.cpp index a558991..4256ea9 100644 --- a/src/target/PosixArmV7Target.cpp +++ b/src/target/PosixArmV7Target.cpp @@ -36,4 +36,15 @@ std::unique_ptr PosixArmV7Target::getWrapperGenerator(void* ad return std::make_unique(address, metadata); } +// Thumb is very fun to deal with! +void* PosixArmV7Target::getRealPtr(void* ptr) { + return reinterpret_cast(reinterpret_cast(ptr) & (~1)); +} +void* PosixArmV7Target::getRealPtrAs(void* ptr, void* lookup) { + return reinterpret_cast( + reinterpret_cast(this->getRealPtr(ptr)) | + (reinterpret_cast(lookup) & 1) + ); +} + #endif \ No newline at end of file diff --git a/src/target/PosixArmV7Target.hpp b/src/target/PosixArmV7Target.hpp index d3be75e..1454e80 100644 --- a/src/target/PosixArmV7Target.hpp +++ b/src/target/PosixArmV7Target.hpp @@ -18,6 +18,9 @@ namespace tulip::hook { void* address, void* trampoline, void* handler, void* content, void* wrapped, HandlerMetadata const& metadata ) override; std::unique_ptr getWrapperGenerator(void* address, WrapperMetadata const& metadata) override; + + void* getRealPtr(void* ptr) override; + void* getRealPtrAs(void* ptr, void* lookup) override; }; } diff --git a/src/target/Target.cpp b/src/target/Target.cpp index f7e423b..43c0b56 100644 --- a/src/target/Target.cpp +++ b/src/target/Target.cpp @@ -33,3 +33,11 @@ void Target::closeCapstone() { csh Target::getCapstone() { return m_capstone; } + +void* Target::getRealPtr(void* ptr) { + return ptr; +} + +void* Target::getRealPtrAs(void* ptr, void* lookup) { + return ptr; +} \ No newline at end of file diff --git a/src/target/Target.hpp b/src/target/Target.hpp index f5e6a45..c559b2c 100644 --- a/src/target/Target.hpp +++ b/src/target/Target.hpp @@ -42,5 +42,9 @@ namespace tulip::hook { ) = 0; virtual std::unique_ptr getWrapperGenerator(void* address, WrapperMetadata const& metadata) = 0; // sorry :( virtual BaseAssembler* getAssembler(int64_t baseAddress); + + // These just exist because of arm7! fun! + virtual void* getRealPtr(void* ptr); + virtual void* getRealPtrAs(void* ptr, void* lookup); }; };