Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows exception #19

Merged
merged 7 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions include/tulip/FunctionData.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

#include <stddef.h>

namespace tulip::hook {
struct FunctionData {
void* m_address;
size_t m_size;
};
}
1 change: 1 addition & 0 deletions include/tulip/TulipHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "AbstractFunction.hpp"
#include "AbstractType.hpp"
#include "CallingConvention.hpp"
#include "FunctionData.hpp"
#include "HandlerData.hpp"
#include "HookData.hpp"
#include "Platform.hpp"
Expand Down
6 changes: 4 additions & 2 deletions src/Handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ Result<> Handler::init() {
auto generator =
Target::get().getHandlerGenerator(m_address, m_trampoline, m_handler, m_content, m_metadata);

TULIP_HOOK_UNWRAP(generator->generateHandler());
TULIP_HOOK_UNWRAP_INTO(auto handler, generator->generateHandler());
m_handlerSize = handler.m_size;

TULIP_HOOK_UNWRAP_INTO(m_modifiedBytes, generator->generateIntervener());

Expand All @@ -45,7 +46,8 @@ Result<> Handler::init() {
auto address = reinterpret_cast<uint8_t*>(Target::get().getRealPtr(m_address));
m_originalBytes.insert(m_originalBytes.begin(), address, address + target);

TULIP_HOOK_UNWRAP(generator->generateTrampoline(target));
TULIP_HOOK_UNWRAP_INTO(auto trampoline, generator->generateTrampoline(target));
m_trampolineSize = trampoline.m_size;

this->addOriginal();

Expand Down
4 changes: 0 additions & 4 deletions src/Handler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,5 @@ namespace tulip::hook {

Result<> interveneFunction();
Result<> restoreFunction();

void generateHandler();
void generateIntervener();
void generateTrampoline();
};
}
4 changes: 2 additions & 2 deletions src/Wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Result<void*> Wrapper::createWrapper(void* address, WrapperMetadata const& metad
m_wrappers[address] = wrapped;
}

return Ok(m_wrappers[address]);
return Ok(m_wrappers[address].m_address);
}

