Skip to content

Refactor? Yes (+ Patchless support) #25

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

Merged
merged 15 commits into from
Jun 20, 2025
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ jobs:
id: ios-arm
os: macos-14
build_tests: false
extra_flags: "-DTULIP_DONT_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_SYSTEM_NAME=iOS"
out_paths: './build/src/libTulipHook.a'
extra_flags: "-DTULIP_BUILD_DYNAMIC=ON -DTULIP_DONT_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug -DCMAKE_SYSTEM_NAME=iOS"
out_paths: './build/src/libTulipHook.dylib'

name: Build and Test ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
Expand Down
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ project(TulipHookRoot LANGUAGES CXX C)
include(cmake/CPM.cmake)

option(TULIP_LINK_SOURCE "Link to TulipHook source files, including external libs" OFF)
option(TULIP_BUILD_DYNAMIC "Build TulipHook as a dynamic library" OFF)

if(TULIP_LINK_SOURCE OR PROJECT_IS_TOP_LEVEL)
if(ANDROID OR UNIX OR APPLE)
Expand Down
11 changes: 9 additions & 2 deletions include/tulip/Platform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
#define TULIP_HOOK_WINDOWS 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1

#define TULIP_HOOK_DEFAULT_CONV __cdecl

#if defined(WIN64) || defined(_WIN64) || defined(__WIN64) && !defined(__CYGWIN__)
#define TULIP_HOOK_X64 1
#define TULIP_HOOK_MICROSOFT_X64_CONV 1
#define TULIP_HOOK_DEFAULT_CONV
#else
#define TULIP_HOOK_X86 1
#define TULIP_HOOK_CDECL_CONV 1
#define TULIP_HOOK_DEFAULT_CONV __cdecl
#endif

#ifdef TULIP_HOOK_DYNAMIC
Expand Down Expand Up @@ -41,9 +43,11 @@

#if TARGET_CPU_ARM64
#define TULIP_HOOK_ARMV8 1
#define TULIP_HOOK_AAPCS64_CONV 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1
#elif TARGET_CPU_X86_64
#define TULIP_HOOK_X64 1
#define TULIP_HOOK_SYSTEMV_CONV 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1
#endif

Expand All @@ -58,6 +62,7 @@
#define TULIP_HOOK_IOS 1

#define TULIP_HOOK_DEFAULT_CONV
#define TULIP_HOOK_AAPCS64_CONV 1

#define TULIP_HOOK_ARMV8 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1
Expand All @@ -82,9 +87,11 @@

#if defined(__arm__)
#define TULIP_HOOK_ARMV7 1
#define TULIP_HOOK_AAPCS_CONV 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1
#elif defined(__aarch64__)
#define TULIP_HOOK_ARMV8 1
#define TULIP_HOOK_AAPCS64_CONV 1
#define TULIP_HOOK_SUPPORTED_PLATFORM 1
#endif

Expand Down
9 changes: 9 additions & 0 deletions include/tulip/TulipHook.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,13 @@ namespace tulip::hook {
TULIP_HOOK_DLL std::shared_ptr<CallingConvention> createConvention(TulipConvention convention) noexcept;

TULIP_HOOK_DLL geode::Result<void, std::string> disableRuntimeIntervening(void* commonHandlerSpace) noexcept;

struct RelocaledBytesReturn {
std::vector<uint8_t> bytes;
size_t offset;
std::string error;
};
TULIP_HOOK_DLL RelocaledBytesReturn getRelocatedBytes(int64_t original, int64_t relocated, std::vector<uint8_t> const& originalBuffer);
TULIP_HOOK_DLL std::vector<uint8_t> getCommonHandlerBytes(int64_t handler, ptrdiff_t spaceOffset);
TULIP_HOOK_DLL std::vector<uint8_t> getCommonIntervenerBytes(int64_t original, int64_t handler, size_t unique, ptrdiff_t relocOffset);
}
1 change: 1 addition & 0 deletions include/tulip/WrapperData.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "AbstractFunction.hpp"
#include "HandlerData.hpp"

