Sinker Runtime Library

class Action

Subclassed by sinker::ActionInstall, sinker::ActionUninstall

Public Functions

virtual void act() = 0
class ActionInstall : public sinker::Action

Public Functions

inline ActionInstall(Installable *installable)
inline virtual void act() override

Private Members

Installable *installable = nullptr
class ActionUninstall : public sinker::Action

Public Functions

inline ActionUninstall(Uninstallable *uninstallable)
inline virtual void act() override

Private Members

Uninstallable *uninstallable = nullptr
class Attributable

Subclassed by sinker::Module, sinker::Symbol

Public Functions

template<typename T>
std::optional<T> get_attribute(std::string_view attribute_name) const
template<typename T>
void set_attribute(std::string const &attribute_name, T value)
std::map<std::string, attribute_value_t, std::less<>> const &get_attributes() const

Private Members

std::map<std::string, attribute_value_t, std::less<>> attributes
class BinaryOperatorExpression : private sinker::Expression

Public Functions

inline BinaryOperatorExpression(std::shared_ptr<Expression> lhs, std::shared_ptr<Expression> rhs, BinaryOperator binary_operator, Type type)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

std::shared_ptr<Expression> lhs
std::shared_ptr<Expression> rhs
BinaryOperator binary_operator
Type type
class Context

Public Functions

inline Context()
Context(Context const&) = delete
Context &operator=(Context const&) = delete
inline std::vector<Module*> const &get_modules() const
Module *get_module(std::string_view module_name)
UserOp *get_user_op(std::string_view user_op_name)
Module *emplace_module(std::string_view name, std::optional<std::string> lpModuleName)
template<typename... Args> inline UserOp * emplace_user_op (std::string_view name, expression_value_t(__cdecl *fn)(Args...))
template<typename... Args> inline UserOp * emplace_user_op (std::string_view name, expression_value_t(__cdecl *fn)(Args...,...))
void dump(std::ostream &out) const
void dump_def(std::ostream &out) const
bool interpret(std::istream &input_stream, Language language, std::string input_filename, bool debug = false)
bool interpret(char const *input, std::size_t size, Language language, std::string input_filename, bool debug = false)
bool interpret(std::string const &input, Language language, std::string input_filename, bool debug = false)
void add_module_tag(std::string const &tag)
void add_symbol_tag(std::string const &tag)
identifier_set_t const &get_symbol_tags() const
~Context()

Private Functions

UserOp * emplace_user_op_impl (std::string_view name, expression_value_t(__cdecl *fn)(...), std::size_t min_arity, std::optional< std::size_t > max_arity)

Private Members

std::vector<Module*> modules
std::vector<UserOp*> user_ops
identifier_set_t module_tags
identifier_set_t symbol_tags
template<typename T>
class Detour : public sinker::Installable, public sinker::Uninstallable

Public Functions

inline Detour(T &real, T wrap)
inline virtual void install() override
inline virtual void uninstall() override

Private Members

T *real = {}
T wrap = {}
class Expression

Subclassed by sinker::BinaryOperatorExpression, sinker::GetProcAddressExpression, sinker::IntegerExpression, sinker::ModuleExpression, sinker::PatternMatchExpression, sinker::SymbolExpression, sinker::UnaryOperatorExpression, sinker::UserOpExpression

Public Functions

virtual std::optional<expression_value_t> calculate(Module *symbol) const = 0
virtual void dump(std::ostream &out) const = 0
inline virtual ~Expression()
class GetProcAddressExpression : private sinker::Expression

Public Functions

inline GetProcAddressExpression(Module *module, std::string const &lpProcName)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

Module *module
std::string lpProcName
class Installable

Subclassed by sinker::Detour< T >, sinker::Patch< T >

Public Functions

virtual void install() = 0
class IntegerExpression : private sinker::Expression

Public Functions

inline IntegerExpression(expression_value_t value)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