Result<void*> Wrapper::createReverseWrapper(void* address, WrapperMetadata const& metadata) {
Expand All @@ -26,5 +26,5 @@ Result<void*> Wrapper::createReverseWrapper(void* address, WrapperMetadata const
m_reverseWrappers[address] = wrapped;
}

return Ok(m_reverseWrappers[address]);
return Ok(m_reverseWrappers[address].m_address);
}
5 changes: 3 additions & 2 deletions src/Wrapper.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <FunctionData.hpp>
#include <TulipResult.hpp>
#include <WrapperData.hpp>
#include <memory>
Expand All @@ -10,8 +11,8 @@ namespace tulip::hook {

class Wrapper {
public:
std::unordered_map<void*, void*> m_wrappers;
std::unordered_map<void*, void*> m_reverseWrappers;
std::unordered_map<void*, FunctionData> m_wrappers;
std::unordered_map<void*, FunctionData> m_reverseWrappers;

static Wrapper& get();

Expand Down
7 changes: 7 additions & 0 deletions src/assembler/BaseAssembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,11 @@ void BaseAssembler::label(std::string const& name) {
m_labels[name] = this->currentAddress();
}

void* BaseAssembler::getLabel(std::string const& name) const {
if (m_labels.find(name) == m_labels.end()) {
return nullptr;
}
return reinterpret_cast<void*>(m_labels.at(name));
}

void BaseAssembler::updateLabels() {}
2 changes: 2 additions & 0 deletions src/assembler/BaseAssembler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ namespace tulip::hook {

void label(std::string const& name);

void* getLabel(std::string const& name) const;

virtual void updateLabels();
};
}
7 changes: 7 additions & 0 deletions src/assembler/X64Assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,11 @@ void X64Assembler::shl(X64Register reg, uint8_t value) {
void X64Assembler::xchg(X64Register reg, X64Register reg2) {
rex(this, reg, reg2, true);
X86Assembler::xchg(x86reg(reg), x86reg(reg2));
}

void X64Assembler::align16() {
auto align = 16 - (this->currentAddress() % 16);
for (auto i = 0; i < align; i++) {
this->write8(0x90);
}
}
2 changes: 2 additions & 0 deletions src/assembler/X64Assembler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,7 @@ namespace tulip::hook {
void shl(X64Register reg, uint8_t value);

void xchg(X64Register reg, X64Register reg2);

void align16();
};
}
26 changes: 20 additions & 6 deletions src/assembler/X86Assembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,29 @@ void X86Assembler::encodeModRM(X86Operand op, uint8_t digit) {
}

void X86Assembler::add(X86Register reg, int32_t value) {
this->write8(0x81);
this->write8(0xC0 | regIdx(reg));
this->write32(value);
if (value >= -0x80 && value <= 0x7f) {
this->write8(0x83);
this->write8(0xC0 | regIdx(reg));
this->write8(value);
}
else {
this->write8(0x81);
this->write8(0xC0 | regIdx(reg));
this->write32(value);
}
}

void X86Assembler::sub(X86Register reg, int32_t value) {
this->write8(0x81);
this->write8(0xE8 | regIdx(reg));
this->write32(value);
if (value >= -0x80 && value <= 0x7f) {
this->write8(0x83);
this->write8(0xE8 | regIdx(reg));
this->write8(value);
}
else {
this->write8(0x81);
this->write8(0xE8 | regIdx(reg));
this->write32(value);
}
}

void X86Assembler::push(X86Register reg) {
Expand Down
7 changes: 4 additions & 3 deletions src/convention/Windows64Convention.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ void Windows64Convention::generateDefaultCleanup(BaseAssembler& a_, AbstractFunc
auto& a = static_cast<X64Assembler&>(a_);
using enum X64Register;

size_t paddedSize = getPaddedStackParamSize(function);
a.add(RSP, paddedSize + 0x20);
// size_t paddedSize = getPaddedStackParamSize(function);
// a.add(RSP, paddedSize + 0x20);
}

void Windows64Convention::generateIntoDefault(BaseAssembler& a_, AbstractFunction const& function) {
Expand All @@ -48,7 +48,8 @@ void Windows64Convention::generateIntoDefault(BaseAssembler& a_, AbstractFunctio
size_t stackParamSize = getStackParamSize(function);
auto const paddedSize = (stackParamSize % 16) ? stackParamSize + 8 : stackParamSize;
// + 0x20 for the shadow space before the first arg
a.sub(RSP, paddedSize + 0x20);
// a.sub(RSP, paddedSize + 0x20);
// a.label("convention-alloc-small");
if (stackParamSize > 0) {
// theres stack args, so we need to copy them over

Expand Down
4 changes: 2 additions & 2 deletions src/generator/ArmV7Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ std::vector<uint8_t> ArmV7HandlerGenerator::intervenerBytes(uint64_t address) {
return std::move(a.m_buffer);
}

Result<> ArmV7HandlerGenerator::generateTrampoline(uint64_t target) {
Result<FunctionData> ArmV7HandlerGenerator::generateTrampoline(uint64_t target) {
auto origin = new CodeMemBlock((uint64_t)Target::get().getRealPtr(m_address), target);
auto relocated = new CodeMemBlock();
// idk about arm thumb stuff help me
Expand All @@ -129,5 +129,5 @@ Result<> ArmV7HandlerGenerator::generateTrampoline(uint64_t target) {
if (relocated->size == 0) {
return Err("Failed to relocate original function");
}
return Ok();
return Ok(FunctionData{m_trampoline, relocated->size});
}
2 changes: 1 addition & 1 deletion src/generator/ArmV7Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace tulip::hook {
public:
using HandlerGenerator::HandlerGenerator;

Result<> generateTrampoline(uint64_t target) override;
Result<FunctionData> generateTrampoline(uint64_t target) override;

std::vector<uint8_t> handlerBytes(uint64_t address) override;
std::vector<uint8_t> intervenerBytes(uint64_t address) override;
Expand Down
4 changes: 2 additions & 2 deletions src/generator/ArmV8Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ std::vector<uint8_t> ArmV8HandlerGenerator::intervenerBytes(uint64_t address) {
return std::move(a.m_buffer);
}

Result<> ArmV8HandlerGenerator::generateTrampoline(uint64_t target) {
Result<FunctionData> ArmV8HandlerGenerator::generateTrampoline(uint64_t target) {
auto origin = new CodeMemBlock(reinterpret_cast<uint64_t>(m_address), target);
auto relocated = new CodeMemBlock();
auto originBuffer = m_address;
Expand All @@ -148,5 +148,5 @@ Result<> ArmV8HandlerGenerator::generateTrampoline(uint64_t target) {
if (relocated->size == 0) {
return Err("Failed to relocate original function");
}
return Ok();
return Ok(FunctionData{m_trampoline, relocated->size});
}
2 changes: 1 addition & 1 deletion src/generator/ArmV8Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace tulip::hook {
public:
using HandlerGenerator::HandlerGenerator;

Result<> generateTrampoline(uint64_t target) override;
Result<FunctionData> generateTrampoline(uint64_t target) override;

std::vector<uint8_t> handlerBytes(uint64_t address) override;
std::vector<uint8_t> intervenerBytes(uint64_t address) override;
Expand Down
16 changes: 8 additions & 8 deletions src/generator/Generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ WrapperGenerator::WrapperGenerator(void* address, WrapperMetadata const& metadat
m_address(address),
m_metadata(metadata) {}

Result<> HandlerGenerator::generateHandler() {
Result<FunctionData> HandlerGenerator::generateHandler() {
auto address = reinterpret_cast<uint64_t>(m_handler);
auto encode = this->handlerBytes(address);

TULIP_HOOK_UNWRAP(Target::get().writeMemory(m_handler, encode.data(), encode.size()));

return Ok();
return Ok(FunctionData{m_handler, encode.size()});
}

Result<std::vector<uint8_t>> HandlerGenerator::generateIntervener() {
Expand All @@ -33,7 +33,7 @@ Result<std::vector<uint8_t>> HandlerGenerator::generateIntervener() {
return Ok(std::move(encode));
}

Result<> HandlerGenerator::generateTrampoline(uint64_t target) {
Result<FunctionData> HandlerGenerator::generateTrampoline(uint64_t target) {
TULIP_HOOK_UNWRAP_INTO(auto offsets, this->relocatedBytes(reinterpret_cast<uint64_t>(m_trampoline), target));

auto address = reinterpret_cast<uint64_t>(m_trampoline) + offsets.m_relocatedBytes.size();
Expand All @@ -45,7 +45,7 @@ Result<> HandlerGenerator::generateTrampoline(uint64_t target) {

TULIP_HOOK_UNWRAP(Target::get().writeMemory(m_trampoline, merge.data(), merge.size()));

return Ok();
return Ok(FunctionData{m_trampoline, merge.size()});
}

std::vector<uint8_t> HandlerGenerator::handlerBytes(uint64_t address) {
Expand All @@ -61,12 +61,12 @@ Result<HandlerGenerator::RelocateReturn> HandlerGenerator::relocatedBytes(uint64
return Ok(HandlerGenerator::RelocateReturn());
}

Result<void*> WrapperGenerator::generateWrapper() {
return Ok(m_address); // only windows needs the wrapper
Result<FunctionData> WrapperGenerator::generateWrapper() {
return Ok(FunctionData{m_address, 0}); // only windows needs the wrapper
}

Result<void*> WrapperGenerator::generateReverseWrapper() {
return Ok(m_address); // only windows needs the wrapper
Result<FunctionData> WrapperGenerator::generateReverseWrapper() {
return Ok(FunctionData{m_address, 0}); // only windows needs the wrapper
}

std::vector<uint8_t> WrapperGenerator::wrapperBytes(uint64_t address) {
Expand Down
9 changes: 5 additions & 4 deletions src/generator/Generator.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <FunctionData.hpp>
#include <HandlerData.hpp>
#include <TulipResult.hpp>
#include <WrapperData.hpp>
Expand All @@ -21,15 +22,15 @@ namespace tulip::hook {

virtual ~HandlerGenerator() = default;

virtual Result<> generateHandler();
virtual Result<FunctionData> generateHandler();
virtual Result<std::vector<uint8_t>> generateIntervener();

struct RelocateReturn {
std::vector<uint8_t> m_relocatedBytes;
int64_t m_originalOffset;
};

virtual Result<> generateTrampoline(uint64_t target);
virtual Result<FunctionData> generateTrampoline(uint64_t target);

virtual std::vector<uint8_t> handlerBytes(uint64_t address);
virtual std::vector<uint8_t> intervenerBytes(uint64_t address);
Expand All @@ -46,8 +47,8 @@ namespace tulip::hook {

WrapperGenerator(void* address, WrapperMetadata const& metadata);

virtual Result<void*> generateWrapper();
virtual Result<void*> generateReverseWrapper();
virtual Result<FunctionData> generateWrapper();
virtual Result<FunctionData> generateReverseWrapper();

virtual std::vector<uint8_t> wrapperBytes(uint64_t address);
virtual std::vector<uint8_t> reverseWrapperBytes(uint64_t address);
Expand Down
Loading
Loading