#include <memory>

Expand Down
25 changes: 25 additions & 0 deletions include/tulip/platform/AAPCS64Convention.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "../Platform.hpp"

#include "../CallingConvention.hpp"

#include <memory>
#include <string>

namespace tulip::hook {
class AbstractFunction;

class TULIP_HOOK_DLL AAPCS64Convention : public CallingConvention {
public:
~AAPCS64Convention() override;

void generateDefaultCleanup(BaseAssembler& a, AbstractFunction const& function) override;
void generateIntoDefault(BaseAssembler& a, AbstractFunction const& function) override;
void generateIntoOriginal(BaseAssembler& a, AbstractFunction const& function) override;
void generateOriginalCleanup(BaseAssembler& a, AbstractFunction const& function) override;
bool needsWrapper(AbstractFunction const& function) const override;

static std::shared_ptr<AAPCS64Convention> create();
};
}
25 changes: 25 additions & 0 deletions include/tulip/platform/AAPCSConvention.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "../Platform.hpp"

#include "../CallingConvention.hpp"

#include <memory>
#include <string>

namespace tulip::hook {
class AbstractFunction;

class TULIP_HOOK_DLL AAPCSConvention : public CallingConvention {
public:
~AAPCSConvention() override;

void generateDefaultCleanup(BaseAssembler& a, AbstractFunction const& function) override;
void generateIntoDefault(BaseAssembler& a, AbstractFunction const& function) override;
void generateIntoOriginal(BaseAssembler& a, AbstractFunction const& function) override;
void generateOriginalCleanup(BaseAssembler& a, AbstractFunction const& function) override;
bool needsWrapper(AbstractFunction const& function) const override;

static std::shared_ptr<AAPCSConvention> create();
};
}
14 changes: 10 additions & 4 deletions include/tulip/platform/PlatformConvention.hpp
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
#include "../Platform.hpp"
#include "AAPCS64Convention.hpp"
#include "AAPCSConvention.hpp"
#include "DefaultConvention.hpp"
#include "Windows32Convention.hpp"
#include "Windows64Convention.hpp"
#include "MacosIntelConvention.hpp"
#include "SystemVConvention.hpp"

namespace tulip::hook {
#if defined(TULIP_HOOK_WINDOWS) && defined(TULIP_HOOK_X86)
#if defined(TULIP_HOOK_CDECL_CONV)
using PlatformConvention = CdeclConvention;
#elif defined(TULIP_HOOK_MACOS) && defined(TULIP_HOOK_X64)
#elif defined(TULIP_HOOK_SYSTEMV_CONV)
using PlatformConvention = SystemVConvention;
#elif defined(TULIP_HOOK_WINDOWS) && defined(TULIP_HOOK_X64)
#elif defined(TULIP_HOOK_MICROSOFT_X64_CONV)
using PlatformConvention = Windows64Convention;
#elif defined(TULIP_HOOK_AAPCS_CONV)
using PlatformConvention = AAPCSConvention;
#elif defined(TULIP_HOOK_AAPCS64_CONV)
using PlatformConvention = AAPCS64Convention;
#else
using PlatformConvention = DefaultConvention;
#endif
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include "../Platform.hpp"

#if defined(TULIP_HOOK_MACOS) && defined(TULIP_HOOK_X64)

#include "../CallingConvention.hpp"

#include <memory>
Expand All @@ -25,5 +23,3 @@ namespace tulip::hook {
static std::shared_ptr<SystemVConvention> create();
};
}

#endif
4 changes: 0 additions & 4 deletions include/tulip/platform/Windows32Convention.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include "../Platform.hpp"

#if defined(TULIP_HOOK_WINDOWS) && defined(TULIP_HOOK_X86)

#include "../CallingConvention.hpp"

#include <memory>
Expand Down Expand Up @@ -90,5 +88,3 @@ namespace tulip::hook {
static std::shared_ptr<StdcallConvention> create();
};
}

#endif
9 changes: 3 additions & 6 deletions include/tulip/platform/Windows64Convention.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#include "../Platform.hpp"

#if defined(TULIP_HOOK_WINDOWS) && defined(TULIP_HOOK_X64)

#include "DefaultConvention.hpp"

#include <memory>
Expand All @@ -22,17 +20,16 @@ namespace tulip::hook {
static std::shared_ptr<Windows64Convention> create();
};

class TULIP_HOOK_DLL ThiscallConvention : public Windows64Convention {
class TULIP_HOOK_DLL Thiscall64Convention : public Windows64Convention {
public:
~ThiscallConvention() override;
~Thiscall64Convention() override;

void generateIntoDefault(BaseAssembler& a, AbstractFunction const& function) override;
void generateIntoOriginal(BaseAssembler& a, AbstractFunction const& function) override;
void generateOriginalCleanup(BaseAssembler& a, AbstractFunction const& function) override;
bool needsWrapper(AbstractFunction const& function) const override;

static std::shared_ptr<ThiscallConvention> create();
static std::shared_ptr<Thiscall64Convention> create();
};
}

#endif
27 changes: 20 additions & 7 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@ file(GLOB TULIP_HOOK_BASE_SOURCES
disassembler/BaseDisassembler.cpp
disassembler/ArmV8Disassembler.cpp
disassembler/ThumbV7Disassembler.cpp
convention/AAPCSConvention.cpp
convention/AAPCS64Convention.cpp
convention/CallingConvention.cpp
convention/DefaultConvention.cpp
convention/SystemVConvention.cpp
convention/Windows32Convention.cpp
convention/Windows64Convention.cpp
generator/Generator.cpp
target/Target.cpp
)
Expand All @@ -23,8 +28,6 @@ if(WIN32)
set(TULIP_HOOK_LINK_DOBBY Off)
set(TULIP_HOOK_LINK_CAPSTONE On)
file(GLOB TULIP_HOOK_PLATFORM_SOURCES
convention/Windows32Convention.cpp
convention/Windows64Convention.cpp
generator/X86Generator.cpp
generator/X64Generator.cpp
target/Windows32Target.cpp
Expand All @@ -34,13 +37,13 @@ elseif(APPLE)
set(TULIP_HOOK_LINK_DOBBY On)
set(TULIP_HOOK_LINK_CAPSTONE On)
file(GLOB TULIP_HOOK_PLATFORM_SOURCES
convention/MacosIntelConvention.cpp
generator/X86Generator.cpp
generator/X64Generator.cpp
generator/ArmV8Generator.cpp
target/DarwinTarget.cpp
target/MacosIntelTarget.cpp
target/MacosM1Target.cpp
target/iOSTarget.cpp
)
elseif(ANDROID OR UNIX)
set(TULIP_HOOK_LINK_DOBBY On)
Expand All @@ -56,10 +59,20 @@ else()
message(FATAL_ERROR "Unsupported platform.")
endif()

add_library(${PROJECT_NAME} STATIC
${TULIP_HOOK_BASE_SOURCES}
${TULIP_HOOK_PLATFORM_SOURCES}
)
if (TULIP_BUILD_DYNAMIC)
add_library(${PROJECT_NAME} SHARED
${TULIP_HOOK_BASE_SOURCES}
${TULIP_HOOK_PLATFORM_SOURCES}
)
target_compile_definitions(${PROJECT_NAME} PUBLIC -DTULIP_HOOK_DYNAMIC=1)
else()
add_library(${PROJECT_NAME} STATIC
${TULIP_HOOK_BASE_SOURCES}
${TULIP_HOOK_PLATFORM_SOURCES}
)
endif()



target_compile_features(${PROJECT_NAME} PUBLIC cxx_std_20)

Expand Down
Loading
Loading