expression_value_t value
struct MaskedByte

Public Members

std::uint8_t value
std::uint8_t mask
class Module : public sinker::Attributable

Public Functions

Module(Module const&) = delete
Module &operator=(Module const&) = delete
Module(Module&&) = default
Module &operator=(Module &&mE) = default
std::string const &get_name() const
std::string const &get_real_variant() const
Symbol *get_symbol(std::string_view symbol_name)
Symbol *emplace_symbol(std::string const &name, std::string const &type)
void add_variant(std::string const &name, std::variant<sha256_digest_t, std::shared_ptr<Expression>> const &variant_condition)
bool has_variant(std::string_view name) const
void dump(std::ostream &out) const
void dump_def(std::ostream &out) const
std::optional<expression_value_t> get_preferred_base_address() const
std::optional<expression_value_t> get_relocated_base_address() const
HMODULE get_hModule() const
void add_tag(std::string const &tag)
Context *get_context() const
bool concretize()
bool is_concrete() const

Private Functions

inline Module(std::string_view name, std::optional<std::string> lpModuleName, Context *context)

Private Members

Context *context
std::string name
std::optional<std::string> lpModuleName
std::optional<expression_value_t> preferred_base_address
std::optional<expression_value_t> relocated_base_address
std::vector<Symbol> symbols
std::vector<std::pair<std::string, std::variant<sha256_digest_t, std::shared_ptr<Expression>>>> variants
std::string real_variant
HMODULE hModule = 0
identifier_set_t tags

Friends

friend class Context
class ModuleExpression : private sinker::Expression

Public Functions

inline ModuleExpression(Module *module)
inline virtual std::optional<expression_value_t> calculate(Module *_module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

Module *module
template<typename T>
class Patch : public sinker::Installable, public sinker::Uninstallable

Public Types

using value_type = std::remove_extent_t<T>
using pointer_type = std::conditional_t<is_array, value_type*, T*>

Public Functions

inline Patch(pointer_type dst, pointer_type src)
inline virtual void install() override
inline virtual void uninstall() override

Public Static Attributes

static constexpr bool is_array = std::is_array_v<T>
static constexpr std::size_t value_count = is_array ? std::extent_v<T> : 1

Private Functions

inline bool make_patch_writable(SIZE_T patch_size, std::vector<ProtectionRegion> &regions) const
inline bool restore_patch_protection(std::vector<ProtectionRegion> const &regions) const

Private Members

pointer_type dst = {}
pointer_type src = {}
value_type backup[value_count] = {}

Private Static Functions

static inline DWORD patch_writable_protection(DWORD protection)
class PatternMatchExact : private sinker::PatternMatchFragment

Public Functions

inline PatternMatchExact(std::vector<std::uint8_t> const &value)
inline virtual void *search(void *begin, void *end) const override
inline virtual bool begins_with(void *begin, void *end) const override
inline virtual std::size_t size() const override
inline virtual PatternMatchType type() const override
inline virtual bool collision(void *address) const

Private Members

std::vector<std::uint8_t> value
class PatternMatchExpression : private sinker::Expression

Public Functions

inline PatternMatchExpression(std::vector<MaskedByte> const &needle, expression_value_t offset = 0, std::vector<PatternMatchFilter> const &filters = {})
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

std::vector<PatternMatchFilter> filters
std::vector<MaskedByte> needle
expression_value_t offset
class PatternMatchFilter

Public Functions

inline PatternMatchFilter(Module const *module = nullptr, std::optional<std::string> const &section_name = {})
inline Module const *get_module() const
inline std::optional<std::string> const &get_section_name() const

Private Members

Module const *module
std::optional<std::string> section_name
class PatternMatchFragment

Subclassed by sinker::PatternMatchExact, sinker::PatternMatchMask, sinker::PatternMatchWildcard

Public Functions

inline virtual ~PatternMatchFragment()
virtual void *search(void *begin, void *end) const = 0
virtual bool begins_with(void *begin, void *end) const = 0
virtual bool collision(void *address) const = 0
virtual std::size_t size() const = 0
virtual PatternMatchType type() const = 0
class PatternMatchMask : private sinker::PatternMatchFragment

Public Functions

inline PatternMatchMask(std::vector<MaskedByte> const &value)
inline virtual void *search(void *begin, void *end) const override
inline virtual bool begins_with(void *begin, void *end) const override
inline virtual std::size_t size() const override
inline virtual PatternMatchType type() const override
inline virtual bool collision(void *address) const

Private Members

std::vector<MaskedByte> value
class PatternMatchNeedle

Public Functions

inline PatternMatchNeedle(std::vector<MaskedByte> const &needle)
inline void *search(void *begin, void *end) const
inline virtual bool collision(void *address) const

Private Members

std::vector<std::unique_ptr<PatternMatchFragment>> fragments = {}
std::size_t size = 0
std::size_t offset = 0
std::size_t index = 0
class PatternMatchWildcard : private sinker::PatternMatchFragment

Public Functions

inline PatternMatchWildcard(std::size_t size)
inline virtual void *search(void *begin, void *end) const override
inline virtual bool begins_with(void *begin, void *end) const override
inline virtual std::size_t size() const override
inline virtual PatternMatchType type() const override
inline virtual bool collision(void *address) const

Private Members

std::size_t s
struct ProtectionRegion

Public Members

void *address
SIZE_T size
DWORD old_protect
template<std::size_t S = 32, std::uint8_t C = 0xEF, bool D = true>
class StackCheck

Public Functions

StackCheck()
bool good() const
~StackCheck()

Private Members

std::uint8_t buffer[S]
class Symbol : public sinker::Attributable

Public Functions

Symbol(Symbol const&) = delete
Symbol &operator=(Symbol const&) = delete
Symbol(Symbol&&) = default
Symbol &operator=(Symbol &&mE) = default
inline std::string const &get_name() const
template<typename T>
std::optional<T> calculate_address()
template<typename T>
std::optional<T> get_cached_calculated_address() const
Module *get_module() const
void add_address(identifier_set_t const &variant_set, std::shared_ptr<Expression> expression)
void dump(std::ostream &out) const
void dump_def(std::ostream &out) const
void add_tag(std::string const &tag)

Private Functions

inline Symbol(std::string const &name, std::string const &type, Module *module)

Private Members

std::optional<expression_value_t> cached_calculated_address
std::string name
std::string type
Module *module
std::vector<std::pair<identifier_set_t, std::shared_ptr<Expression>>> addresses
identifier_set_t tags

Friends

friend class Module
class SymbolExpression : private sinker::Expression

Public Functions

inline SymbolExpression(Symbol *symbol)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

Symbol *symbol
class Transaction

Public Functions

inline Transaction()
inline void add(Action *action)
inline long commit()

Private Members

std::vector<Action*> actions
class UnaryOperatorExpression : private sinker::Expression

Public Functions

inline UnaryOperatorExpression(std::shared_ptr<Expression> expression, UnaryOperator unary_operator, Type type)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Members

std::shared_ptr<Expression> expression
UnaryOperator unary_operator
Type type
class Uninstallable

Subclassed by sinker::Detour< T >, sinker::Patch< T >

Public Functions

virtual void uninstall() = 0
class UserOp

Public Functions

UserOp(UserOp const&) = default
UserOp &operator=(UserOp const&) = default
UserOp(UserOp&&) = default
UserOp &operator=(UserOp &&mE) = default
std::string const &get_name() const
expression_value_t (__cdecl *get_fn() const)(...)
std::size_t get_min_arity() const
std::optional<std::size_t> get_max_arity() const
bool accepts_arity(std::size_t arity) const

Private Functions

inline  UserOp (std::string_view name, expression_value_t(__cdecl *fn)(...), std::size_t min_arity, std::optional< std::size_t > max_arity)
expression_value_t (__cdecl *fn)(...)

Private Members

std::string name
std::size_t min_arity
std::optional<std::size_t> max_arity

Friends

friend class Context
class UserOpExpression : private sinker::Expression

Public Functions

inline UserOpExpression(UserOp *user_op, expression_list_t args)
inline virtual std::optional<expression_value_t> calculate(Module *module) const override
inline virtual void dump(std::ostream &out) const override

Private Functions

template<std::size_t... I>
inline std::optional<expression_value_t> invoke_with_indices(std::vector<expression_value_t> const &resolved_args, std::index_sequence<I...>) const
template<std::size_t N = 0>
inline std::optional<expression_value_t> invoke_with_runtime_arity(std::vector<expression_value_t> const &resolved_args) const

Private Members

UserOp *user_op
expression_list_t args

Private Static Attributes

static constexpr std::size_t MAX_ARITY = USER_OP_MAX_ARITY
namespace sinker

Typedefs

typedef unsigned long long expression_value_t
typedef std::variant<expression_value_t, bool, std::string> attribute_value_t
typedef std::set<std::string> identifier_set_t
typedef std::vector<std::shared_ptr<Expression>> expression_list_t

Enums

enum class Language

Values:

enumerator SINKER
enumerator SOURCE_CODE
enum class Type

Values:

enumerator None
enumerator U8
enumerator U16
enumerator U32
enumerator U64
enumerator I8
enumerator I16
enumerator I32
enumerator I64
enumerator PTR
enum class UnaryOperator

Values:

enumerator PARENTHESES
enumerator INDIRECTION
enumerator RELOCATION
enumerator BITWISE_NOT
enumerator SIZEOF
enum class BinaryOperator

Values:

enumerator ADDITION
enumerator SUBTRACTION
enumerator MULTIPLICATION
enumerator INTEGER_DIVISION
enumerator MODULO
enumerator BITWISE_AND
enumerator BITWISE_OR
enumerator BITWISE_XOR
enumerator BITWISE_SHIFT_LEFT
enumerator BITWISE_SHIFT_RIGHT
enumerator ARRAY_SUBSCRIPT
enumerator POINTER_PATH
enumerator SHORT_CIRCUIT_AND
enumerator SHORT_CIRCUIT_OR
enum class PatternMatchType

Values:

enumerator EXACT
enumerator MASK
enumerator WILDCARD
enumerator COUNT

Functions

std::ostream &operator<<(std::ostream &out, attribute_value_t const &attribute_value)
std::ostream &operator<<(std::ostream &os, Expression const &expression)
std::ostream &operator<<(std::ostream &os, Context const &context)
std::ostream &operator<<(std::ostream &os, Symbol const &symbol)
std::ostream &operator<<(std::ostream &os, Module const &module)
std::size_t SizeOfType(Type type)
char const *TypeToString(Type type)
std::optional<expression_value_t> CheckedDereference(expression_value_t value, Type type)

Variables

constexpr std::size_t USER_OP_MAX_ARITY = 64
file sinker.hpp
#include <Windows.h>
#include <cstdio>
#include <detours.h>
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
#include <optional>
#include <ostream>
#include <set>
#include <sha256.hpp>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <variant>
#include <vector>
#include “sinker.tpp”

Defines

SINKER_DEFINED_WIN32_LEAN_AND_MEAN
WIN32_LEAN_AND_MEAN
SINKER_DEFINED_NOMINMAX
NOMINMAX
PROPAGATE_UNRESOLVED(x)
dir /home/docs/checkouts/readthedocs.org/user_builds/sinker/checkouts/latest/sinker/include
dir /home/docs/checkouts/readthedocs.org/user_builds/sinker/checkouts/latest/sinker
dir /home/docs/checkouts/readthedocs.org/user_builds/sinker/checkouts/latest/sinker/include/sinker