Skip to content

Instantly share code, notes, and snippets.

@yazzn
Last active July 29, 2016 15:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yazzn/4e108ae6e7fb195aa01ed17385c3bcba to your computer and use it in GitHub Desktop.
Save yazzn/4e108ae6e7fb195aa01ed17385c3bcba to your computer and use it in GitHub Desktop.
#include <array>
#include <vector>
#include <functional>
#include <windows.h>
namespace memory
{
namespace detail
{
template <typename... Params>
struct parameter_size;
template <typename Ty, typename... Params>
struct parameter_size<Ty, Params...>
{
static std::ptrdiff_t count(std::size_t size, Ty param, Params... params)
{
return parameter_size<Params...>::count(size + sizeof(Ty), params...);
}
};
template <int N, typename... Params>
struct parameter_size<std::_Ph<N>, Params...>
{
static std::ptrdiff_t count(std::size_t size, std::_Ph<N> param, Params... params)
{
return parameter_size<Params...>::count(size + N, params...);
}
};
template <typename Ty, std::size_t N, typename... Params>
struct parameter_size<std::array<Ty, N>, Params...>
{
static std::ptrdiff_t count(std::size_t size, std::array<Ty, N> &param, Params... params)
{
return parameter_size<Params...>::count(size + N * sizeof(Ty), params...);
}
};
template <typename Ty, typename... Params>
struct parameter_size<std::vector<Ty>, Params...>
{
static std::ptrdiff_t count(std::size_t size, std::vector<Ty> &param, Params... params)
{
return parameter_size<Params...>::count(size + std::size(param) * sizeof(Ty), params...);
}
};
template <typename... Params>
struct parameter_size<const char *, Params...>
{
static std::ptrdiff_t count(std::size_t size, const char *param, Params... params)
{
return parameter_size<Params...>::count(size + std::strlen(param), params...);
}
};
template <typename... Params>
struct parameter_size<char *, Params...>
{
static std::ptrdiff_t count(std::size_t size, char *param, Params... params)
{
return parameter_size<Params...>::count(size + std::strlen(param), params...);
}
};
template <>
struct parameter_size<>
{
static std::ptrdiff_t count(std::size_t size)
{
return size;
}
};
template <typename... Pattern>
struct pattern_helper;
template <int N, typename... Pattern>
struct pattern_helper<std::_Ph<N>, Pattern...>
{
static bool match(std::uintptr_t pointer, std::_Ph<N> ph, Pattern... pattern)
{
return pattern_helper<Pattern...>::match(pointer + N, pattern...);
}
};
template <typename... Pattern>
struct pattern_helper<char *, Pattern...>
{
static bool match(std::uintptr_t pointer, char *value, Pattern... pattern)
{
std::size_t size = std::strlen(value);
return !memcmp(reinterpret_cast<char *>(pointer), value, size) &&
pattern_helper<Pattern...>::match(pointer + size, pattern...);
}
};
template <typename... Pattern>
struct pattern_helper<char const *, Pattern...>
{
static bool match(std::uintptr_t pointer, char const *value, Pattern... pattern)
{
std::size_t size = std::strlen(value);
return !memcmp(reinterpret_cast<char const *>(pointer), value, size) &&
pattern_helper<Pattern...>::match(pointer + size, pattern...);
}
};
template <typename Ty, typename... Pattern>
struct pattern_helper<Ty, Pattern...>
{
static bool match(std::uintptr_t pointer, Ty value, Pattern... pattern)
{
return !memcmp(reinterpret_cast<Ty *>(pointer), &value, sizeof(Ty)) &&
pattern_helper<Pattern...>::match(pointer + sizeof(Ty), pattern...);
}
};
template <typename Ty, std::size_t N, typename... Pattern>
struct pattern_helper<std::array<Ty, N>, Pattern...>
{
static bool match(std::uintptr_t pointer, std::array<Ty, N> &value, Pattern... pattern)
{
return !memcmp(reinterpret_cast<Ty *>(pointer), std::data(value), N * sizeof(Ty)) &&
pattern_helper<Pattern...>::match(pointer + N * sizeof(Ty), pattern...);
}
};
template <typename Ty, typename... Pattern>
struct pattern_helper<std::vector<Ty>, Pattern...>
{
static bool match(std::uintptr_t pointer, std::vector<Ty> &value, Pattern... pattern)
{
return !memcmp(reinterpret_cast<Ty *>(pointer), std::data(value), std::size(value) * sizeof(Ty)) &&
pattern_helper<Pattern...>::match(pointer + std::size(value) * sizeof(Ty), pattern...);
}
};
template <>
struct pattern_helper<>
{
static bool match(std::uintptr_t pointer)
{ return true; }
};
std::pair<std::uintptr_t, std::uintptr_t> module_base_info(const char *module)
{
PIMAGE_DOS_HEADER image_dos_header = reinterpret_cast<PIMAGE_DOS_HEADER>(GetModuleHandleA(module));
if (image_dos_header->e_magic == IMAGE_DOS_SIGNATURE)
{
PIMAGE_NT_HEADERS image_nt_header = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<std::uint8_t *>(image_dos_header) + image_dos_header->e_lfanew);
if (image_nt_header->Signature == IMAGE_NT_SIGNATURE)
{
return std::make_pair(image_nt_header->OptionalHeader.ImageBase, image_nt_header->OptionalHeader.SizeOfImage);
}
}
return std::make_pair(0, 0);
}
}
template <typename... Params>
std::ptrdiff_t count_parameter_size(Params... params)
{
return detail::parameter_size<Params...>::count(0, params...);
}
template <typename... Pattern>
bool matches_pattern(std::uintptr_t pointer, Pattern... pattern)
{
return detail::pattern_helper<Pattern...>::match(pointer, pattern...);
}
template <typename... Pattern>
std::uintptr_t find_pattern_range(std::uintptr_t first, std::ptrdiff_t length, Pattern... pattern)
{
for (std::uintptr_t pointer = first; pointer + count_parameter_size(pattern...) < (first + length); ++pointer)
{
if (matches_pattern(pointer, pattern...))
return pointer;
}
return 0;
}
template <typename... Pattern>
std::uintptr_t find_pattern(const char *module, Pattern... pattern)
{
auto base_info = detail::module_base_info(module);
return find_pattern_range(base_info.first, base_info.second, pattern...);
}
template <typename... Pattern>
std::vector<std::uintptr_t> find_pattern_all(std::uintptr_t first, std::ptrdiff_t length, Pattern... pattern)
{
std::vector<std::uintptr_t> results;
for (std::uintptr_t pointer = first; pointer + count_parameter_size(pattern...) < (first + length); ++pointer)
{
if (matches_pattern(pointer, pattern...))
results.push_back(pointer);
}
return results;
}
template <typename... Pattern>
std::vector<std::uintptr_t> find_pattern_all(const char *module, Pattern... pattern)
{
auto base_info = detail::module_base_info(module);
return find_pattern_all(base_info.first, base_info.second, pattern...);
}
template <std::size_t N>
using u8a = std::array<std::uint8_t, N>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment